diff --git a/.vscode/settings.json b/.vscode/settings.json index 9dfbaa3..2897ca2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,6 +20,7 @@ "Bandcamp", "dotenv", "encyclopaedia", + "ENDC", "levenshtein", "metallum", "musify", diff --git a/music_kraken/objects/parents.py b/music_kraken/objects/parents.py index fd2a80c..59a3d10 100644 --- a/music_kraken/objects/parents.py +++ b/music_kraken/objects/parents.py @@ -267,9 +267,9 @@ class OuterProxy: return r - def __repr__(self): - return f"{type(self).__name__}({', '.join(key + ': ' + str(val) for key, val in self.indexing_values)})" - @property def title_string(self) -> str: return str(self.__getattribute__(self.TITEL)) + + def __repr__(self): + return f"{type(self).__name__}({self.title_string})" diff --git a/music_kraken/objects/song.py b/music_kraken/objects/song.py index 2df348e..e9a38b6 100644 --- a/music_kraken/objects/song.py +++ b/music_kraken/objects/song.py @@ -27,14 +27,44 @@ from ..utils.string_processing import unify from .parents import OuterProxy as Base from ..utils.config import main_settings +from ..utils.enums.colors import BColors """ All Objects dependent """ CountryTyping = type(list(pycountry.countries)[0]) -OPTION_STRING_DELIMITER = " | " +OPTION_BACKGROUND = BColors.GREY +OPTION_FOREGROUND = BColors.OKBLUE + +def get_collection_string( + collection: Collection[Base], + template: str, + background: BColors = OPTION_BACKGROUND, + foreground: BColors = OPTION_FOREGROUND +) -> str: + if collection.empty: + return "" + + foreground = foreground.value + background = background.value + + r = background + + element: Base + for i, element in enumerate(collection): + delimiter = ", " + if i == len(collection) - 1: + delimiter = "" + elif i == len(collection) - 2: + delimiter = " and " + + r += foreground + element.title_string + BColors.ENDC.value + background + delimiter + BColors.ENDC.value + + r += BColors.ENDC.value + + return template.format(r) class Song(Base): title: str @@ -152,18 +182,12 @@ class Song(Base): return main_artists return f"{main_artists} feat. {feature_artists}" - def __repr__(self) -> str: - return f"Song(\"{self.title}\")" - @property def option_string(self) -> str: - r = f"{self.__repr__()}" - if not self.album_collection.empty: - r += f" from Album({OPTION_STRING_DELIMITER.join(album.title for album in self.album_collection)})" - if not self.main_artist_collection.empty: - r += f" by Artist({OPTION_STRING_DELIMITER.join(artist.name for artist in self.main_artist_collection)})" - if not self.feature_artist_collection.empty: - r += f" feat. Artist({OPTION_STRING_DELIMITER.join(artist.name for artist in self.feature_artist_collection)})" + r = OPTION_FOREGROUND.value + self.title + BColors.ENDC.value + OPTION_BACKGROUND.value + r += get_collection_string(self.album_collection, " from {}") + r += get_collection_string(self.main_artist_collection, " by {}") + r += get_collection_string(self.feature_artist_collection, " feat. {}") return r @property @@ -302,15 +326,16 @@ class Album(Base): id3Mapping.ALBUMSORTORDER: [str(self.albumsort)] if self.albumsort is not None else [] }) - def __repr__(self): - return f"Album(\"{self.title}\")" - @property def option_string(self) -> str: - return f"{self.__repr__()} " \ - f"by Artist({OPTION_STRING_DELIMITER.join([artist.name + str(artist.id) for artist in self.artist_collection])}) " \ - f"under Label({OPTION_STRING_DELIMITER.join([label.name for label in self.label_collection])})" + r = OPTION_FOREGROUND.value + self.title + BColors.ENDC.value + OPTION_BACKGROUND.value + r += get_collection_string(self.artist_collection, " by {}") + r += get_collection_string(self.label_collection, " under {}") + if len(self.song_collection) > 0: + r += f" with {len(self.song_collection)} songs" + return r + @property def options(self) -> List[P]: options = [*self.artist_collection, self, *self.song_collection] @@ -570,8 +595,18 @@ class Artist(Base): @property def option_string(self) -> str: - return f"{self.__repr__()} " \ - f"under Label({OPTION_STRING_DELIMITER.join([label.name for label in self.label_collection])})" + r = OPTION_FOREGROUND.value + self.name + BColors.ENDC.value + OPTION_BACKGROUND.value + r += get_collection_string(self.label_collection, " under {}") + + r += OPTION_BACKGROUND.value + if len(self.main_album_collection) > 0: + r += f" with {len(self.main_album_collection)} albums" + + if len(self.feature_song_collection) > 0: + r += f" featured in {len(self.feature_song_collection)} songs" + r += BColors.ENDC.value + + return r @property def options(self) -> List[P]: @@ -689,4 +724,4 @@ class Label(Base): @property def option_string(self): - return self.__repr__() + return OPTION_FOREGROUND.value + self.name + BColors.ENDC.value diff --git a/music_kraken/utils/string_processing.py b/music_kraken/utils/string_processing.py index 00b6024..efea651 100644 --- a/music_kraken/utils/string_processing.py +++ b/music_kraken/utils/string_processing.py @@ -176,4 +176,3 @@ def match_length(length_1: int | None, length_2: int | None) -> bool: if length_1 is None or length_2 is None: return True return abs(length_1 - length_2) <= ALLOWED_LENGTH_DISTANCE -