From: Colin P. McCabe Date: Fri, 3 Jun 2022 23:44:15 +0000 (-0700) Subject: tagger.py: convert to python 3 X-Git-Url: http://www.club.cc.cmu.edu/~cmccabe/cgi-bin/gitweb.cgi?p=cmccabe-bin;a=commitdiff_plain;h=216993683b06009481be24fedcff59a9bd6fea72 tagger.py: convert to python 3 --- diff --git a/tagger.py b/tagger.py index 59c280b..e67f275 100755 --- 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")