diff --git a/assets/02.png b/assets/02.png
new file mode 100644
index 0000000..1bc91de
Binary files /dev/null and b/assets/02.png differ
diff --git a/assets/logo.jpg b/assets/logo.jpg
index a4f0a94..c31aed3 100644
Binary files a/assets/logo.jpg and b/assets/logo.jpg differ
diff --git a/assets/logo2.jpg b/assets/logo2.jpg
deleted file mode 100644
index cfa2081..0000000
Binary files a/assets/logo2.jpg and /dev/null differ
diff --git a/assets/logos/.png b/assets/logos/.png
new file mode 100644
index 0000000..df21544
Binary files /dev/null and b/assets/logos/.png differ
diff --git a/assets/logos/00.jpg b/assets/logos/00.jpg
new file mode 100644
index 0000000..a4f0a94
Binary files /dev/null and b/assets/logos/00.jpg differ
diff --git a/assets/logos/01.png b/assets/logos/01.png
new file mode 100644
index 0000000..e0c807d
Binary files /dev/null and b/assets/logos/01.png differ
diff --git a/assets/logos/01.svg b/assets/logos/01.svg
new file mode 100644
index 0000000..13e2386
--- /dev/null
+++ b/assets/logos/01.svg
@@ -0,0 +1,76 @@
+
+
+
diff --git a/assets/logos/02.png b/assets/logos/02.png
new file mode 100644
index 0000000..1bc91de
Binary files /dev/null and b/assets/logos/02.png differ
diff --git a/assets/logos/02.svg b/assets/logos/02.svg
new file mode 100644
index 0000000..306a88d
--- /dev/null
+++ b/assets/logos/02.svg
@@ -0,0 +1,80 @@
+
+
+
diff --git a/assets/logos/craiyon_142854_simplistic_black_and_white_logo_of_an_octopus_wearing_headphones__svg__cute__octupus.png b/assets/logos/craiyon_142854_simplistic_black_and_white_logo_of_an_octopus_wearing_headphones__svg__cute__octupus.png
new file mode 100644
index 0000000..7c75bb2
Binary files /dev/null and b/assets/logos/craiyon_142854_simplistic_black_and_white_logo_of_an_octopus_wearing_headphones__svg__cute__octupus.png differ
diff --git a/assets/logos/craiyon_142854_simplistic_black_and_white_logo_of_an_octopus_wearing_headphones__svg__cute__octupus.svg b/assets/logos/craiyon_142854_simplistic_black_and_white_logo_of_an_octopus_wearing_headphones__svg__cute__octupus.svg
new file mode 100644
index 0000000..bac4a90
--- /dev/null
+++ b/assets/logos/craiyon_142854_simplistic_black_and_white_logo_of_an_octopus_wearing_headphones__svg__cute__octupus.svg
@@ -0,0 +1,137 @@
+
+
+
diff --git a/assets/logos/craiyon_144924_simplistic__black_and_white_logo__octopus_wearing_headphones__svg__cute__in_frame__ce.png b/assets/logos/craiyon_144924_simplistic__black_and_white_logo__octopus_wearing_headphones__svg__cute__in_frame__ce.png
new file mode 100644
index 0000000..df21544
Binary files /dev/null and b/assets/logos/craiyon_144924_simplistic__black_and_white_logo__octopus_wearing_headphones__svg__cute__in_frame__ce.png differ
diff --git a/src/music_kraken/objects/__init__.py b/src/music_kraken/objects/__init__.py
index 232e379..ae540b7 100644
--- a/src/music_kraken/objects/__init__.py
+++ b/src/music_kraken/objects/__init__.py
@@ -3,7 +3,8 @@ from . import (
metadata,
source,
parents,
- formatted_text
+ formatted_text,
+ album
)
MusicObject = parents.DatabaseObject
@@ -21,6 +22,8 @@ Source = source.Source
Target = song.Target
Lyrics = song.Lyrics
+AlbumType = album.AlbumType
+AlbumStatus = album.AlbumStatus
Album = song.Album
FormattedText = formatted_text.FormattedText
diff --git a/src/music_kraken/objects/album.py b/src/music_kraken/objects/album.py
new file mode 100644
index 0000000..2bab8d0
--- /dev/null
+++ b/src/music_kraken/objects/album.py
@@ -0,0 +1,25 @@
+from enum import Enum
+
+
+class AlbumStatus(Enum):
+ """
+ Enum class representing the possible statuses of an album.
+ """
+ UNRELEASED = "Unreleased"
+ RELEASED = "Released"
+ LEAKED = "Leaked"
+ OFFICIAL = "Official"
+ BOOTLEG = "Bootleg"
+
+
+class AlbumType(Enum):
+ """
+ Enum class representing the possible types of an album.
+ """
+ STUDIO_ALBUM = "Studio Album"
+ EP = "EP (Extended Play)"
+ SINGLE = "Single"
+ LIVE_ALBUM = "Live Album"
+ COMPILATION_ALBUM = "Compilation Album"
+ MIXTAPE = "Mixtape"
+ OTHER = "Other"
diff --git a/src/music_kraken/objects/song.py b/src/music_kraken/objects/song.py
index fc4a526..471dff6 100644
--- a/src/music_kraken/objects/song.py
+++ b/src/music_kraken/objects/song.py
@@ -1,5 +1,5 @@
import os
-from typing import List
+from typing import List, Optional, Type
import pycountry
import copy
@@ -25,11 +25,14 @@ from .source import (
)
from .formatted_text import FormattedText
from .collection import Collection
+from .album import AlbumType, AlbumStatus
"""
All Objects dependent
"""
+CountryTyping = type(list(pycountry.countries)[0])
+
class Target(DatabaseObject, SongAttribute):
"""
@@ -49,7 +52,7 @@ class Target(DatabaseObject, SongAttribute):
def set_file(self, _file: str):
self._file = _file
- def get_file(self) -> str | None:
+ def get_file(self) -> Optional[str]:
if self._file is None:
return None
return os.path.join(MUSIC_DIR, self._file)
@@ -57,7 +60,7 @@ class Target(DatabaseObject, SongAttribute):
def set_path(self, _path: str):
self._path = _path
- def get_path(self) -> str | None:
+ def get_path(self) -> Optional[str]:
if self._path is None:
return None
return os.path.join(MUSIC_DIR, self._path)
@@ -85,7 +88,7 @@ class Lyrics(DatabaseObject, SongAttribute, SourceAttribute, MetadataAttribute):
def __init__(
self,
text: str,
- language: str,
+ language: pycountry.Languages,
id_: str = None,
source_list: List[Source] = None
) -> None:
@@ -112,7 +115,6 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
def __init__(
self,
id_: str = None,
- mb_id: str = None,
title: str = None,
isrc: str = None,
length: int = None,
@@ -121,9 +123,9 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
source_list: List[Source] = None,
target: Target = None,
lyrics_list: List[Lyrics] = None,
- album=None,
- main_artist_list: list = None,
- feature_artist_list: list = None,
+ album_list: Type['Album'] = None,
+ main_artist_list: List[Type['Artist']] = None,
+ feature_artist_list: List[Type['Artist']] = None,
**kwargs
) -> None:
"""
@@ -135,7 +137,6 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
self.title: str = title
self.isrc: str = isrc
self.length: int = length
- self.mb_id: str | None = mb_id
self.tracksort: int = tracksort or 0
self.genre: str = genre
@@ -146,7 +147,12 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
# initialize with either a passed in album, or an empty one,
# so it can at least properly generate dynamic attributes
- self._album = album or Album(empty=True)
+
+ """
+ TODO
+ put in collection
+ """
+ self._album: List[Type['Album']] = album_list or []
self.album = album
self.main_artist_collection = Collection(
@@ -168,7 +174,7 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
def get_artist_credits(self) -> str:
main_artists = ", ".join([artist.name for artist in self.main_artist_collection])
feature_artists = ", ".join([artist.name for artist in self.feature_artist_collection])
-
+
if len(feature_artists) == 0:
return main_artists
return f"{main_artists} feat. {feature_artists}"
@@ -224,9 +230,9 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
def get_option_string(self) -> str:
return f"Song({self.title}) of Album({self.album.title}) from Artists({self.get_artist_credits()})"
- tracksort_str = property(fget=get_tracksort_str)
- main_artist_list: list = property(fget=lambda self: self.main_artist_collection.copy())
- feature_artist_list: list = property(fget=lambda self: self.feature_artist_collection.copy())
+ tracksort_str: List[Type['Album']] = property(fget=get_tracksort_str)
+ main_artist_list: List[Type['Artist']] = property(fget=lambda self: self.main_artist_collection.copy())
+ feature_artist_list: List[Type['Artist']] = property(fget=lambda self: self.feature_artist_collection.copy())
"""
@@ -240,10 +246,8 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
id_: str = None,
title: str = None,
label: str = None,
- album_status: str = None,
language: pycountry.Languages = None,
date: ID3Timestamp = None,
- country: str = None,
barcode: str = None,
is_split: bool = False,
albumsort: int = None,
@@ -251,7 +255,8 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
source_list: List[Source] = None,
artist_list: list = None,
tracklist: List[Song] = None,
- album_type: str = None,
+ album_status: AlbumStatus = None,
+ album_type: AlbumType = None,
**kwargs
) -> None:
DatabaseObject.__init__(self, id_=id_, dynamic=dynamic, **kwargs)
@@ -260,18 +265,17 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
TODO
add to db
"""
- self.album_type = album_type
+ self.album_type: AlbumType = album_type
self.title: str = title
- self.album_status: str = album_status
+ self.album_status: AlbumStatus = album_status
self.label = label
self.language: pycountry.Languages = language
self.date: ID3Timestamp = date or ID3Timestamp()
- self.country: str = country
"""
TODO
find out the id3 tag for barcode and implement it
- maybee look at how mutagen does it with easy_id3
+ maybe look at how mutagen does it with easy_id3
"""
self.barcode: str = barcode
self.is_split: bool = is_split
@@ -280,8 +284,7 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
implement a function in the Artist class,
to set albumsort with help of the release year
"""
- self.albumsort: int | None = albumsort
-
+ self.albumsort: Optional[int] = albumsort
self._tracklist = Collection(
data=tracklist or [],
@@ -295,7 +298,6 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
element_type=Artist
)
-
def __str__(self) -> str:
return f"-----{self.title}-----\n{self.tracklist}"
@@ -329,13 +331,13 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
def get_copyright(self) -> str:
if self.date is None:
- return None
+ return ""
if self.date.year == 1 or self.label is None:
- return None
+ return ""
return f"{self.date.year} {self.label}"
- def get_iso_639_2_lang(self) -> str:
+ def get_iso_639_2_lang(self) -> Optional[str]:
if self.language is None:
return None
@@ -350,11 +352,10 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
options.append(new_track)
return options
-
+
def get_option_string(self) -> str:
return f"Album: {self.title}; Artists {', '.join([i.name for i in self.artists])}"
-
copyright = property(fget=get_copyright)
iso_639_2_language = property(fget=get_iso_639_2_lang)
tracklist: Collection = property(fget=lambda self: self._tracklist, fset=set_tracklist)
@@ -383,7 +384,7 @@ class Artist(DatabaseObject, SourceAttribute, MetadataAttribute):
notes: FormattedText = None,
lyrical_themes: List[str] = None,
general_genre: str = "",
- country=None,
+ country: CountryTyping = None,
formed_in: ID3Timestamp = None
):
DatabaseObject.__init__(self, id_=id_)
@@ -391,7 +392,7 @@ class Artist(DatabaseObject, SourceAttribute, MetadataAttribute):
"""
TODO implement album type and notes
"""
- self.country: pycountry.Country = country
+ self.country: CountryTyping = country
self.formed_in: ID3Timestamp = formed_in
"""
notes, generall genre, lyrics themes are attributes
@@ -429,30 +430,29 @@ class Artist(DatabaseObject, SourceAttribute, MetadataAttribute):
def __repr__(self):
return self.__str__()
- def __eq__(self, __o: object) -> bool:
+ def __eq__(self, __o: DatabaseObject) -> bool:
return self.id_ == __o.id_
def get_features(self) -> Album:
feature_release = Album(
title="features",
- album_status="dynamic",
+ album_status=AlbumStatus.UNRELEASED,
+ album_type=AlbumType.COMPILATION_ALBUM,
is_split=True,
albumsort=666,
dynamic=True
)
- for feature in self.feature_songs:
- feature_release.add_song(feature)
return feature_release
def get_all_songs(self) -> List[Song]:
"""
returns a list of all Songs.
- probaply not that usefull, because it is unsorted
+ probably not that useful, because it is unsorted
"""
collection = []
for album in self.discography:
- collection.extend(album)
+ collection.extend(album.tracklist)
return collection
diff --git a/src/tests/__init__.py b/src/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/tests/conftest.py b/src/tests/conftest.py
new file mode 100644
index 0000000..3bf1e84
--- /dev/null
+++ b/src/tests/conftest.py
@@ -0,0 +1,5 @@
+import os
+import sys
+
+# Add the parent directory of the current file (i.e., the "tests" directory) to sys.path
+sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
diff --git a/src/tests/example_data_objects.py b/src/tests/example_data_objects.py
new file mode 100644
index 0000000..56252a3
--- /dev/null
+++ b/src/tests/example_data_objects.py
@@ -0,0 +1,46 @@
+import pycountry
+
+from ..music_kraken.objects import (
+ Song,
+ Source,
+ SourcePages,
+ Target,
+ Lyrics,
+ Album
+)
+
+"""
+TODO
+create enums for Album.album_status
+move country from Album to Artist, and use pycountry.Countries
+"""
+
+song = Song(
+ title="title",
+ isrc="isrc",
+ length=666,
+ tracksort=1,
+ genre="horrorcore",
+ source_list=[
+ Source(SourcePages.YOUTUBE, "https://www.youtube.com/watch?v=dQw4w9WgXcQ"),
+ Source(SourcePages.SPOTIFY, "https://open.spotify.com/track/6rqhFgbbKwnb9MLmUQDhG6"),
+ Source(SourcePages.BANDCAMP, "https://metalband.bandcamp.com/track/song1")
+ ],
+ target=Target(file="song.mp3", path="~/Music"),
+ lyrics_list=[
+ Lyrics(text="some song lyrics", language="en")
+ ],
+ album=Album(
+ title="some album",
+ label="braindead",
+ album_status="official",
+ language=pycountry.languages.get(alpha_2='de'),
+ )
+)
+
+
+song1_sources = [
+ Source(SourcePages.YOUTUBE, "https://www.youtube.com/watch?v=dQw4w9WgXcQ"),
+ Source(SourcePages.SPOTIFY, "https://open.spotify.com/track/6rqhFgbbKwnb9MLmUQDhG6"),
+ Source(SourcePages.BANDCAMP, "https://metalband.bandcamp.com/track/song1")
+]
diff --git a/src/try.py b/src/try.py
new file mode 100644
index 0000000..24690da
--- /dev/null
+++ b/src/try.py
@@ -0,0 +1,3 @@
+from tests import example_data_objects
+
+