diff --git a/arts/_東方獣王園 ~ Unfinished Dream of All Living Ghost_.png b/arts/_東方獣王園 ~ Unfinished Dream of All Living Ghost_.png new file mode 100644 index 0000000..d1ed2e8 Binary files /dev/null and b/arts/_東方獣王園 ~ Unfinished Dream of All Living Ghost_.png differ diff --git a/mobject.py b/mobject.py index 85699de..733e514 100644 --- a/mobject.py +++ b/mobject.py @@ -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) diff --git a/musick.py b/musick.py index b607621..f6d950a 100644 --- a/musick.py +++ b/musick.py @@ -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: ") 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))