started fixing importand design flaw
This commit is contained in:
parent
d685827fb5
commit
5387301ed2
@ -62,7 +62,7 @@ class Collection:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def append(self, element: DatabaseObject, merge_on_conflict: bool = True, merge_into_existing: bool = True) -> bool:
|
def append(self, element: DatabaseObject, merge_on_conflict: bool = True, merge_into_existing: bool = True) -> DatabaseObject:
|
||||||
"""
|
"""
|
||||||
:param element:
|
:param element:
|
||||||
:param merge_on_conflict:
|
:param merge_on_conflict:
|
||||||
@ -78,14 +78,17 @@ class Collection:
|
|||||||
if value in self._attribute_to_object_map[name]:
|
if value in self._attribute_to_object_map[name]:
|
||||||
existing_object = self._attribute_to_object_map[name][value]
|
existing_object = self._attribute_to_object_map[name][value]
|
||||||
|
|
||||||
if merge_on_conflict:
|
if not merge_on_conflict:
|
||||||
|
return existing_object
|
||||||
|
|
||||||
# if the object does already exist
|
# if the object does already exist
|
||||||
# thus merging and don't add it afterwards
|
# thus merging and don't add it afterwards
|
||||||
if merge_into_existing:
|
if merge_into_existing:
|
||||||
existing_object.merge(element)
|
existing_object.merge(element)
|
||||||
# in case any relevant data has been added (e.g. it remaps the old object)
|
# in case any relevant data has been added (e.g. it remaps the old object)
|
||||||
self.map_element(existing_object)
|
self.map_element(existing_object)
|
||||||
else:
|
return existing_object
|
||||||
|
|
||||||
element.merge(existing_object)
|
element.merge(existing_object)
|
||||||
|
|
||||||
exists_at = self._data.index(existing_object)
|
exists_at = self._data.index(existing_object)
|
||||||
@ -93,13 +96,15 @@ class Collection:
|
|||||||
|
|
||||||
self.unmap_element(existing_object)
|
self.unmap_element(existing_object)
|
||||||
self.map_element(element)
|
self.map_element(element)
|
||||||
|
return element
|
||||||
return False
|
|
||||||
|
|
||||||
self._data.append(element)
|
self._data.append(element)
|
||||||
self.map_element(element)
|
self.map_element(element)
|
||||||
|
|
||||||
return True
|
return element
|
||||||
|
|
||||||
|
def append_is_already_in_collection(self, element: DatabaseObject, merge_on_conflict: bool = True, merge_into_existing: bool = True) -> bool:
|
||||||
|
object_representing_the_data = self.append(element, merge_on_conflict=merge_on_conflict, merge_into_existing=merge_into_existing)
|
||||||
|
|
||||||
def extend(self, element_list: Iterable[DatabaseObject], merge_on_conflict: bool = True):
|
def extend(self, element_list: Iterable[DatabaseObject], merge_on_conflict: bool = True):
|
||||||
for element in element_list:
|
for element in element_list:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import Optional
|
from typing import Optional, Union, Type
|
||||||
import requests
|
import requests
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -16,7 +16,8 @@ from ..objects import (
|
|||||||
MusicObject,
|
MusicObject,
|
||||||
Options,
|
Options,
|
||||||
SourcePages,
|
SourcePages,
|
||||||
Collection
|
Collection,
|
||||||
|
Label
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -138,114 +139,62 @@ class Page:
|
|||||||
return Options()
|
return Options()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fetch_details(cls, music_object: MusicObject, flat: bool = False) -> MusicObject:
|
def fetch_details(cls, music_object: Union[Song, Album, Artist, Label], stop_at_level: int = 1) -> MusicObject:
|
||||||
"""
|
"""
|
||||||
when a music object with laccing data is passed in, it returns
|
when a music object with laccing data is passed in, it returns
|
||||||
the SAME object **(no copy)** with more detailed data.
|
the SAME object **(no copy)** with more detailed data.
|
||||||
If you for example put in an album, it fetches the tracklist
|
If you for example put in an album, it fetches the tracklist
|
||||||
|
|
||||||
:param music_object:
|
:param music_object:
|
||||||
:param flat:
|
:param stop_at_level:
|
||||||
if it is true it fetches only the most important information (only one level)
|
This says the depth of the level the scraper will recurse to.
|
||||||
if an Artist is passed in, it fetches only the discography of the artist, and not the
|
If this is for example set to 2, then the levels could be:
|
||||||
tracklist of every album of the artist.
|
1. Level: the album
|
||||||
|
2. Level: every song of the album + every artist of the album
|
||||||
|
If no additional requests are needed to get the data one level below the supposed stop level
|
||||||
|
this gets ignored
|
||||||
:return detailed_music_object: IT MODIFIES THE INPUT OBJ
|
:return detailed_music_object: IT MODIFIES THE INPUT OBJ
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if type(music_object) == Song:
|
new_music_object: MusicObject = type(music_object).__init__()
|
||||||
song = cls.fetch_song_details(music_object, flat=flat)
|
|
||||||
song.compile()
|
|
||||||
return song
|
|
||||||
|
|
||||||
if type(music_object) == Album:
|
source: Source
|
||||||
album = cls.fetch_album_details(music_object, flat=flat)
|
for source in music_object.source_collection:
|
||||||
album.compile()
|
new_music_object.merge(cls.fetch_object_from_source(source=source, obj_type=type(music_object), stop_at_level=stop_at_level))
|
||||||
return album
|
|
||||||
|
|
||||||
if type(music_object) == Artist:
|
|
||||||
artist = cls.fetch_artist_details(music_object, flat=flat)
|
|
||||||
artist.compile()
|
|
||||||
return artist
|
|
||||||
|
|
||||||
raise NotImplementedError(f"MusicObject {type(music_object)} has not been implemented yet")
|
|
||||||
|
music_object.merge(new_music_object)
|
||||||
|
music_object.compile()
|
||||||
|
|
||||||
|
return music_object
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fetch_song_from_source(cls, source: Source, flat: bool = False) -> Song:
|
def fetch_object_from_source(cls, source: Source, obj_type: Union[Type[Song], Type[Album], Type[Artist], Type[Label]], stop_at_level: int = 1):
|
||||||
|
if obj_type == Artist:
|
||||||
|
return cls.fetch_artist_from_source(source=source, stop_at_level=stop_at_level)
|
||||||
|
|
||||||
|
if obj_type == Song:
|
||||||
|
return cls.fetch_song_from_source(source=source, stop_at_level=stop_at_level)
|
||||||
|
|
||||||
|
if obj_type == Album:
|
||||||
|
return cls.fetch_album_from_source(source=source, stop_at_level=stop_at_level)
|
||||||
|
|
||||||
|
if obj_type == Label:
|
||||||
|
return cls.fetch_label_from_source(source=source, stop_at_level=stop_at_level)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fetch_song_from_source(cls, source: Source, stop_at_level: int = 1) -> Song:
|
||||||
return Song()
|
return Song()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fetch_song_details(cls, song: Song, flat: bool = False) -> Song:
|
def fetch_album_from_source(cls, source: Source, stop_at_level: int = 1) -> Album:
|
||||||
"""
|
|
||||||
for a general description check cls.fetch_details
|
|
||||||
|
|
||||||
:param song: song without much data
|
|
||||||
:param flat:
|
|
||||||
when True it only fetches the artist and the album, and the attributes of those,
|
|
||||||
who can be gotten with one api request
|
|
||||||
when False it fetches everything including, but not limited to:
|
|
||||||
- Lyrics
|
|
||||||
- Album + Tracklist (for tracksort)
|
|
||||||
|
|
||||||
:return detailed_song: it modifies the input song
|
|
||||||
"""
|
|
||||||
|
|
||||||
source: Source
|
|
||||||
for source in song.source_collection.get_sources_from_page(cls.SOURCE_TYPE):
|
|
||||||
new_song = cls.fetch_song_from_source(source, flat)
|
|
||||||
song.merge(new_song)
|
|
||||||
|
|
||||||
return song
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_album_from_source(cls, source: Source, flat: bool = False) -> Album:
|
|
||||||
return Album()
|
return Album()
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_album_details(cls, album: Album, flat: bool = False) -> Album:
|
|
||||||
"""
|
|
||||||
for a general description check cls.fetch_details
|
|
||||||
|
|
||||||
:param album: album without much data
|
|
||||||
:param flat:
|
|
||||||
when True it only fetches the artist and the tracklist, and the attributes of those,
|
|
||||||
which can be gotten with one api request
|
|
||||||
when False it fetches everything including, but not limited to:
|
|
||||||
- Lyrics of every song
|
|
||||||
- Artist, Album, Tracklist
|
|
||||||
- every attribute of those
|
|
||||||
|
|
||||||
:return detailed_artist: it modifies the input artist
|
|
||||||
"""
|
|
||||||
|
|
||||||
source: Source
|
|
||||||
for source in album.source_collection.get_sources_from_page(cls.SOURCE_TYPE):
|
|
||||||
new_album: Album = cls.fetch_album_from_source(source, flat)
|
|
||||||
album.merge(new_album)
|
|
||||||
|
|
||||||
return album
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fetch_artist_from_source(cls, source: Source, flat: bool = False) -> Artist:
|
def fetch_artist_from_source(cls, source: Source, stop_at_level: int = 1) -> Artist:
|
||||||
return Artist()
|
return Artist()
|
||||||
|
|
||||||
@classmethod
|
def fetch_label_from_source(source: Source, stop_at_level: int = 1) -> Label:
|
||||||
def fetch_artist_details(cls, artist: Artist, flat: bool = False) -> Artist:
|
return Label()
|
||||||
"""
|
|
||||||
for a general description check cls.fetch_details
|
|
||||||
|
|
||||||
:param artist: artist without much data
|
|
||||||
:param flat:
|
|
||||||
when True it only fetches the discographie, meaning every album, but not every tracklist
|
|
||||||
when False it fetches everything including, but not limited to:
|
|
||||||
- the whole discography
|
|
||||||
- the tracklist of every album in the discography
|
|
||||||
|
|
||||||
:return detailed_artist: it modifies the input artist
|
|
||||||
"""
|
|
||||||
|
|
||||||
source: Source
|
|
||||||
for source in artist.source_collection.get_sources_from_page(cls.SOURCE_TYPE):
|
|
||||||
new_artist: Artist = cls.fetch_artist_from_source(source, flat)
|
|
||||||
artist.merge(new_artist)
|
|
||||||
|
|
||||||
return artist
|
|
||||||
|
Loading…
Reference in New Issue
Block a user