added better default targets

This commit is contained in:
Hellow2 2023-04-03 10:38:12 +02:00
parent 376bbf2fa2
commit c05199d928
3 changed files with 113 additions and 44 deletions

View File

@ -3,6 +3,8 @@ from typing import Optional, Union, Type, Dict, List
from bs4 import BeautifulSoup
import requests
import logging
from dataclasses import dataclass
from copy import copy
from ..utils import shared
from ..objects import (
@ -19,9 +21,34 @@ from ..objects import (
Label
)
from ..tagging import write_metadata_to_target
from ..utils.shared import DOWNLOAD_PATH, DOWNLOAD_FILE, DEFAULT_VALUES
LOGGER = logging.getLogger("this shouldn't be used")
@dataclass
class DefaultTarget:
genre: str = DEFAULT_VALUES["genre"]
label: str = DEFAULT_VALUES["label"]
artist: str = DEFAULT_VALUES["artist"]
album: str = DEFAULT_VALUES["album"]
song: str = DEFAULT_VALUES["song"]
def __setattr__(self, __name: str, __value: str) -> None:
if __name in DEFAULT_VALUES:
if self.__getattribute__(__name) == DEFAULT_VALUES[__name]:
super().__setattr__(__name, __value)
return
super().__setattr__(__name, __value)
@property
def target(self) -> Target:
return Target(
relative_to_music_dir=True,
path=DOWNLOAD_PATH.format(genre=self.genre, label=self.label, artist=self.artist, album=self.album, song=self.song),
file=DOWNLOAD_FILE.format(genre=self.genre, label=self.label, artist=self.artist, album=self.album, song=self.song)
)
class Page:
"""
@ -283,56 +310,80 @@ class Page:
cls._clean_collection(song.main_artist_collection, collections)
@classmethod
def download(cls, music_object: Union[Song, Album, Artist, Label], download_features: bool = True):
print("downloading")
print(music_object)
def download(
cls,
music_object: Union[Song, Album, Artist, Label],
download_features: bool = True,
default_target: DefaultTarget = None
):
if default_target is None:
default_target = DefaultTarget()
if type(music_object) is Song:
return cls.download_song(music_object)
return cls.download_song(music_object, default_target)
if type(music_object) is Album:
return cls.download_album(music_object)
return cls.download_album(music_object, default_target)
if type(music_object) is Artist:
return cls.download_artist(music_object, download_features=download_features)
return cls.download_artist(music_object, default_target)
if type(music_object) is Label:
return cls.download_label(music_object, download_features=download_features)
return cls.download_label(music_object, download_features=download_features, default_target=default_target)
@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, default_target: DefaultTarget = None):
if default_target is None:
default_target = DefaultTarget()
else:
default_target = copy(default_target)
default_target.label = label.name
cls.fetch_details(label)
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, default_target=default_target)
for album in label.album_collection:
cls.download_album(album, override_existing=override_existing)
cls.download_album(album, override_existing=override_existing, default_target=default_target)
@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, default_target: DefaultTarget = None):
if default_target is None:
default_target = DefaultTarget()
else:
default_target = copy(default_target)
default_target.artist = artist.name
cls.fetch_details(artist)
for album in artist.main_album_collection:
cls.download_album(album, override_existing=override_existing)
cls.download_album(album, override_existing=override_existing, default_target=default_target)
if download_features:
for song in artist.feature_album.song_collection:
cls.download_song(song, override_existing=override_existing)
cls.download_song(song, override_existing=override_existing, default_target=default_target)
@classmethod
def download_album(cls, album: Album, override_existing: bool = False):
def download_album(cls, album: Album, override_existing: bool = False, default_target: DefaultTarget = None):
if default_target is None:
default_target = DefaultTarget()
else:
default_target = copy(default_target)
default_target.album = album.title
cls.fetch_details(album)
for song in album.song_collection:
cls.download_song(song, override_existing=override_existing)
cls.download_song(song, override_existing=override_existing, default_target=default_target)
@classmethod
def download_song(cls, song: Song, override_existing: bool = False, create_target_on_demand: bool = True):
def download_song(cls, song: Song, override_existing: bool = False, create_target_on_demand: bool = True, default_target: DefaultTarget = None):
if default_target is None:
default_target = DefaultTarget()
else:
default_target = copy(default_target)
default_target.song = song.title
cls.fetch_details(song)
if song.target_collection.empty:
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}"
)
)
song.target_collection.append(default_target.target)
else:
return

View File

@ -10,8 +10,7 @@ from pathlib import Path
import random
from ..utils.shared import (
ENCYCLOPAEDIA_METALLUM_LOGGER as LOGGER,
TEMP_FOLDER
ENCYCLOPAEDIA_METALLUM_LOGGER as LOGGER
)
from .abstract import Page
@ -864,7 +863,7 @@ class Musify(Page):
:param source:
:return:
"""
album = Album(title="Hi :)")
album = Album(title="Hi :)", source_list=[source])
url = cls.parse_url(source.url)
@ -881,6 +880,14 @@ class Musify(Page):
card_soup: BeautifulSoup
for card_soup in cards_soup.find_all("div", {"class": "playlist__item"}):
album.song_collection.append(cls.parse_song_card(card_soup))
if stop_at_level > 1:
song: Song
for song in album.song_collection:
sources = song.source_collection.get_sources_from_page(cls.SOURCE_TYPE)
for source in sources:
song.merge(cls._fetch_song_from_source(source=source))
album.update_tracksort()
return album

View File

@ -4,18 +4,13 @@ import tempfile
import os
import configparser
from sys import platform as current_os
from pathlib import Path
TEMP_FOLDER = "music-downloader"
LOG_FILE = "download_logs.log"
TEMP_DATABASE_FILE = "metadata.db"
DATABASE_STRUCTURE_FILE = "database_structure.sql"
DATABASE_STRUCTURE_FALLBACK = "https://raw.githubusercontent.com/HeIIow2/music-downloader/master/assets/database_structure.sql"
TEMP_DIR = os.path.join(tempfile.gettempdir(), TEMP_FOLDER)
if not os.path.exists(TEMP_DIR):
os.mkdir(TEMP_DIR)
TEMP_DATABASE_PATH = os.path.join(TEMP_DIR, TEMP_DATABASE_FILE)
TEMP_DIR = Path(tempfile.gettempdir(), "music-downloader")
TEMP_DIR.mkdir(exist_ok=True)
# configure logger default
logging.basicConfig(
@ -33,18 +28,17 @@ INIT_PATH_LOGGER = logging.getLogger("init_path")
DATABASE_LOGGER = logging.getLogger("database")
METADATA_DOWNLOAD_LOGGER = logging.getLogger("metadata")
URL_DOWNLOAD_LOGGER = logging.getLogger("AudioSource")
TAGGING_LOGGER = logging.getLogger("tagging")
YOUTUBE_LOGGER = logging.getLogger("Youtube")
MUSIFY_LOGGER = logging.getLogger("Musify")
PATH_LOGGER = logging.getLogger("create-paths")
DOWNLOAD_LOGGER = logging.getLogger("download")
LYRICS_LOGGER = logging.getLogger("lyrics")
GENIUS_LOGGER = logging.getLogger("genius")
TAGGING_LOGGER = logging.getLogger("tagging")
ENCYCLOPAEDIA_METALLUM_LOGGER = logging.getLogger("ma")
NOT_A_GENRE = ".", "..", "misc_scripts", "Music", "script", ".git", ".idea"
MUSIC_DIR = os.path.join(os.path.expanduser("~"), "Music")
MUSIC_DIR = Path(os.path.expanduser("~"), "Music")
if current_os == "linux":
# XDG_USER_DIRS_FILE reference: https://freedesktop.org/wiki/Software/xdg-user-dirs/
@ -58,17 +52,34 @@ if current_os == "linux":
config.read_string(data)
xdg_config = config['XDG_USER_DIRS']
MUSIC_DIR = os.path.expandvars(xdg_config['xdg_music_dir'].strip('"'))
except (FileNotFoundError, KeyError) as E:
logger.warning(f'''
Missing file or No entry found for "xdg_music_dir" in: \'{XDG_USER_DIRS_FILE}\'.
Will fallback on default '$HOME/Music'.
----
''')
logger.warning(
f"Missing file or No entry found for \"xdg_music_dir\" in: \"{XDG_USER_DIRS_FILE}\".\n" \
f"Will fallback on default \"$HOME/Music\"."
)
TOR = False
proxies = {
'http': 'socks5h://127.0.0.1:9150',
'https': 'socks5h://127.0.0.1:9150'
} if TOR else {}
# only the sources here will get downloaded, in the order the list is ordered
AUDIO_SOURCES = ["Musify", "Youtube"]
"""
available variables:
- genre
- label
- artist
- album
- song
"""
DOWNLOAD_PATH = "{genre}/{artist}/{album}"
DOWNLOAD_FILE = "{song}.mp3"
DEFAULT_VALUES = {
"genre": "Various Genre",
"label": "Various Labels",
"artist": "Various Artists",
"album": "Various Album",
"song": "Various Song",
}