implemented downloading

This commit is contained in:
Hellow2 2023-03-31 10:34:29 +02:00
parent 094c4256d4
commit 5bf7392ab3
6 changed files with 74 additions and 9 deletions

View File

@ -43,4 +43,4 @@ def download_audio():
if __name__ == "__main__": if __name__ == "__main__":
download_audio() music_kraken.cli()

View File

@ -1,5 +1,5 @@
import gc import gc
from pathlib import Path
from typing import List from typing import List
import musicbrainzngs import musicbrainzngs
import logging import logging
@ -35,6 +35,12 @@ logging.getLogger("musicbrainzngs").setLevel(logging.WARNING)
musicbrainzngs.set_useragent("metadata receiver", "0.1", "https://github.com/HeIIow2/music-downloader") musicbrainzngs.set_useragent("metadata receiver", "0.1", "https://github.com/HeIIow2/music-downloader")
URL_REGGEX = 'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+' URL_REGGEX = 'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+'
DOWNLOAD_COMMANDS = {
"ok",
"download",
"\d",
"hs"
}
def cli(): def cli():
@ -52,6 +58,14 @@ def cli():
search.choose_index(int(parsed)) search.choose_index(int(parsed))
return return
if parsed in DOWNLOAD_COMMANDS:
if not search.download_chosen():
print("could not download the chosen option.. sorry.")
else:
print("success! have fun :)")
return
url = re.match(URL_REGGEX, query) url = re.match(URL_REGGEX, query)
if url is not None: if url is not None:
if not search.search_url(url.string): if not search.search_url(url.string):

View File

@ -533,7 +533,7 @@ class Artist(MainObject):
is_split=True, is_split=True,
albumsort=666, albumsort=666,
dynamic=True, dynamic=True,
song_list=self.feature_song_collection.copy() song_list=self.feature_song_collection.shallow_list
) )
def get_all_songs(self) -> List[Song]: def get_all_songs(self) -> List[Song]:

View File

@ -281,6 +281,8 @@ class Page:
@classmethod @classmethod
def download(cls, music_object: Union[Song, Album, Artist, Label], download_features: bool = True): def download(cls, music_object: Union[Song, Album, Artist, Label], download_features: bool = True):
print("downloading")
print(music_object)
if type(music_object) is Song: if type(music_object) is Song:
return cls.download_song(music_object) return cls.download_song(music_object)
if type(music_object) is Album: if type(music_object) is Album:
@ -292,6 +294,7 @@ class Page:
@classmethod @classmethod
def download_label(cls, label: Label, download_features: bool = True, override_existing: bool = False): def download_label(cls, label: Label, download_features: bool = True, override_existing: bool = False):
cls.fetch_details(label)
for artist in label.current_artist_collection: for artist in label.current_artist_collection:
cls.download_artist(artist, download_features=download_features, override_existing=override_existing) cls.download_artist(artist, download_features=download_features, override_existing=override_existing)
@ -300,22 +303,35 @@ class Page:
@classmethod @classmethod
def download_artist(cls, artist: Artist, download_features: bool = True, override_existing: bool = False): def download_artist(cls, artist: Artist, download_features: bool = True, override_existing: bool = False):
cls.fetch_details(artist)
for album in artist.main_album_collection: for album in artist.main_album_collection:
cls.download_album(album, override_existing=override_existing) cls.download_album(album, override_existing=override_existing)
if download_features: if download_features:
for song in artist.feature_album: for song in artist.feature_album.song_collection:
cls.download_song(song, override_existing=override_existing) cls.download_song(song, override_existing=override_existing)
@classmethod @classmethod
def download_album(cls, album: Album, override_existing: bool = False): def download_album(cls, album: Album, override_existing: bool = False):
cls.fetch_details(album)
for song in album.song_collection: for song in album.song_collection:
cls.download_song(song, override_existing=override_existing) cls.download_song(song, override_existing=override_existing)
@classmethod @classmethod
def download_song(cls, song: Song, override_existing: bool = False): def download_song(cls, song: Song, override_existing: bool = False, create_target_on_demand: bool = True):
cls.fetch_details(song)
if song.target_collection.empty: if song.target_collection.empty:
return if create_target_on_demand and not song.main_artist_collection.empty and not song.album_collection.empty:
song.target_collection.append(
Target(
file=f"{song.title}.mp3",
relative_to_music_dir=True,
path=f"{song.main_artist_collection[0].name}/{song.album_collection[0].title}"
)
)
else:
return
target: Target target: Target
if any(target.exists for target in song.target_collection) and not override_existing: if any(target.exists for target in song.target_collection) and not override_existing:
@ -334,6 +350,8 @@ class Page:
if len(sources) == 0: if len(sources) == 0:
return return
print("great")
temp_target: Target = Target( temp_target: Target = Target(
path=shared.TEMP_DIR, path=shared.TEMP_DIR,
file=str(random.randint(0, 999999)) file=str(random.randint(0, 999999))

View File

@ -43,3 +43,4 @@ class Download:
return source_page.fetch_object_from_source(source) return source_page.fetch_object_from_source(source)

View File

@ -11,7 +11,9 @@ class MultiPageOptions:
def __init__( def __init__(
self, self,
max_displayed_options: int = 10, max_displayed_options: int = 10,
option_digits: int = 3 option_digits: int = 3,
database_object: DatabaseObject = None,
page: Type[Page] = None
) -> None: ) -> None:
self.max_displayed_options = max_displayed_options self.max_displayed_options = max_displayed_options
self.option_digits: int = option_digits self.option_digits: int = option_digits
@ -19,6 +21,12 @@ class MultiPageOptions:
self._length = 0 self._length = 0
self._current_option_dict: Dict[Type[Page], Options] = defaultdict(lambda: Options()) self._current_option_dict: Dict[Type[Page], Options] = defaultdict(lambda: Options())
self.database_object = database_object
self.page = page
if database_object is not None and page is not None:
self[page] = database_object.options
def __getitem__(self, key: Type[Page]): def __getitem__(self, key: Type[Page]):
return self._current_option_dict[key] return self._current_option_dict[key]
@ -96,6 +104,17 @@ class MultiPageOptions:
def __repr__(self) -> str: def __repr__(self) -> str:
return self.string_from_all_pages() return self.string_from_all_pages()
def download(self) -> bool:
if self._length != 1:
return False
if self.database_object is None or self.page is None:
return False
self.page.download(self.database_object)
return True
class Search(Download): class Search(Download):
def __init__( def __init__(
@ -133,6 +152,17 @@ class Search(Download):
self._current_option = mpo self._current_option = mpo
return mpo return mpo
def next_options_from_music_obj(self, database_obj: DatabaseObject, page: Type[Page]) -> MultiPageOptions:
mpo = MultiPageOptions(
max_displayed_options=self.max_displayed_options,
option_digits=self.option_digits,
database_object=database_obj,
page=page
)
self._option_history.append(mpo)
self._current_option = mpo
return mpo
@property @property
def _previous_options(self) -> MultiPageOptions: def _previous_options(self) -> MultiPageOptions:
self._option_history.pop() self._option_history.pop()
@ -172,8 +202,7 @@ class Search(Download):
music_object = self.fetch_details(db_object) music_object = self.fetch_details(db_object)
mpo = self.next_options mpo = self.next_options_from_music_obj(music_object, page)
mpo[page] = music_object.options
def goto_previous(self): def goto_previous(self):
try: try:
@ -195,3 +224,6 @@ class Search(Download):
mpo[page] = new_object.options mpo[page] = new_object.options
return True return True
def download_chosen(self) -> bool:
return self._current_option.download()