refactored and cleaned up data objects
This commit is contained in:
parent
819111c53a
commit
5f4912bda5
@ -25,6 +25,8 @@ EVEN if that means to for example keep decimal values stored in strings.
|
|||||||
|
|
||||||
|
|
||||||
class BaseModel(Model):
|
class BaseModel(Model):
|
||||||
|
notes: str = CharField(null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
database = None
|
database = None
|
||||||
|
|
||||||
@ -38,33 +40,41 @@ class BaseModel(Model):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
class Album(BaseModel):
|
class ObjectModel(BaseModel):
|
||||||
|
additional_arguments: str = CharField(null=True)
|
||||||
|
notes: str = CharField(null=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Album(ObjectModel):
|
||||||
"""A class representing an album in the music database."""
|
"""A class representing an album in the music database."""
|
||||||
|
|
||||||
title: str = CharField(null=True)
|
title: str = CharField(null=True)
|
||||||
label: str = CharField(null=True)
|
|
||||||
album_status: str = CharField(null=True)
|
album_status: str = CharField(null=True)
|
||||||
album_type: str = CharField(null=True)
|
album_type: str = CharField(null=True)
|
||||||
language: str = CharField(null=True)
|
language: str = CharField(null=True)
|
||||||
date: str = CharField(null=True)
|
date: str = CharField(null=True)
|
||||||
date_format: str = CharField(null=True)
|
date_format: str = CharField(null=True)
|
||||||
country: str = CharField(null=True)
|
|
||||||
barcode: str = CharField(null=True)
|
barcode: str = CharField(null=True)
|
||||||
albumsort: int = IntegerField(null=True)
|
|
||||||
is_split: bool = BooleanField(default=False)
|
is_split: bool = BooleanField(default=False)
|
||||||
|
|
||||||
|
albumsort: int = IntegerField(null=True)
|
||||||
|
|
||||||
|
|
||||||
class Artist(BaseModel):
|
class Artist(BaseModel):
|
||||||
"""A class representing an artist in the music database."""
|
"""A class representing an artist in the music database."""
|
||||||
|
|
||||||
name: str = CharField()
|
name: str = CharField(null=True)
|
||||||
notes: str = CharField()
|
country: str = CharField(null=True)
|
||||||
|
formed_in_date: str = CharField(null=True)
|
||||||
|
formed_in_date_format: str = CharField(null=True)
|
||||||
|
general_genre: str = CharField(null=True)
|
||||||
|
|
||||||
|
|
||||||
class Song(BaseModel):
|
class Song(BaseModel):
|
||||||
"""A class representing a song in the music database."""
|
"""A class representing a song in the music database."""
|
||||||
|
|
||||||
name: str = CharField(null=True)
|
title: str = CharField(null=True)
|
||||||
isrc: str = CharField(null=True)
|
isrc: str = CharField(null=True)
|
||||||
length: int = IntegerField(null=True)
|
length: int = IntegerField(null=True)
|
||||||
tracksort: int = IntegerField(null=True)
|
tracksort: int = IntegerField(null=True)
|
||||||
@ -87,6 +97,12 @@ class Lyrics(BaseModel):
|
|||||||
song = ForeignKeyField(Song, backref='lyrics')
|
song = ForeignKeyField(Song, backref='lyrics')
|
||||||
|
|
||||||
|
|
||||||
|
class SongTarget(BaseModel):
|
||||||
|
song: ForeignKeyField = ForeignKeyField(Song, backref='song_target')
|
||||||
|
artist: ForeignKeyField = ForeignKeyField(Target, backref='song_target')
|
||||||
|
is_feature: bool = BooleanField(default=False)
|
||||||
|
|
||||||
|
|
||||||
class SongArtist(BaseModel):
|
class SongArtist(BaseModel):
|
||||||
"""A class representing the relationship between a song and an artist."""
|
"""A class representing the relationship between a song and an artist."""
|
||||||
|
|
||||||
|
27
src/music_kraken/objects/lyrics.py
Normal file
27
src/music_kraken/objects/lyrics.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
|
import pycountry
|
||||||
|
|
||||||
|
from .parents import DatabaseObject
|
||||||
|
from .source import SourceAttribute, Source
|
||||||
|
from .metadata import MetadataAttribute
|
||||||
|
from .formatted_text import FormattedText
|
||||||
|
|
||||||
|
|
||||||
|
class Lyrics(DatabaseObject, SourceAttribute, MetadataAttribute):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
text: FormattedText,
|
||||||
|
language: pycountry.Languages,
|
||||||
|
_id: str = None,
|
||||||
|
dynamic: bool = False,
|
||||||
|
source_list: List[Source] = None,
|
||||||
|
**kwargs
|
||||||
|
) -> None:
|
||||||
|
DatabaseObject.__init__(_id=_id, dynamic=dynamic)
|
||||||
|
|
||||||
|
self.text: FormattedText = text
|
||||||
|
self.language: pycountry.Languages = language
|
||||||
|
|
||||||
|
if source_list is not None:
|
||||||
|
self.source_list = source_list
|
@ -193,17 +193,14 @@ class ID3Timestamp:
|
|||||||
return "%Y"
|
return "%Y"
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def get_timestamp(self) -> str:
|
def get_timestamp(self) -> str:
|
||||||
time_format = self.get_time_format()
|
time_format = self.get_time_format()
|
||||||
return self.date_obj.strftime(time_format)
|
return self.date_obj.strftime(time_format)
|
||||||
|
|
||||||
|
|
||||||
def get_timestamp_w_format(self) -> Tuple[str, str]:
|
def get_timestamp_w_format(self) -> Tuple[str, str]:
|
||||||
time_format = self.get_time_format()
|
time_format = self.get_time_format()
|
||||||
return time_format, self.date_obj.strftime(time_format)
|
return time_format, self.date_obj.strftime(time_format)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def strptime(cls, time_stamp: str, format: str):
|
def strptime(cls, time_stamp: str, format: str):
|
||||||
"""
|
"""
|
||||||
|
@ -1,96 +1,48 @@
|
|||||||
|
from typing import Optional
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from src.music_kraken.utils.shared import (
|
from src.music_kraken.utils.shared import (
|
||||||
SONG_LOGGER as logger
|
SONG_LOGGER as LOGGER
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Reference:
|
|
||||||
def __init__(self, id_: str) -> None:
|
|
||||||
self.id = id_
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"references to an object with the id: {self.id}"
|
|
||||||
|
|
||||||
def __eq__(self, __o: object) -> bool:
|
|
||||||
if type(__o) != type(self):
|
|
||||||
return False
|
|
||||||
return self.id == __o.id
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseObject:
|
class DatabaseObject:
|
||||||
empty: bool
|
def __init__(self, _id: str = None, dynamic: bool = False, **kwargs) -> None:
|
||||||
|
if _id is None and not dynamic:
|
||||||
def __init__(self, id_: str = None, dynamic: bool = False, empty: bool = False, **kwargs) -> None:
|
|
||||||
"""
|
"""
|
||||||
empty means it is an placeholder.
|
generates a random UUID
|
||||||
it makes the object perform the same, it is just the same
|
|
||||||
"""
|
|
||||||
self.id_: str | None = id_
|
|
||||||
self.dynamic = dynamic
|
|
||||||
self.empty = empty
|
|
||||||
|
|
||||||
def get_id(self) -> str:
|
|
||||||
"""
|
|
||||||
returns the id if it is set, else
|
|
||||||
it returns a randomly generated UUID
|
|
||||||
https://docs.python.org/3/library/uuid.html
|
https://docs.python.org/3/library/uuid.html
|
||||||
|
|
||||||
if the object is empty, it returns None
|
|
||||||
if the object is dynamic, it raises an error
|
|
||||||
"""
|
"""
|
||||||
if self.empty:
|
_id = str(uuid.uuid4())
|
||||||
return None
|
LOGGER.info(f"id for {self.__name__} isn't set. Setting to {_id}")
|
||||||
if self.dynamic:
|
|
||||||
raise ValueError("Dynamic objects have no idea, because they are not in the database")
|
|
||||||
|
|
||||||
if self.id_ is None:
|
# The id can only be None, if the object is dynamic (self.dynamic = True)
|
||||||
self.id_ = str(uuid.uuid4())
|
self.id: Optional[str] = _id
|
||||||
logger.info(f"id for {self.__str__()} isn't set. Setting to {self.id_}")
|
|
||||||
|
|
||||||
return self.id_
|
self.dynamic = dynamic
|
||||||
|
|
||||||
def get_reference(self) -> Reference:
|
|
||||||
return Reference(self.id)
|
class MainObject(DatabaseObject):
|
||||||
|
"""
|
||||||
|
This is the parent class for all "main" data objects:
|
||||||
|
- Song
|
||||||
|
- Album
|
||||||
|
- Artist
|
||||||
|
- Label
|
||||||
|
|
||||||
|
It has all the functionality of the "DatabaseObject" (it inherits from said class)
|
||||||
|
but also some added functions as well.
|
||||||
|
"""
|
||||||
|
def __init__(self, _id: str = None, dynamic: bool = False, **kwargs):
|
||||||
|
super().__init__(_id=_id, dynamic=dynamic, **kwargs)
|
||||||
|
|
||||||
|
self.additional_arguments: dict = kwargs
|
||||||
|
|
||||||
def get_options(self) -> list:
|
def get_options(self) -> list:
|
||||||
"""
|
|
||||||
makes only sense in
|
|
||||||
- artist
|
|
||||||
- song
|
|
||||||
- album
|
|
||||||
"""
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def get_option_string(self) -> str:
|
def get_option_string(self) -> str:
|
||||||
"""
|
|
||||||
makes only sense in
|
|
||||||
- artist
|
|
||||||
- song
|
|
||||||
- album
|
|
||||||
"""
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
id = property(fget=get_id)
|
|
||||||
reference = property(fget=get_reference)
|
|
||||||
options = property(fget=get_options)
|
options = property(fget=get_options)
|
||||||
options_str = property(fget=get_option_string)
|
options_str = property(fget=get_option_string)
|
||||||
|
|
||||||
|
|
||||||
class SongAttribute:
|
|
||||||
def __init__(self, song=None):
|
|
||||||
# the reference to the song the lyrics belong to
|
|
||||||
self.song = song
|
|
||||||
|
|
||||||
def add_song(self, song):
|
|
||||||
self.song = song
|
|
||||||
|
|
||||||
def get_ref_song_id(self):
|
|
||||||
if self.song is None:
|
|
||||||
return None
|
|
||||||
return self.song.reference.id
|
|
||||||
|
|
||||||
def set_ref_song_id(self, song_id):
|
|
||||||
self.song_ref = Reference(song_id)
|
|
||||||
|
|
||||||
song_ref_id = property(fget=get_ref_song_id, fset=set_ref_song_id)
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
from typing import List, Optional, Type, Dict
|
from typing import List, Optional, Type, Dict
|
||||||
import pycountry
|
import pycountry
|
||||||
import copy
|
|
||||||
|
|
||||||
from .metadata import (
|
from .metadata import (
|
||||||
Mapping as id3Mapping,
|
Mapping as id3Mapping,
|
||||||
@ -10,12 +9,11 @@ from .metadata import (
|
|||||||
)
|
)
|
||||||
from src.music_kraken.utils.shared import (
|
from src.music_kraken.utils.shared import (
|
||||||
MUSIC_DIR,
|
MUSIC_DIR,
|
||||||
DATABASE_LOGGER as logger
|
DATABASE_LOGGER as LOGGER
|
||||||
)
|
)
|
||||||
from .parents import (
|
from .parents import (
|
||||||
DatabaseObject,
|
DatabaseObject,
|
||||||
Reference,
|
MainObject
|
||||||
SongAttribute
|
|
||||||
)
|
)
|
||||||
from .source import (
|
from .source import (
|
||||||
Source,
|
Source,
|
||||||
@ -26,6 +24,8 @@ from .source import (
|
|||||||
from .formatted_text import FormattedText
|
from .formatted_text import FormattedText
|
||||||
from .collection import Collection
|
from .collection import Collection
|
||||||
from .album import AlbumType, AlbumStatus
|
from .album import AlbumType, AlbumStatus
|
||||||
|
from .lyrics import Lyrics
|
||||||
|
from .target import Target
|
||||||
|
|
||||||
"""
|
"""
|
||||||
All Objects dependent
|
All Objects dependent
|
||||||
@ -34,77 +34,7 @@ All Objects dependent
|
|||||||
CountryTyping = type(list(pycountry.countries)[0])
|
CountryTyping = type(list(pycountry.countries)[0])
|
||||||
|
|
||||||
|
|
||||||
class Target(DatabaseObject, SongAttribute):
|
class Song(MainObject, SourceAttribute, MetadataAttribute):
|
||||||
"""
|
|
||||||
create somehow like that
|
|
||||||
```python
|
|
||||||
# I know path is pointless, and I will change that (don't worry about backwards compatibility there)
|
|
||||||
Target(file="~/Music/genre/artist/album/song.mp3", path="~/Music/genre/artist/album")
|
|
||||||
```
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, id_: str = None, file: str = None, path: str = None) -> None:
|
|
||||||
DatabaseObject.__init__(self, id_=id_)
|
|
||||||
SongAttribute.__init__(self)
|
|
||||||
self._file = file
|
|
||||||
self._path = path
|
|
||||||
|
|
||||||
def set_file(self, _file: str):
|
|
||||||
self._file = _file
|
|
||||||
|
|
||||||
def get_file(self) -> Optional[str]:
|
|
||||||
if self._file is None:
|
|
||||||
return None
|
|
||||||
return os.path.join(MUSIC_DIR, self._file)
|
|
||||||
|
|
||||||
def set_path(self, _path: str):
|
|
||||||
self._path = _path
|
|
||||||
|
|
||||||
def get_path(self) -> Optional[str]:
|
|
||||||
if self._path is None:
|
|
||||||
return None
|
|
||||||
return os.path.join(MUSIC_DIR, self._path)
|
|
||||||
|
|
||||||
def get_exists_on_disc(self) -> bool:
|
|
||||||
"""
|
|
||||||
returns True when file can be found on disc
|
|
||||||
returns False when file can't be found on disc or no filepath is set
|
|
||||||
"""
|
|
||||||
if not self.is_set():
|
|
||||||
return False
|
|
||||||
|
|
||||||
return os.path.exists(self.file)
|
|
||||||
|
|
||||||
def is_set(self) -> bool:
|
|
||||||
return not (self._file is None or self._path is None)
|
|
||||||
|
|
||||||
file = property(fget=get_file, fset=set_file)
|
|
||||||
path = property(fget=get_path, fset=set_path)
|
|
||||||
|
|
||||||
exists_on_disc = property(fget=get_exists_on_disc)
|
|
||||||
|
|
||||||
|
|
||||||
class Lyrics(DatabaseObject, SongAttribute, SourceAttribute, MetadataAttribute):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
text: str,
|
|
||||||
language: pycountry.Languages,
|
|
||||||
id_: str = None,
|
|
||||||
source_list: List[Source] = None
|
|
||||||
) -> None:
|
|
||||||
DatabaseObject.__init__(self, id_=id_)
|
|
||||||
SongAttribute.__init__(self)
|
|
||||||
self.text = text
|
|
||||||
self.language = language
|
|
||||||
|
|
||||||
if source_list is not None:
|
|
||||||
self.source_list = source_list
|
|
||||||
|
|
||||||
def get_metadata(self) -> MetadataAttribute.Metadata:
|
|
||||||
return super().get_metadata()
|
|
||||||
|
|
||||||
|
|
||||||
class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|
||||||
"""
|
"""
|
||||||
Class representing a song object, with attributes id, mb_id, title, album_name, isrc, length,
|
Class representing a song object, with attributes id, mb_id, title, album_name, isrc, length,
|
||||||
tracksort, genre, source_list, target, lyrics_list, album, main_artist_list, and feature_artist_list.
|
tracksort, genre, source_list, target, lyrics_list, album, main_artist_list, and feature_artist_list.
|
||||||
@ -114,14 +44,15 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
id_: str = None,
|
_id: str = None,
|
||||||
|
dynamic: bool = False,
|
||||||
title: str = None,
|
title: str = None,
|
||||||
isrc: str = None,
|
isrc: str = None,
|
||||||
length: int = None,
|
length: int = None,
|
||||||
tracksort: int = None,
|
tracksort: int = None,
|
||||||
genre: str = None,
|
genre: str = None,
|
||||||
source_list: List[Source] = None,
|
source_list: List[Source] = None,
|
||||||
target_list: Target = None,
|
target_list: List[Target] = None,
|
||||||
lyrics_list: List[Lyrics] = None,
|
lyrics_list: List[Lyrics] = None,
|
||||||
album_list: Type['Album'] = None,
|
album_list: Type['Album'] = None,
|
||||||
main_artist_list: List[Type['Artist']] = None,
|
main_artist_list: List[Type['Artist']] = None,
|
||||||
@ -131,7 +62,7 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
"""
|
"""
|
||||||
Initializes the Song object with the following attributes:
|
Initializes the Song object with the following attributes:
|
||||||
"""
|
"""
|
||||||
super().__init__(id_=id_, **kwargs)
|
MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs)
|
||||||
# attributes
|
# attributes
|
||||||
self.title: str = title
|
self.title: str = title
|
||||||
self.isrc: str = isrc
|
self.isrc: str = isrc
|
||||||
@ -242,10 +173,10 @@ All objects dependent on Album
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
|
class Album(MainObject, SourceAttribute, MetadataAttribute):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
id_: str = None,
|
_id: str = None,
|
||||||
title: str = None,
|
title: str = None,
|
||||||
language: pycountry.Languages = None,
|
language: pycountry.Languages = None,
|
||||||
date: ID3Timestamp = None,
|
date: ID3Timestamp = None,
|
||||||
@ -261,7 +192,7 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
label_list: List[Type['Label']] = None,
|
label_list: List[Type['Label']] = None,
|
||||||
**kwargs
|
**kwargs
|
||||||
) -> None:
|
) -> None:
|
||||||
DatabaseObject.__init__(self, id_=id_, dynamic=dynamic, **kwargs)
|
MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs)
|
||||||
|
|
||||||
self.title: str = title
|
self.title: str = title
|
||||||
self.album_status: AlbumStatus = album_status
|
self.album_status: AlbumStatus = album_status
|
||||||
@ -384,10 +315,11 @@ All objects dependent on Artist
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Artist(DatabaseObject, SourceAttribute, MetadataAttribute):
|
class Artist(MainObject, SourceAttribute, MetadataAttribute):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
id_: str = None,
|
_id: str = None,
|
||||||
|
dynamic: bool = False,
|
||||||
name: str = None,
|
name: str = None,
|
||||||
source_list: List[Source] = None,
|
source_list: List[Source] = None,
|
||||||
feature_song_list: List[Song] = None,
|
feature_song_list: List[Song] = None,
|
||||||
@ -398,8 +330,11 @@ class Artist(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
country: CountryTyping = None,
|
country: CountryTyping = None,
|
||||||
formed_in: ID3Timestamp = None,
|
formed_in: ID3Timestamp = None,
|
||||||
label_list: List[Type['Label']] = None,
|
label_list: List[Type['Label']] = None,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
DatabaseObject.__init__(self, id_=id_)
|
MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs)
|
||||||
|
|
||||||
|
self.name: str = name
|
||||||
|
|
||||||
"""
|
"""
|
||||||
TODO implement album type and notes
|
TODO implement album type and notes
|
||||||
@ -412,11 +347,13 @@ class Artist(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
i mean do as you want but there aint no strict rule about em so good luck
|
i mean do as you want but there aint no strict rule about em so good luck
|
||||||
"""
|
"""
|
||||||
self.notes: FormattedText = notes or FormattedText()
|
self.notes: FormattedText = notes or FormattedText()
|
||||||
|
"""
|
||||||
|
TODO
|
||||||
|
implement in db
|
||||||
|
"""
|
||||||
self.lyrical_themes: List[str] = lyrical_themes or []
|
self.lyrical_themes: List[str] = lyrical_themes or []
|
||||||
self.general_genre = general_genre
|
self.general_genre = general_genre
|
||||||
|
|
||||||
self.name: str = name
|
|
||||||
|
|
||||||
self.feature_song_collection: Collection = Collection(
|
self.feature_song_collection: Collection = Collection(
|
||||||
data=feature_song_list,
|
data=feature_song_list,
|
||||||
map_attributes=["title"],
|
map_attributes=["title"],
|
||||||
@ -526,17 +463,18 @@ Label
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Label(DatabaseObject, SourceAttribute, MetadataAttribute):
|
class Label(MainObject, SourceAttribute, MetadataAttribute):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
id_: str = None,
|
_id: str = None,
|
||||||
|
dynamic: bool = False,
|
||||||
name: str = None,
|
name: str = 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,
|
||||||
**kwargs
|
**kwargs
|
||||||
):
|
):
|
||||||
DatabaseObject.__init__(self, id_=id_)
|
MainObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs)
|
||||||
|
|
||||||
self.name: str = name
|
self.name: str = name
|
||||||
|
|
||||||
@ -553,7 +491,11 @@ class Label(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.source_list = source_list or []
|
self.source_list = source_list or []
|
||||||
self.additional_attributes = kwargs
|
|
||||||
|
|
||||||
album_list = property(fget=lambda self: self.album_collection.copy())
|
@property
|
||||||
current_artist_list = property(fget=lambda self: self.current_artist_collection.copy())
|
def album_list(self) -> List[Album]:
|
||||||
|
return self.album_collection.copy()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_artist_list(self) -> List[Artist]:
|
||||||
|
self.current_artist_collection.copy()
|
||||||
|
@ -133,7 +133,7 @@ class SourceAttribute:
|
|||||||
This is a class that is meant to be inherited from.
|
This is a class that is meant to be inherited from.
|
||||||
it adds the source_list attribute to a class
|
it adds the source_list attribute to a class
|
||||||
"""
|
"""
|
||||||
_source_dict: Dict[object, List[Source]]
|
_source_dict: Dict[SourcePages, List[Source]]
|
||||||
source_url_map: Dict[str, Source]
|
source_url_map: Dict[str, Source]
|
||||||
|
|
||||||
def __new__(cls, **kwargs):
|
def __new__(cls, **kwargs):
|
||||||
|
35
src/music_kraken/objects/target.py
Normal file
35
src/music_kraken/objects/target.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from ..utils import shared
|
||||||
|
from .parents import DatabaseObject
|
||||||
|
|
||||||
|
|
||||||
|
class Target(DatabaseObject):
|
||||||
|
"""
|
||||||
|
create somehow like that
|
||||||
|
```python
|
||||||
|
# I know path is pointless, and I will change that (don't worry about backwards compatibility there)
|
||||||
|
Target(file="song.mp3", path="~/Music/genre/artist/album")
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
file: str = None,
|
||||||
|
path: str = None,
|
||||||
|
_id: str = None,
|
||||||
|
dynamic: bool = False,
|
||||||
|
relative_to_music_dir: bool = False
|
||||||
|
) -> None:
|
||||||
|
super().__init__(_id=_id, dynamic=dynamic)
|
||||||
|
self._file: Path = Path(file)
|
||||||
|
self._path = path
|
||||||
|
|
||||||
|
self.is_relative_to_music_dir: bool = relative_to_music_dir
|
||||||
|
|
||||||
|
@property
|
||||||
|
def file_path(self) -> Path:
|
||||||
|
if self.is_relative_to_music_dir:
|
||||||
|
return Path(shared.MUSIC_DIR, self._path, self._file)
|
||||||
|
return Path(self._path, self._file)
|
Loading…
Reference in New Issue
Block a user