refactored merging function to take default values other than None into account parents.py

This commit is contained in:
Hellow 2023-03-18 12:36:53 +01:00
parent 5bd9439104
commit 862c25dd35
8 changed files with 103 additions and 33 deletions

View File

@ -43,19 +43,32 @@ class FormattedText:
def get_markdown(self) -> str: def get_markdown(self) -> str:
if self.doc is None: if self.doc is None:
return None return ""
return pandoc.write(self.doc, format="markdown").strip() return pandoc.write(self.doc, format="markdown").strip()
def get_html(self) -> str: def get_html(self) -> str:
if self.doc is None: if self.doc is None:
return None return ""
return pandoc.write(self.doc, format="html").strip() return pandoc.write(self.doc, format="html").strip()
def get_plaintext(self) -> str: def get_plaintext(self) -> str:
if self.doc is None: if self.doc is None:
return None return ""
return pandoc.write(self.doc, format="plain").strip() return pandoc.write(self.doc, format="plain").strip()
@property
def is_empty(self) -> bool:
return self.doc is None
def __eq__(self, other) -> False:
if type(other) != type(self):
return False
if self.is_empty and other.is_empty:
return True
return self.doc == other.doc
plaintext = property(fget=get_plaintext, fset=set_plaintext) plaintext = property(fget=get_plaintext, fset=set_plaintext)
markdown = property(fget=get_markdown, fset=set_markdown) markdown = property(fget=get_markdown, fset=set_markdown)

View File

@ -1,16 +1,18 @@
from typing import List from typing import List
from collections import defaultdict
import pycountry import pycountry
from .parents import DatabaseObject from .parents import DatabaseObject
from .source import Source, SourceCollection from .source import Source, SourceCollection
from .metadata import Metadata
from .formatted_text import FormattedText from .formatted_text import FormattedText
class Lyrics(DatabaseObject): class Lyrics(DatabaseObject):
COLLECTION_ATTRIBUTES = ("source_collection",) COLLECTION_ATTRIBUTES = ("source_collection",)
SIMPLE_ATTRIBUTES = ("text", "language") SIMPLE_ATTRIBUTES = {
"text": FormattedText(),
"language": None
}
def __init__( def __init__(
self, self,
@ -21,9 +23,9 @@ class Lyrics(DatabaseObject):
source_list: List[Source] = None, source_list: List[Source] = None,
**kwargs **kwargs
) -> None: ) -> None:
DatabaseObject.__init__(self, _id=_id, dynamic=dynamic) DatabaseObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs)
self.text: FormattedText = text self.text: FormattedText = text or FormattedText()
self.language: pycountry.Languages = language self.language: pycountry.Languages = language
self.source_collection: SourceCollection = SourceCollection(source_list) self.source_collection: SourceCollection = SourceCollection(source_list)

View File

@ -154,6 +154,8 @@ class ID3Timestamp:
return self.date_obj >= other.date_obj return self.date_obj >= other.date_obj
def __eq__(self, other): def __eq__(self, other):
if type(other) != type(self):
return False
return self.date_obj == other.date_obj return self.date_obj == other.date_obj
def get_time_format(self) -> str: def get_time_format(self) -> str:

View File

@ -11,11 +11,11 @@ from .option import Options
class DatabaseObject: class DatabaseObject:
COLLECTION_ATTRIBUTES: tuple = tuple() COLLECTION_ATTRIBUTES: tuple = tuple()
SIMPLE_ATTRIBUTES: tuple = tuple() SIMPLE_ATTRIBUTES: dict = dict()
def __init__(self, _id: str = None, dynamic: bool = False, **kwargs) -> None: def __init__(self, _id: str = None, dynamic: bool = False, **kwargs) -> None:
self.automatic_id: bool = False self.automatic_id: bool = False
if _id is None and not dynamic: if _id is None and not dynamic:
""" """
generates a random UUID generates a random UUID
@ -46,7 +46,7 @@ class DatabaseObject:
return True return True
return False return False
@property @property
def indexing_values(self) -> List[Tuple[str, object]]: def indexing_values(self) -> List[Tuple[str, object]]:
""" """
@ -56,9 +56,9 @@ class DatabaseObject:
Returns: Returns:
List[Tuple[str, object]]: the first element in the tuple is the name of the attribute, the second the value. List[Tuple[str, object]]: the first element in the tuple is the name of the attribute, the second the value.
""" """
return list() return list()
def merge(self, other, override: bool = False): def merge(self, other, override: bool = False):
if not isinstance(other, type(self)): if not isinstance(other, type(self)):
LOGGER.warning(f"can't merge \"{type(other)}\" into \"{type(self)}\"") LOGGER.warning(f"can't merge \"{type(other)}\" into \"{type(self)}\"")
@ -67,14 +67,13 @@ class DatabaseObject:
for collection in type(self).COLLECTION_ATTRIBUTES: for collection in type(self).COLLECTION_ATTRIBUTES:
getattr(self, collection).extend(getattr(other, collection)) getattr(self, collection).extend(getattr(other, collection))
for simple_attribute in type(self).SIMPLE_ATTRIBUTES: for simple_attribute, default_value in type(self).SIMPLE_ATTRIBUTES.items():
if getattr(other, simple_attribute) is None: if getattr(other, simple_attribute) == default_value:
continue continue
if override or getattr(self, simple_attribute) is None: if override or getattr(self, simple_attribute) == default_value:
setattr(self, simple_attribute, getattr(other, simple_attribute)) setattr(self, simple_attribute, getattr(other, simple_attribute))
@property @property
def metadata(self) -> Metadata: def metadata(self) -> Metadata:
return Metadata() return Metadata()
@ -86,7 +85,7 @@ class DatabaseObject:
@property @property
def option_string(self) -> str: def option_string(self) -> str:
return self.__repr__() return self.__repr__()
def compile(self) -> bool: def compile(self) -> bool:
""" """
compiles the recursive structures, compiles the recursive structures,
@ -111,7 +110,7 @@ class MainObject(DatabaseObject):
It has all the functionality of the "DatabaseObject" (it inherits from said class) It has all the functionality of the "DatabaseObject" (it inherits from said class)
but also some added functions as well. but also some added functions as well.
""" """
def __init__(self, _id: str = None, dynamic: bool = False, **kwargs): def __init__(self, _id: str = None, dynamic: bool = False, **kwargs):
DatabaseObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs) DatabaseObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs)

View File

@ -1,6 +1,7 @@
import os import os
from typing import List, Optional, Dict, Tuple from typing import List, Optional, Dict, Tuple
import pycountry import pycountry
from collections import defaultdict
from .metadata import ( from .metadata import (
Mapping as id3Mapping, Mapping as id3Mapping,
@ -46,7 +47,15 @@ class Song(MainObject):
COLLECTION_ATTRIBUTES = ( COLLECTION_ATTRIBUTES = (
"lyrics_collection", "album_collection", "main_artist_collection", "feature_artist_collection", "lyrics_collection", "album_collection", "main_artist_collection", "feature_artist_collection",
"source_collection") "source_collection")
SIMPLE_ATTRIBUTES = ("title", "unified_title", "isrc", "length", "tracksort", "genre") SIMPLE_ATTRIBUTES = {
"title": None,
"unified_title": None,
"isrc": None,
"length": None,
"tracksort": 0,
"genre": None,
"notes": FormattedText()
}
def __init__( def __init__(
self, self,
@ -64,17 +73,21 @@ class Song(MainObject):
album_list: List['Album'] = None, album_list: List['Album'] = None,
main_artist_list: List['Artist'] = None, main_artist_list: List['Artist'] = None,
feature_artist_list: List['Artist'] = None, feature_artist_list: List['Artist'] = None,
notes: FormattedText = None,
**kwargs **kwargs
) -> None: ) -> None:
MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs) MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs)
# attributes # attributes
self.title: str = title self.title: str = title
self.unified_title: str = unified_title or unify(title) self.unified_title: str = unified_title
if unified_title is None and title is not None:
self.unified_title = unify(title)
self.isrc: str = isrc self.isrc: str = isrc
self.length: int = length self.length: int = length
self.tracksort: int = tracksort or 0 self.tracksort: int = tracksort or 0
self.genre: str = genre self.genre: str = genre
self.notes: FormattedText = notes or FormattedText()
self.source_collection: SourceCollection = SourceCollection(source_list) self.source_collection: SourceCollection = SourceCollection(source_list)
self.target_collection: Collection = Collection(data=target_list, element_type=Target) self.target_collection: Collection = Collection(data=target_list, element_type=Target)
@ -181,7 +194,17 @@ All objects dependent on Album
class Album(MainObject): class Album(MainObject):
COLLECTION_ATTRIBUTES = ("label_collection", "artist_collection", "song_collection") COLLECTION_ATTRIBUTES = ("label_collection", "artist_collection", "song_collection")
SIMPLE_ATTRIBUTES = ("title", "album_status", "album_type", "language", "date", "barcode", "albumsort") SIMPLE_ATTRIBUTES = {
"title": None,
"unified_title": None,
"album_status": None,
"album_type": AlbumType.OTHER,
"language": None,
"date": ID3Timestamp(),
"barcode": None,
"albumsort": None,
"notes": FormattedText()
}
def __init__( def __init__(
self, self,
@ -199,15 +222,18 @@ class Album(MainObject):
album_status: AlbumStatus = None, album_status: AlbumStatus = None,
album_type: AlbumType = None, album_type: AlbumType = None,
label_list: List['Label'] = None, label_list: List['Label'] = None,
notes: FormattedText = None,
**kwargs **kwargs
) -> None: ) -> None:
MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs) MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs)
self.title: str = title self.title: str = title
self.unified_title: str = unified_title or unify(self.title) self.unified_title: str = unified_title
if unified_title is None and title is not None:
self.unified_title = unify(title)
self.album_status: AlbumStatus = album_status self.album_status: AlbumStatus = album_status
self.album_type: AlbumType = album_type self.album_type: AlbumType = album_type or AlbumType.OTHER
self.language: pycountry.Languages = language self.language: pycountry.Languages = language
self.date: ID3Timestamp = date or ID3Timestamp() self.date: ID3Timestamp = date or ID3Timestamp()
@ -223,6 +249,7 @@ class Album(MainObject):
to set albumsort with help of the release year to set albumsort with help of the release year
""" """
self.albumsort: Optional[int] = albumsort self.albumsort: Optional[int] = albumsort
self.notes = notes or FormattedText()
self.source_collection: SourceCollection = SourceCollection(source_list) self.source_collection: SourceCollection = SourceCollection(source_list)
self.song_collection: Collection = Collection(data=song_list, element_type=Song) self.song_collection: Collection = Collection(data=song_list, element_type=Song)
@ -230,7 +257,7 @@ class Album(MainObject):
self.label_collection: Collection = Collection(data=label_list, element_type=Label) self.label_collection: Collection = Collection(data=label_list, element_type=Label)
def compile(self): def compile(self):
song: "Song" song: Song
for song in self.song_collection: for song in self.song_collection:
if song.album_collection.insecure_append(self): if song.album_collection.insecure_append(self):
song.compile() song.compile()
@ -351,7 +378,15 @@ All objects dependent on Artist
class Artist(MainObject): class Artist(MainObject):
COLLECTION_ATTRIBUTES = ("feature_song_collection", "main_album_collection", "label_collection") COLLECTION_ATTRIBUTES = ("feature_song_collection", "main_album_collection", "label_collection")
SIMPLE_ATTRIBUTES = ("name", "name", "country", "formed_in", "notes", "lyrical_themes", "general_genre") SIMPLE_ATTRIBUTES = {
"name": None,
"unified_name": None,
"country": None,
"formed_in": ID3Timestamp(),
"notes": FormattedText(),
"lyrical_themes": [],
"general_genre": ""
}
def __init__( def __init__(
self, self,
@ -373,7 +408,9 @@ class Artist(MainObject):
MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs) MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs)
self.name: str = name self.name: str = name
self.unified_name: str = unified_name or unify(self.name) self.unified_name: str = unified_name
if unified_name is None and name is not None:
self.unified_name = unify(name)
""" """
TODO implement album type and notes TODO implement album type and notes
@ -512,7 +549,11 @@ Label
class Label(MainObject): class Label(MainObject):
COLLECTION_ATTRIBUTES = ("album_collection", "current_artist_collection") COLLECTION_ATTRIBUTES = ("album_collection", "current_artist_collection")
SIMPLE_ATTRIBUTES = ("name",) SIMPLE_ATTRIBUTES = {
"name": None,
"unified_name": None,
"notes": FormattedText()
}
def __init__( def __init__(
self, self,
@ -520,6 +561,7 @@ class Label(MainObject):
dynamic: bool = False, dynamic: bool = False,
name: str = None, name: str = None,
unified_name: str = None, unified_name: str = None,
notes: FormattedText = None,
album_list: List[Album] = None, album_list: List[Album] = None,
current_artist_list: List[Artist] = None, current_artist_list: List[Artist] = None,
source_list: List[Source] = None, source_list: List[Source] = None,
@ -528,7 +570,10 @@ class Label(MainObject):
MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs) MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs)
self.name: str = name self.name: str = name
self.unified_name: str = unified_name or unify(self.name) self.unified_name: str = unified_name
if unified_name is None and name is not None:
self.unified_name = unify(name)
self.notes = notes or FormattedText()
self.source_collection: SourceCollection = SourceCollection(source_list) self.source_collection: SourceCollection = SourceCollection(source_list)
self.album_collection: Collection = Collection(data=album_list, element_type=Album) self.album_collection: Collection = Collection(data=album_list, element_type=Album)

View File

@ -56,7 +56,11 @@ class Source(DatabaseObject):
``` ```
""" """
COLLECTION_ATTRIBUTES = tuple() COLLECTION_ATTRIBUTES = tuple()
SIMPLE_ATTRIBUTES = ("type_enum", "page_enum", "url") SIMPLE_ATTRIBUTES = {
"type_enum": None,
"page_enum": None,
"url": None
}
def __init__(self, page_enum: SourcePages, url: str, id_: str = None, type_enum=None) -> None: def __init__(self, page_enum: SourcePages, url: str, id_: str = None, type_enum=None) -> None:
DatabaseObject.__init__(self, id_=id_) DatabaseObject.__init__(self, id_=id_)

View File

@ -1,5 +1,6 @@
from typing import Optional, List, Tuple from typing import Optional, List, Tuple
from pathlib import Path from pathlib import Path
from collections import defaultdict
from ..utils import shared from ..utils import shared
from .parents import DatabaseObject from .parents import DatabaseObject
@ -14,7 +15,10 @@ class Target(DatabaseObject):
``` ```
""" """
SIMPLE_ATTRIBUTES = ("_file", "_path") SIMPLE_ATTRIBUTES = {
"_file": None,
"_path": None
}
COLLECTION_ATTRIBUTES = tuple() COLLECTION_ATTRIBUTES = tuple()
def __init__( def __init__(

View File

@ -12,9 +12,10 @@ def fetch_artist():
name="Ghost Bath", name="Ghost Bath",
source_list=[objects.Source(objects.SourcePages.MUSIFY, "https://musify.club/artist/psychonaut-4-83193")] source_list=[objects.Source(objects.SourcePages.MUSIFY, "https://musify.club/artist/psychonaut-4-83193")]
) )
artist = Musify.fetch_details(artist) artist = Musify.fetch_details(artist)
print(artist.options) print(artist.options)
if __name__ == "__main__": if __name__ == "__main__":
fetch_artist() fetch_artist()