tagger.py: convert to python 3
authorColin P. McCabe <cmccabe@apache.org>
Fri, 3 Jun 2022 23:44:15 +0000 (16:44 -0700)
committerColin P. McCabe <cmccabe@apache.org>
Sat, 4 Jun 2022 00:26:52 +0000 (17:26 -0700)
tagger.py

index 59c280b..e67f275 100755 (executable)
--- a/tagger.py
+++ b/tagger.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python2
+#!/usr/bin/env python3
 
 #
 # Changes mp3 ID3 tags to match the file names.
@@ -59,11 +59,11 @@ def find_companion_script(target):
         statinfo = os.stat(mydir + "/" + target)
         mode = statinfo[0]
         if not (mode & stat.S_IEXEC):
-            print "ERROR: " + target + " is not executable"
+            print("ERROR: " + target + " is not executable")
             sys.exit(1)
         return target_path 
-    except Exception, e:
-        print "ERROR: can't find id3v2_wrapper.sh: " + str(e)
+    except Exception as e:
+        print("ERROR: can't find id3v2_wrapper.sh: " + str(e))
         sys.exit(1)
 
 # Verifies that a given program is installed.
@@ -72,8 +72,8 @@ def verify_program_installed(prog):
         proc = subprocess.Popen(prog, stdout=subprocess.PIPE)
         line = proc.stdout.readline()
         return True
-    except Exception, e:
-        print "failed to execute " + str(prog)
+    except Exception as e:
+        print("failed to execute " + str(prog))
         return False
 
 # Regular expressions for parsing file names--
@@ -99,20 +99,20 @@ dir_name_re = re.compile("(.*/)?" +
 def self_test_music_file(m, artist, album_name, \
                         conductor, track_number, title):
     if (m.album.artist != artist):
-        print "FAILED: artist: \"" + m.album.artist + "\""
-        print "\tshould be: \"" + artist + "\""
+        print("FAILED: artist: \"" + m.album.artist + "\"")
+        print("\tshould be: \"" + artist + "\"")
     if (m.album.name != album_name):
-        print "FAILED: album_name: \"" + m.album.name + "\""
-        print "\tshould be: \"" + album_name + "\""
+        print("FAILED: album_name: \"" + m.album.name + "\"")
+        print("\tshould be: \"" + album_name + "\"")
     if (m.album.conductor != conductor):
-        print "FAILED: conductor: \"" + m.album.conductor + "\""
-        print "\tshould be: \"" + conductor + "\""
+        print("FAILED: conductor: \"" + m.album.conductor + "\"")
+        print("\tshould be: \"" + conductor + "\"")
     if (m.track_number != track_number):
-        print "FAILED: track_number: \"" + int(m.track_number) + "\""
-        print "\tshould be: \"" + str(track_number) + "\""
+        print("FAILED: track_number: \"" + int(m.track_number) + "\"")
+        print("\tshould be: \"" + str(track_number) + "\"")
     if (m.title != title):
-        print "FAILED: title: \"" + m.title + "\""
-        print "\tshould be: \"" + title + "\""
+        print("FAILED: title: \"" + m.title + "\"")
+        print("\tshould be: \"" + title + "\"")
 
 def run_self_test():
     m = MusicFile.from_filename("./Mozart - " +
@@ -153,29 +153,24 @@ def run_self_test():
 # i.e. if H[k] = v, H'[v] = k
 def reverse_hash(h):
     ret = dict()
-    i = h.iteritems()
-    while 1:
-        try:
-            k,v = i.next()
-            ret[v] = k
-        except StopIteration:
-            break
+    for k, v in h.items():
+        ret[v] = k
     return ret
 
 def my_system(ignore_ret, *cmd):
     if (verbose == True):
-        print cmd
+        print(cmd)
     if (dry_run == False):
         try:
             my_env = {"MALLOC_CHECK_" : "0", "PATH" : os.environ.get("PATH")}
             retcode = subprocess.call(cmd, env=my_env, shell=False)
             if (retcode < 0):
-                print "ERROR: Child was terminated by signal", -retcode
+                print("ERROR: Child was terminated by signal", -retcode)
             else:
                 if ((not ignore_ret) and (retcode != 0)):
-                    print "ERROR: Child returned", retcode
-        except OSError, e:
-            print "ERROR: Execution failed:", e
+                    print("ERROR: Child returned", retcode)
+        except OSError as e:
+            print("ERROR: Execution failed:", e)
 
 # CLASSES
 class FileType(object):
@@ -188,14 +183,14 @@ class Album(object):
             raise MusicFileErr("can't have Album.artist = None")
         if (name == None):
             raise MusicFileErr("can't have Album.name = None")
-        self.artist = string.rstrip(artist)
-        self.name = string.rstrip(name)
+        self.artist = artist.rstrip()
+        self.name = name.rstrip()
         if (conductor):
             i = conductor.find(' = ')
             self.conductor = conductor[i+len(' = '):]
         else:
             self.conductor = ""
-        self.encoding = string.rstrip(encoding) if encoding else ""
+        self.encoding = encoding.rstrip() if encoding else ""
 
     def from_dirname(dirname):
         match = dir_name_re.match(dirname)
@@ -263,18 +258,14 @@ class MusicFile(object):
         my_system(False, "id3v2", attribute, expr, self.filename)
 
     def set_tags(self):
-        i = self.id3v2_to_attrib.iteritems()
-        while 1:
-            try:
-                att,expr = i.next()
-                self.add_tag(att, eval(expr))
-            except StopIteration:
-                break
+        for att, expr in self.id3v2_to_attrib.items():
+            self.add_tag(att, eval(expr))
+
 # CODE
 
 ## Make sure that id3v2 is installed
 if not verify_program_installed(["id3v2", "--version"]):
-    print "You must install the id3v2 program to run this script."
+    print("You must install the id3v2 program to run this script.")
     sys.exit(1)
 
 ## Find id3v2_wrapper.sh
@@ -282,16 +273,16 @@ id3v2_wrapper = find_companion_script('id3v2_wrapper.sh')
 
 ## Parse options
 def Usage():
-    print os.path.basename(sys.argv[0]) + ": the mp3 tagging program"
-    print
-    print "Usage: " + os.path.basename(sys.argv[0]) + \
-            " [-h][-d][-s] [dirs]"
-    print "-h: this help message"
-    print "-d: dry-run mode"
-    print "-s: self-test"
-    print "-A: audiobook mode"
-    print "dirs: directories to search for albums."
-    print "This program skips dirs with \"[LL]\" in the name."
+    print(os.path.basename(sys.argv[0]) + ": the mp3 tagging program")
+    print()
+    print("Usage: " + os.path.basename(sys.argv[0]) + \
+            " [-h][-d][-s] [dirs]")
+    print("-h: this help message")
+    print("-d: dry-run mode")
+    print("-s: self-test")
+    print("-A: audiobook mode")
+    print("dirs: directories to search for albums.")
+    print("This program skips dirs with \"[LL]\" in the name.")
     sys.exit(1)
 
 try:
@@ -317,7 +308,7 @@ if (self_test):
 
 for dir in dirs:
     if (re.search("\[LL\]", dir)):
-        print "skipping \"" + dir + "\"..."
+        print("skipping \"" + dir + "\"...")
         continue
     # Assume that paths without a directory prefix are local
     if ((dir[0] != "/") and (dir.find("./") != 0)):
@@ -329,31 +320,31 @@ for dir in dirs:
     try:
         entries = os.listdir(dir)
     except:
-        print "ERROR: cannot stat entries of \"" + dir + "\""
+        print("ERROR: cannot stat entries of \"" + dir + "\"")
         continue
 
     # Process all files in the directory
     if (verbose):
-        print "******** find -L " + dir + " -noleaf"
+        print("******** find -L " + dir + " -noleaf")
     proc = subprocess.Popen(['find', '-L', dir, '-noleaf'],\
             stdout=subprocess.PIPE)
     line = proc.stdout.readline()
-    while line != '':
-        file_name = line.strip()
+    while line:
+        file_name = line.decode("utf-8").strip()
         if (music_file_re.match(file_name)):
             try:
                 m = MusicFile.from_filename(file_name)
                 m.clear_tags()
                 m.set_tags()
                 if (verbose):
-                    print "SUCCESS: " + file_name
+                    print("SUCCESS: " + file_name)
                 total_albums = total_albums + 1
-            except MusicFileErr, e:
-                print "ERROR: " + str(e)
+            except MusicFileErr as e:
+                print("ERROR: " + str(e))
         line = proc.stdout.readline()
     if (verbose):
-        print "********"
+        print("********")
 
 if (dry_run):
-    print "(dry run)",
-print "Successfully processed " + str(total_albums) + " total mp3s"
+    print("(dry run)", end='')
+print("Successfully processed " + str(total_albums) + " total mp3s")