diff --git a/src/metal_archives.py b/src/metal_archives.py index 2a8188f..7a92b97 100644 --- a/src/metal_archives.py +++ b/src/metal_archives.py @@ -63,6 +63,7 @@ artist = song.main_artist_list[0] # artist = EncyclopaediaMetallum.fetch_artist_details(artist, flat=False) album = EncyclopaediaMetallum.fetch_album_details(song.album, flat=False) +print(album.tracklist) # print_artist(artist) diff --git a/src/music_kraken/database/objects/collection.py b/src/music_kraken/database/objects/collection.py index 215c783..dd98e08 100644 --- a/src/music_kraken/database/objects/collection.py +++ b/src/music_kraken/database/objects/collection.py @@ -14,7 +14,7 @@ class Collection: _by_attribute: dict - def __init__(self, data: list = None, map_attributes: list = None) -> None: + def __init__(self, data: list = None, map_attributes: list = None, element_type=None) -> None: """ Attribute needs to point to """ @@ -22,6 +22,7 @@ class Collection: self.map_attributes = map_attributes or [] + self.element_type = element_type self._by_attribute = {attr: dict() for attr in map_attributes} self._data = data or [] @@ -30,7 +31,9 @@ class Collection: self.map_element(element=element) def map_element(self, element: SourceAttribute): - self._by_url.update(element.source_url_map) + for source_url in element.source_url_map: + self._by_url[source_url] = element + for attr in self.map_attributes: value = element.__getattribute__(attr) if type(value) != str: @@ -53,9 +56,20 @@ class Collection: raise ValueError(f"didn't map the attribute {name}") unified = string_processing.unify(value) - if unified in self._by_attribute[name][unified]: + if unified in self._by_attribute[name]: return self._by_attribute[name][unified] def append(self, element: SourceAttribute): + if type(element) is not self.element_type and self.element_type is not None: + + raise TypeError(f"{type(element)} is not the set type {self.element_type}") + self._data.append(element) self.map_element(element) + + def __iter__(self): + for element in self._data: + yield element + + def __str__(self) -> str: + return "\n".join([f"{str(j).zfill(2)}: {i}" for j, i in enumerate(self._data)]) diff --git a/src/music_kraken/database/objects/song.py b/src/music_kraken/database/objects/song.py index 574cb45..948818f 100644 --- a/src/music_kraken/database/objects/song.py +++ b/src/music_kraken/database/objects/song.py @@ -24,6 +24,7 @@ from .source import ( SourceAttribute ) from .formatted_text import FormattedText +from .collection import Collection """ All Objects dependent @@ -262,7 +263,8 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute): albumsort: int = None, dynamic: bool = False, source_list: List[Source] = None, - artists: list = None + artists: list = None, + tracklist: List[Song] = None ) -> None: DatabaseObject.__init__(self, id_=id_, dynamic=dynamic) self.title: str = title @@ -282,14 +284,15 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute): self.is_split: bool = is_split self.albumsort: int | None = albumsort - self._tracklist: List[Song] = list() - if source_list is not None: - self.source_list = source_list + self._tracklist = Collection( + data=tracklist or [], + map_attributes=["title"], + element_type=Song + ) + self.source_list = source_list or [] + self.artists = artists or [] - self.artists = [] - if artists is not None: - self.artists = artists def __str__(self) -> str: return f"Album: \"{self.title}\"" @@ -300,11 +303,19 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute): def __len__(self) -> int: return len(self.tracklist) - def set_tracklist(self, tracklist: List[Song]): - self._tracklist = tracklist + def set_tracklist(self, tracklist): + tracklist_list = [] + if type(tracklist) == Collection: + tracklist_list = tracklist_list + elif type(tracklist) == list: + tracklist_list = tracklist - for i, track in enumerate(self._tracklist): - track.tracksort = i + 1 + self._tracklist = Collection( + data=tracklist_list, + map_attributes=["title"], + element_type=Song + ) + def add_song(self, song: Song): for existing_song in self._tracklist: @@ -337,9 +348,10 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute): return self.language.alpha_3 + copyright = property(fget=get_copyright) iso_639_2_language = property(fget=get_iso_639_2_lang) - tracklist = property(fget=lambda self: self._tracklist, fset=set_tracklist) + tracklist: Collection = property(fget=lambda self: self._tracklist, fset=set_tracklist) """ diff --git a/src/music_kraken/pages/encyclopaedia_metallum.py b/src/music_kraken/pages/encyclopaedia_metallum.py index c4d44e3..9f23f11 100644 --- a/src/music_kraken/pages/encyclopaedia_metallum.py +++ b/src/music_kraken/pages/encyclopaedia_metallum.py @@ -446,19 +446,6 @@ class EncyclopaediaMetallum(Page): LOGGER.warning(f"code {r.status_code} at {source.url}") return album - # prepare tracklist - track_by_url = dict() - track_by_name = dict() - for track in album._tracklist: - track_by_name[string_processing.unify(track.title)] = track - for source in track.get_sources_from_page(cls.SOURCE_TYPE): - track_by_url[source.url] = album - old_tracklist = album._tracklist.copy() - # save the ids of the albums, that are added to this set, so I can - # efficiently add all leftover albums from the discography to the new one - used_ids = set() - new_tracklist = [] - soup = BeautifulSoup(r.text, 'html.parser') tracklist_soup = soup.find("table", {"class": "table_lyrics"}).find("tbody") @@ -488,34 +475,26 @@ class EncyclopaediaMetallum(Page): minutes, seconds = duration_stamp.split(":") length = (int(minutes) * 60 + int(seconds))*1000 # in milliseconds - track: Song - if track_id in track_by_url: - track = track_by_url[track_id] - used_ids.add(track.id) - elif title in track_by_name: - track = track_by_name[title] - used_ids.add(track.id) - else: - track = Song( - id_=track_id, - title=title, - length=length, - tracksort=track_sort - ) - track.add_source(Source(cls.SOURCE_TYPE, track_id)) - - new_tracklist.append(track) + track: Song = album.tracklist.get_object_with_source(track_id) or album.tracklist.get_object_with_attribute("title", title) - print(track) - print("-"*20) - # print(row) - - for old_track in old_tracklist: - if old_track.dynamic: + if track is not None: + track.add_source(Source(cls.SOURCE_TYPE, track_id)) + track.length = length + track.tracksort = track_sort continue - if old_track.id not in used_ids: - new_tracklist.append(old_track) - album.tracklist = new_tracklist + + + track = Song( + id_=track_id, + title=title, + length=length, + tracksort=track_sort, + source_list=[ + Source(cls.SOURCE_TYPE, track_id) + ] + ) + + album.tracklist.append(track) return album