music-kraken-core/src/music_kraken/objects/source.py

178 lines
5.4 KiB
Python
Raw Normal View History

2023-03-09 21:14:39 +00:00
from collections import defaultdict
2023-01-12 15:25:50 +00:00
from enum import Enum
from typing import List, Dict, Tuple, Optional
from urllib.parse import urlparse
2023-01-12 15:25:50 +00:00
2023-03-10 08:09:35 +00:00
from .metadata import Mapping, Metadata
2023-03-09 21:14:39 +00:00
from .parents import DatabaseObject
from .collection import Collection
2023-01-12 15:25:50 +00:00
2023-01-20 22:05:15 +00:00
class SourceTypes(Enum):
2023-01-16 14:37:04 +00:00
SONG = "song"
ALBUM = "album"
ARTIST = "artist"
LYRICS = "lyrics"
2023-01-20 22:05:15 +00:00
class SourcePages(Enum):
2023-01-12 15:25:50 +00:00
YOUTUBE = "youtube"
2023-01-20 22:05:15 +00:00
MUSIFY = "musify"
2023-01-16 14:37:04 +00:00
GENIUS = "genius"
MUSICBRAINZ = "musicbrainz"
ENCYCLOPAEDIA_METALLUM = "encyclopaedia metallum"
BANDCAMP = "bandcamp"
DEEZER = "deezer"
SPOTIFY = "spotify"
# This has nothing to do with audio, but bands can be here
2023-03-18 16:06:12 +00:00
WIKIPEDIA = "wikipedia"
INSTAGRAM = "instagram"
FACEBOOK = "facebook"
TWITTER = "twitter" # I will use nitter though lol
MYSPACE = "myspace" # Yes somehow this ancient site is linked EVERYWHERE
2023-01-12 15:25:50 +00:00
@classmethod
def get_homepage(cls, attribute) -> str:
homepage_map = {
2023-01-20 22:05:15 +00:00
cls.YOUTUBE: "https://www.youtube.com/",
cls.MUSIFY: "https://musify.club/",
cls.MUSICBRAINZ: "https://musicbrainz.org/",
2023-01-16 14:37:04 +00:00
cls.ENCYCLOPAEDIA_METALLUM: "https://www.metal-archives.com/",
cls.GENIUS: "https://genius.com/",
cls.BANDCAMP: "https://bandcamp.com/",
cls.DEEZER: "https://www.deezer.com/",
cls.INSTAGRAM: "https://www.instagram.com/",
cls.FACEBOOK: "https://www.facebook.com/",
cls.SPOTIFY: "https://open.spotify.com/",
cls.TWITTER: "https://twitter.com/",
2023-03-18 16:06:12 +00:00
cls.MYSPACE: "https://myspace.com/",
cls.WIKIPEDIA: "https://en.wikipedia.org/wiki/Main_Page"
2023-01-12 15:25:50 +00:00
}
return homepage_map[attribute]
2023-03-10 09:13:35 +00:00
class Source(DatabaseObject):
2023-01-12 15:25:50 +00:00
"""
create somehow like that
```python
# url won't be a valid one due to it being just an example
Source(src="youtube", url="https://youtu.be/dfnsdajlhkjhsd")
```
"""
2023-03-13 13:33:17 +00:00
COLLECTION_ATTRIBUTES = tuple()
SIMPLE_ATTRIBUTES = {
"type_enum": None,
"page_enum": None,
"url": None
}
2023-01-12 15:25:50 +00:00
2023-03-03 06:52:13 +00:00
def __init__(self, page_enum: SourcePages, url: str, id_: str = None, type_enum=None) -> None:
2023-01-12 15:25:50 +00:00
DatabaseObject.__init__(self, id_=id_)
2023-01-20 09:56:40 +00:00
self.type_enum = type_enum
2023-01-20 22:05:15 +00:00
self.page_enum = page_enum
2023-01-12 15:25:50 +00:00
self.url = url
@classmethod
def match_url(cls, url: str) -> Optional["Source"]:
"""
this shouldn't be used, unlesse you are not certain what the source is for
the reason is that it is more inefficient
"""
parsed = urlparse(url)
url = parsed.geturl()
2023-03-30 10:31:37 +00:00
if "musify" in parsed.netloc:
return cls(SourcePages.MUSIFY, url)
if url.startswith("https://www.youtube"):
return cls(SourcePages.YOUTUBE, url)
if url.startswith("https://www.deezer"):
return cls(SourcePages.DEEZER, url)
if url.startswith("https://open.spotify.com"):
return cls(SourcePages.SPOTIFY, url)
if "bandcamp" in url:
return cls(SourcePages.BANDCAMP, url)
2023-03-18 16:06:12 +00:00
if "wikipedia" in parsed.netloc:
return cls(SourcePages.WIKIPEDIA, url)
if url.startswith("https://www.metal-archives.com/"):
return cls(SourcePages.ENCYCLOPAEDIA_METALLUM, url)
# the less important once
if url.startswith("https://www.facebook"):
return cls(SourcePages.FACEBOOK, url)
if url.startswith("https://www.instagram"):
return cls(SourcePages.INSTAGRAM, url)
if url.startswith("https://twitter"):
return cls(SourcePages.TWITTER, url)
if url.startswith("https://myspace.com"):
return cls(SourcePages.MYSPACE, url)
2023-03-10 09:13:35 +00:00
def get_song_metadata(self) -> Metadata:
return Metadata({
2023-01-30 13:41:02 +00:00
Mapping.FILE_WEBPAGE_URL: [self.url],
Mapping.SOURCE_WEBPAGE_URL: [self.homepage]
})
2023-03-10 09:13:35 +00:00
def get_artist_metadata(self) -> Metadata:
return Metadata({
2023-01-30 13:41:02 +00:00
Mapping.ARTIST_WEBPAGE_URL: [self.url]
})
2023-03-10 08:09:35 +00:00
@property
def metadata(self) -> Metadata:
2023-01-20 22:05:15 +00:00
if self.type_enum == SourceTypes.SONG:
2023-01-30 13:41:02 +00:00
return self.get_song_metadata()
2023-01-20 22:05:15 +00:00
if self.type_enum == SourceTypes.ARTIST:
2023-01-30 13:41:02 +00:00
return self.get_artist_metadata()
2023-01-20 10:01:18 +00:00
2023-03-10 08:09:35 +00:00
return super().metadata
2023-01-12 16:14:21 +00:00
@property
def indexing_values(self) -> List[Tuple[str, object]]:
return [
('id', self.id),
('url', self.url)
]
2023-01-12 15:25:50 +00:00
def __str__(self):
return self.__repr__()
2023-01-12 15:25:50 +00:00
2023-01-30 13:41:02 +00:00
def __repr__(self) -> str:
return f"Src({self.page_enum.value}: {self.url})"
2023-01-20 22:05:15 +00:00
page_str = property(fget=lambda self: self.page_enum.value)
2023-01-20 09:56:40 +00:00
type_str = property(fget=lambda self: self.type_enum.value)
2023-01-20 22:05:15 +00:00
homepage = property(fget=lambda self: SourcePages.get_homepage(self.page_enum))
2023-01-25 13:14:15 +00:00
2023-03-09 21:14:39 +00:00
class SourceCollection(Collection):
def __init__(self, source_list: List[Source]):
self._page_to_source_list: Dict[SourcePages, List[Source]] = defaultdict(list)
2023-03-10 09:13:35 +00:00
super().__init__(data=source_list, element_type=Source)
2023-03-09 21:14:39 +00:00
def map_element(self, source: Source):
super().map_element(source)
self._page_to_source_list[source.page_enum].append(source)
def get_sources_from_page(self, source_page: SourcePages) -> List[Source]:
"""
getting the sources for a specific page like
YouTube or musify
"""
return self._page_to_source_list[source_page].copy()