multi value tag support

This commit is contained in:
quackerd 2023-06-06 18:26:52 -04:00
parent 0b8827c1b8
commit c2fdf3a779
3 changed files with 59 additions and 47 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB

View File

@ -15,27 +15,27 @@ class MObject:
def get_bytes(self) -> bytes:
return self._file_io.getbuffer()
def get_title(self) -> str:
def get_title(self) -> list[str]:
raise Exception("unimplemented")
def get_album(self) -> str:
def get_album(self) -> list[str]:
raise Exception("unimplemented")
def get_artist(self) -> str:
def get_artist(self) -> list[str]:
raise Exception("unimplemented")
def get_cover(self) -> bytes:
raise Exception("unimplemented")
def set_artist(self, val : str) -> None:
def set_artist(self, val : list[str]) -> None:
raise Exception("unimplemented")
def set_album(self, val : str) -> None:
def set_album(self, val : list[str]) -> None:
raise Exception("unimplemented")
def set_title(self, val : str) -> None:
def set_title(self, val : list[str]) -> None:
raise Exception("unimplemented")
def set_cover(self, val : bytes, png : bool = False) -> None:
raise Exception("unimplemented")
@ -48,30 +48,30 @@ class MMP3Object(MObject):
self._id3.load(self._file_io, translate = True)
return
def get_title(self) -> str:
return self._id3.get("TIT2", default = TIT2(text = ""))
def get_title(self) -> list[str]:
return self._id3.get("TIT2")
def set_title(self, val : str) -> None:
def set_title(self, val : list[str]) -> None:
self._id3.delall("TIT2")
self._id3.add(TIT2(text = val))
self._file_io.seek(0)
self._id3.save(self._file_io)
def get_album(self) -> str:
return self._id3.get("TALB", default = TALB(text = ""))
def get_album(self) -> list[str]:
return self._id3.get("TALB")
def set_album(self, val : str) -> None:
def set_album(self, val : list[str]) -> None:
self._id3.delall("TALB")
self._id3.add(TALB(text = val))
self._file_io.seek(0)
self._id3.save(self._file_io)
def get_artist(self) -> str:
return self._id3.get("TPE1", default = TPE1(text = ""))
def get_artist(self) -> list[str]:
return self._id3.get("TPE1")
def set_artist(self, val : str):
def set_artist(self, val : list[str]):
self._id3.delall("TPE1")
self._id3.add(TPE1(text = val))
@ -100,28 +100,28 @@ class MFLACObject(MObject):
self._flac = FLAC(self._file_io)
return
def get_title(self) -> str:
return self._flac.get("TITLE", default = None)
def get_title(self) -> list[str]:
return self._flac.get("TITLE")
def set_title(self, val : str) -> None:
self._flac["TITLE"] = val
def set_title(self, val : list[str]) -> None:
self._flac["TITLE"] = val[0]
self._file_io.seek(0)
self._flac.save(self._file_io)
def get_album(self) -> str:
return self._flac.get("ALBUM", default = None)
def get_album(self) -> list[str]:
return self._flac.get("ALBUM")
def set_album(self, val : str) -> None:
self._flac["ALBUM"] = val
def set_album(self, val : list[str]) -> None:
self._flac["ALBUM"] = val[0]
self._file_io.seek(0)
self._flac.save(self._file_io)
def get_artist(self) -> str:
return self._flac.get("ARTIST", default = None)
def get_artist(self) -> list[str]:
return self._flac.get("ARTIST")
def set_artist(self, val : str):
def set_artist(self, val : list[str]):
self._flac["ARTIST"] = val
self._file_io.seek(0)

View File

@ -1,7 +1,7 @@
import os
import getopt
import sys
import shutil
import pathlib
import mobject
@ -28,12 +28,12 @@ ALBUM_MATCH_SCORE = 100
TITLE_MATCH_SCORE = 1000
# to get a > 0 score, each field either must match or the cover tuple is wildcare (None)
def calc_cover_score(artist: str, album: str, title: str, tup : tuple):
def calc_cover_score(artist: list[str], album: list[str], title: list[str], tup : tuple) -> int:
score = 0
if (tup[0] == artist):
score += ARTIST_MATCH_SCORE
elif (tup[0] == ""):
elif (tup[0] == [""]):
score += WILDCARD_MATCH_SCORE
else:
# mismatched artist, discard
@ -41,7 +41,7 @@ def calc_cover_score(artist: str, album: str, title: str, tup : tuple):
if (tup[1] == album):
score += ALBUM_MATCH_SCORE
elif (tup[1] == ""):
elif (tup[1] == [""]):
score += WILDCARD_MATCH_SCORE
else:
# mismatched album, discard
@ -49,7 +49,7 @@ def calc_cover_score(artist: str, album: str, title: str, tup : tuple):
if (tup[2] == title):
score += TITLE_MATCH_SCORE
elif (tup[2] == ""):
elif (tup[2] == [""]):
score += WILDCARD_MATCH_SCORE
else:
# mismatched title, discard
@ -59,7 +59,7 @@ def calc_cover_score(artist: str, album: str, title: str, tup : tuple):
# returns the idx into cover_arts array.
# < 0 means no match
def find_best_cover(artist: str, album: str, title: str):
def find_best_cover(artist: list[str], album: list[str], title: list[str]) -> int:
best_idx = -1
best_score = 0
for i in range(0, len(cover_arts)):
@ -70,17 +70,24 @@ def find_best_cover(artist: str, album: str, title: str):
return best_idx
def plus_str_to_list(s : str) -> list[str]:
ss : list[str] = s.split("+")
ret = []
for sss in ss:
ret.append(sss)
return ret
def parse_triple(f: str):
def parse_triple(f: str) -> tuple[list[str], list[str], list[str]]:
triple = os.path.splitext(os.path.basename(f))[0].split("_")
album = ""
title = ""
artist = triple[0]
artist = plus_str_to_list(triple[0])
if len(triple) >= 2:
album = triple[1]
album = plus_str_to_list(triple[1])
if len(triple) >= 3:
title = triple[2]
return artist, album, title
title = plus_str_to_list(triple[2])
return (artist, album, title)
def load_cover_arts():
global cover_arts
@ -95,9 +102,14 @@ def load_cover_arts():
artist, album, title = parse_triple(f)
f = os.path.join(cover_dir, f)
print("Processing cover art - " + f)
fp = pathlib.Path(f)
if (fp.suffix.lower() == ".png"):
type = "PNG"
else:
type = "JPEG"
with open(f,'rb') as img:
cover_arts.append((artist, album, title, img.read(), os.path.basename(f), f))
print(" Loading cover art - " + f + " Artist: " + artist + " Album: " + album + " Title: " + title)
cover_arts.append((artist, album, title, img.read(), type, f))
print(" Loading cover art - " + f + " Artist: " + str(artist) + " Album: " + str(album) + " Title: " + str(title) + " Type: " + type)
except Exception as e:
print(" Skipping due to Exception - " + str(e))
print("")
@ -122,11 +134,11 @@ def process_file(f: str, odir: str):
total_proc += 1
artist, album, title = parse_triple(f)
if album == "":
album = UNKNOWN_ALBUM_NAME
if artist == "":
artist = UNKNOWN_ARTIST_NAME
if title == "":
if len(album) == 0:
album = [UNKNOWN_ALBUM_NAME]
if len(artist) == 0:
artist = [UNKNOWN_ARTIST_NAME]
if len(title) == 0:
raise Exception("No title")
mobj = mobject.create_mobject(f)
@ -142,7 +154,7 @@ def process_file(f: str, odir: str):
if (mobj.get_cover() == None or overwrite_cover):
cover_idx = find_best_cover(artist, album, title)
if (cover_idx >= 0):
mobj.set_cover(cover_arts[cover_idx][3])
mobj.set_cover(cover_arts[cover_idx][3], cover_arts[cover_idx][4] == "PNG")
print(f" Cover: <{'None' if mobj.get_cover() == None else 'Exists'}> -> \"{cover_arts[cover_idx][5]}\"")
total_cover_written += 1
else:
@ -152,7 +164,7 @@ def process_file(f: str, odir: str):
print(" Cover: <Exists>")
total_cover_exists += 1
target_dir = os.path.join(odir, artist, album)
target_dir = os.path.join(odir, "+".join(artist), "+".join(album))
os.makedirs(target_dir, exist_ok = True)
target_f = os.path.join(target_dir, os.path.basename(f))