From 1a3f1648271af6e31dc762d5c1a951d1044257db Mon Sep 17 00:00:00 2001 From: Lars Noack Date: Mon, 15 Jan 2024 11:40:48 +0100 Subject: [PATCH] fix: downloads --- src/music_kraken/audio/codec.py | 4 +-- src/music_kraken/objects/collection.py | 1 + src/music_kraken/objects/song.py | 8 ++--- src/music_kraken/objects/target.py | 2 +- src/music_kraken/pages/bandcamp.py | 48 ++++++++++++-------------- src/music_kraken/pages/musify.py | 2 +- 6 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/music_kraken/audio/codec.py b/src/music_kraken/audio/codec.py index afb3a0f..9ec70e6 100644 --- a/src/music_kraken/audio/codec.py +++ b/src/music_kraken/audio/codec.py @@ -1,3 +1,4 @@ +from pathlib import Path from typing import List, Tuple from tqdm import tqdm from ffmpeg_progress_yield import FfmpegProgress @@ -19,8 +20,7 @@ def correct_codec(target: Target, bitrate_kb: int = main_settings["bitrate"], au bitrate_b = int(bitrate_kb / 1024) output_target = Target( - path=target._path, - file=str(target._file) + "." + audio_format + file_path=Path(str(target.file_path) + "." + audio_format) ) # get the select thingie diff --git a/src/music_kraken/objects/collection.py b/src/music_kraken/objects/collection.py index ee99692..a3b1bbf 100644 --- a/src/music_kraken/objects/collection.py +++ b/src/music_kraken/objects/collection.py @@ -229,6 +229,7 @@ class Collection(Generic[T]): if existing_object is None: # append + # print("appending", existing_object, __object) append_to._data.append(__object) else: # merge diff --git a/src/music_kraken/objects/song.py b/src/music_kraken/objects/song.py index a113c6f..120f109 100644 --- a/src/music_kraken/objects/song.py +++ b/src/music_kraken/objects/song.py @@ -68,7 +68,7 @@ class Song(Base): } def __init__(self, title: str = None, unified_title: str = None, isrc: str = None, length: int = None, - genre: str = None, note: FormattedText = None, source_list: SourceCollection = None, + genre: str = None, note: FormattedText = None, source_list: List[Source] = None, target_list: List[Target] = None, lyrics_list: List[Lyrics] = None, main_artist_list: List[Artist] = None, feature_artist_list: List[Artist] = None, album_list: List[Album] = None, **kwargs) -> None: @@ -214,7 +214,7 @@ class Album(Base): def __init__(self, title: str = None, unified_title: str = None, album_status: AlbumStatus = None, album_type: AlbumType = None, language: Language = None, date: ID3Timestamp = None, barcode: str = None, albumsort: int = None, notes: FormattedText = None, - source_list: SourceCollection = None, artist_list: List[Artist] = None, song_list: List[Song] = None, + source_list: List[Source] = None, artist_list: List[Artist] = None, song_list: List[Song] = None, label_list: List[Label] = None, **kwargs) -> None: super().__init__(title=title, unified_title=unified_title, album_status=album_status, album_type=album_type, language=language, date=date, barcode=barcode, albumsort=albumsort, notes=notes, @@ -410,7 +410,7 @@ class Artist(Base): # This is automatically generated def __init__(self, name: str = None, unified_name: str = None, country: Country = None, formed_in: ID3Timestamp = None, notes: FormattedText = None, lyrical_themes: List[str] = None, - general_genre: str = None, unformated_location: str = None, source_list: SourceCollection = None, + general_genre: str = None, unformated_location: str = None, source_list: List[Source] = None, contact_list: List[Contact] = None, feature_song_list: List[Song] = None, main_album_list: List[Album] = None, label_list: List[Label] = None, **kwargs) -> None: @@ -604,7 +604,7 @@ class Label(Base): } def __init__(self, name: str = None, unified_name: str = None, notes: FormattedText = None, - source_list: SourceCollection = None, contact_list: List[Contact] = None, + source_list: List[Source] = None, contact_list: List[Contact] = None, album_list: List[Album] = None, current_artist_list: List[Artist] = None, **kwargs) -> None: super().__init__(name=name, unified_name=unified_name, notes=notes, source_list=source_list, contact_list=contact_list, album_list=album_list, current_artist_list=current_artist_list, diff --git a/src/music_kraken/objects/target.py b/src/music_kraken/objects/target.py index c6a5b0e..35afd4a 100644 --- a/src/music_kraken/objects/target.py +++ b/src/music_kraken/objects/target.py @@ -64,7 +64,7 @@ class Target(OuterProxy): return self.file_path.stat().st_size def create_path(self): - self._path.mkdir(parents=True, exist_ok=True) + self.file_path.parent.mkdir(parents=True, exist_ok=True) def copy_content(self, copy_to: Target): if not self.exists: diff --git a/src/music_kraken/pages/bandcamp.py b/src/music_kraken/pages/bandcamp.py index c0d1bb3..4a0d5da 100644 --- a/src/music_kraken/pages/bandcamp.py +++ b/src/music_kraken/pages/bandcamp.py @@ -24,6 +24,7 @@ from ..connection import Connection from ..utils.support_classes.download_result import DownloadResult from ..utils.config import main_settings, logging_settings from ..utils.shared import DEBUG + if DEBUG: from ..utils.debug_utils import dump_to_file @@ -38,7 +39,6 @@ def _get_host(source: Source) -> str: return urlunparse((parsed.scheme, parsed.netloc, "", "", "", "")) - class BandcampTypes(Enum): ARTIST = "b" ALBUM = "a" @@ -55,7 +55,7 @@ class Bandcamp(Page): host="https://bandcamp.com/", logger=self.LOGGER ) - + super().__init__(*args, **kwargs) def get_source_type(self, source: Source) -> Optional[Type[DatabaseObject]]: @@ -68,7 +68,7 @@ class Bandcamp(Page): return Album if path.startswith("track"): return Song - + return super().get_source_type(source) def _parse_autocomplete_api_result(self, data: dict) -> DatabaseObject: @@ -124,7 +124,7 @@ class Bandcamp(Page): ) ] ) - + def general_search(self, search_query: str, filter_string: str = "") -> List[DatabaseObject]: results = [] @@ -148,19 +148,18 @@ class Bandcamp(Page): results.append(r) return results - + def label_search(self, label: Label) -> List[Label]: return self.general_search(label.name, filter_string="b") - + def artist_search(self, artist: Artist) -> List[Artist]: return self.general_search(artist.name, filter_string="b") - + def album_search(self, album: Album) -> List[Album]: return self.general_search(album.title, filter_string="a") - + def song_search(self, song: Song) -> List[Song]: return self.general_search(song.title, filter_string="t") - def fetch_label(self, source: Source, stop_at_level: int = 1) -> Label: return Label() @@ -169,13 +168,13 @@ class Bandcamp(Page): name: str = None source_list: List[Source] = [] contact_list: List[Contact] = [] - + band_name_location: BeautifulSoup = soup.find("p", {"id": "band-name-location"}) if band_name_location is not None: title_span = band_name_location.find("span", {"class": "title"}) if title_span is not None: name = title_span.text.strip() - + link_container: BeautifulSoup = soup.find("ol", {"id": "band-links"}) if link_container is not None: li: BeautifulSoup @@ -189,7 +188,7 @@ class Bandcamp(Page): name=name, source_list=source_list ) - + def _parse_album(self, soup: BeautifulSoup, initial_source: Source) -> List[Album]: title = None source_list: List[Source] = [] @@ -197,7 +196,7 @@ class Bandcamp(Page): a = soup.find("a") if a is not None and a["href"] is not None: source_list.append(Source(self.SOURCE_TYPE, _get_host(initial_source) + a["href"])) - + title_p = soup.find("p", {"class": "title"}) if title_p is not None: title = title_p.text.strip() @@ -219,14 +218,13 @@ class Bandcamp(Page): return album_list - def fetch_artist(self, source: Source, stop_at_level: int = 1) -> Artist: artist = Artist() r = self.connection.get(_parse_artist_url(source.url)) if r is None: return artist - + soup = self.get_soup_from_response(r) if DEBUG: @@ -238,7 +236,7 @@ class Bandcamp(Page): if html_music_grid is not None: for subsoup in html_music_grid.find_all("li"): artist.main_album_collection.append(self._parse_album(soup=subsoup, initial_source=source)) - + for i, data_blob_soup in enumerate(soup.find_all("div", {"id": ["pagedata", "collectors-data"]})): data_blob = data_blob_soup["data-blob"] @@ -252,7 +250,7 @@ class Bandcamp(Page): artist.source_collection.append(source) return artist - + def _parse_track_element(self, track: dict) -> Optional[Song]: return Song( title=track["item"]["name"].strip(), @@ -266,11 +264,11 @@ class Bandcamp(Page): r = self.connection.get(source.url) if r is None: return album - + soup = self.get_soup_from_response(r) data_container = soup.find("script", {"type": "application/ld+json"}) - + if DEBUG: dump_to_file("album_data.json", data_container.text, is_json=True, exit_after_dump=False) @@ -279,7 +277,7 @@ class Bandcamp(Page): artist_source_list = [] if "@id" in artist_data: - artist_source_list=[Source(self.SOURCE_TYPE, _parse_artist_url(artist_data["@id"]))] + artist_source_list = [Source(self.SOURCE_TYPE, _parse_artist_url(artist_data["@id"]))] album = Album( title=data["name"].strip(), source_list=[Source(self.SOURCE_TYPE, data.get("mainEntityOfPage", data["@id"]))], @@ -307,15 +305,14 @@ class Bandcamp(Page): if track_lyrics: self.LOGGER.debug(" Lyrics retrieved..") return [Lyrics(text=FormattedText(html=track_lyrics.prettify()))] - + return [] - def fetch_song(self, source: Source, stop_at_level: int = 1) -> Song: r = self.connection.get(source.url) if r is None: return Song() - + soup = self.get_soup_from_response(r) data_container = soup.find("script", {"type": "application/ld+json"}) @@ -340,7 +337,7 @@ class Bandcamp(Page): song = Song( title=data["name"].strip(), - source_list=[Source(self.SOURCE_TYPE, data.get("mainEntityOfPage", data["@id"]), adio_url=mp3_url)], + source_list=[Source(self.SOURCE_TYPE, data.get("mainEntityOfPage", data["@id"]), audio_url=mp3_url)], album_list=[Album( title=album_data["name"].strip(), date=ID3Timestamp.strptime(data["datePublished"], "%d %b %Y %H:%M:%S %Z"), @@ -348,7 +345,7 @@ class Bandcamp(Page): )], main_artist_list=[Artist( name=artist_data["name"].strip(), - source_list=[Source(self.SOURCE_TYPE, _parse_artist_url(artist_data["@id"]))] + source_list=[Source(self.SOURCE_TYPE, _parse_artist_url(artist_data["@id"]))] )], lyrics_list=self._fetch_lyrics(soup=soup) ) @@ -359,5 +356,6 @@ class Bandcamp(Page): def download_song_to_target(self, source: Source, target: Target, desc: str = None) -> DownloadResult: if source.audio_url is None: + print(source) return DownloadResult(error_message="Couldn't find download link.") return self.connection.stream_into(url=source.audio_url, target=target, description=desc) diff --git a/src/music_kraken/pages/musify.py b/src/music_kraken/pages/musify.py index 44b61d9..371633a 100644 --- a/src/music_kraken/pages/musify.py +++ b/src/music_kraken/pages/musify.py @@ -628,7 +628,7 @@ class Musify(Page): source_list.append(Source( self.SOURCE_TYPE, url=current_url, - adio_url=self.HOST + download_href + audio_url=self.HOST + download_href )) return Song(