diff --git a/mp3tag.py b/mp3tag.py new file mode 100755 index 0000000..1881c1d --- /dev/null +++ b/mp3tag.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from fuzzywuzzy import fuzz, process +from mutagen.easyid3 import EasyID3 +from mutagen.id3 import ID3NoHeaderError +import os +from os.path import basename, normpath, splitext +import sys + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +def filename(f): + return splitext(normpath(basename(f)))[0] + + +dirs = [] +for d in sys.argv[1:]: + if not os.path.isdir(d): + eprint("Error: Cannot open {}: not a directory".format(d)) + sys.exit(1) + dirs += [d] + +for d in dirs: + # Get first level file list + (root, _, files) = next(os.walk(d)) + dir_artist = filename(d) + + for f in files: + f = os.path.join(root, f) + name = filename(f) + name_parts = name.split(" - ") + file_artist = name_parts[0] + fuzzy_artist = process.extractOne(dir_artist, name_parts, scorer=fuzz.token_sort_ratio) + + if len(name_parts) < 2: + eprint("Error: No title found for {}".format(f)) + continue + + file_title = name_parts[1] + + if dir_artist != file_artist: + eprint("""Error: Artist name mismatch between folder and file: {} + Fuzzy score = {:3d}, artist = {}""".format(f, fuzzy_artist[1], fuzzy_artist[0])) + # Test for common artist name patterns + if fuzzy_artist[1] < 90: + r = fuzz.ratio(dir_artist, "the " + fuzzy_artist[0]) + if True: # r >= 95: + eprint(" Fuzzy match r={} for: {}".format( + r, + "the " + fuzzy_artist[0])) + continue + + try: + id3 = EasyID3(f) + except ID3NoHeaderError: + id3 = EasyID3() + if id3 is None: + eprint("Error: cannot open {} for tagging".format(f)) + continue + + if "artist" not in id3.keys(): + id3["artist"] = file_artist + print("Artist set to {}".format(file_artist)) + if "title" not in id3.keys(): + id3["title"] = file_title + print("Title set to {}".format(file_title)) + # id3.save(f)