added better default targets
This commit is contained in:
parent
376bbf2fa2
commit
c05199d928
@ -3,6 +3,8 @@ from typing import Optional, Union, Type, Dict, List
|
|||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
import requests
|
import requests
|
||||||
import logging
|
import logging
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from copy import copy
|
||||||
|
|
||||||
from ..utils import shared
|
from ..utils import shared
|
||||||
from ..objects import (
|
from ..objects import (
|
||||||
@ -19,9 +21,34 @@ from ..objects import (
|
|||||||
Label
|
Label
|
||||||
)
|
)
|
||||||
from ..tagging import write_metadata_to_target
|
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")
|
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:
|
class Page:
|
||||||
"""
|
"""
|
||||||
@ -283,56 +310,80 @@ class Page:
|
|||||||
cls._clean_collection(song.main_artist_collection, collections)
|
cls._clean_collection(song.main_artist_collection, collections)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def download(cls, music_object: Union[Song, Album, Artist, Label], download_features: bool = True):
|
def download(
|
||||||
print("downloading")
|
cls,
|
||||||
print(music_object)
|
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:
|
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:
|
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:
|
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:
|
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
|
@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)
|
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, default_target=default_target)
|
||||||
|
|
||||||
for album in label.album_collection:
|
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
|
@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)
|
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, default_target=default_target)
|
||||||
|
|
||||||
if download_features:
|
if download_features:
|
||||||
for song in artist.feature_album.song_collection:
|
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
|
@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)
|
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, default_target=default_target)
|
||||||
|
|
||||||
@classmethod
|
@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)
|
cls.fetch_details(song)
|
||||||
|
|
||||||
if song.target_collection.empty:
|
if song.target_collection.empty:
|
||||||
if create_target_on_demand and not song.main_artist_collection.empty and not song.album_collection.empty:
|
if create_target_on_demand and not song.main_artist_collection.empty and not song.album_collection.empty:
|
||||||
song.target_collection.append(
|
song.target_collection.append(default_target.target)
|
||||||
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:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -10,8 +10,7 @@ from pathlib import Path
|
|||||||
import random
|
import random
|
||||||
|
|
||||||
from ..utils.shared import (
|
from ..utils.shared import (
|
||||||
ENCYCLOPAEDIA_METALLUM_LOGGER as LOGGER,
|
ENCYCLOPAEDIA_METALLUM_LOGGER as LOGGER
|
||||||
TEMP_FOLDER
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from .abstract import Page
|
from .abstract import Page
|
||||||
@ -864,7 +863,7 @@ class Musify(Page):
|
|||||||
:param source:
|
:param source:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
album = Album(title="Hi :)")
|
album = Album(title="Hi :)", source_list=[source])
|
||||||
|
|
||||||
url = cls.parse_url(source.url)
|
url = cls.parse_url(source.url)
|
||||||
|
|
||||||
@ -881,6 +880,14 @@ class Musify(Page):
|
|||||||
card_soup: BeautifulSoup
|
card_soup: BeautifulSoup
|
||||||
for card_soup in cards_soup.find_all("div", {"class": "playlist__item"}):
|
for card_soup in cards_soup.find_all("div", {"class": "playlist__item"}):
|
||||||
album.song_collection.append(cls.parse_song_card(card_soup))
|
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()
|
album.update_tracksort()
|
||||||
|
|
||||||
return album
|
return album
|
||||||
|
@ -4,18 +4,13 @@ import tempfile
|
|||||||
import os
|
import os
|
||||||
import configparser
|
import configparser
|
||||||
from sys import platform as current_os
|
from sys import platform as current_os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
TEMP_FOLDER = "music-downloader"
|
|
||||||
LOG_FILE = "download_logs.log"
|
LOG_FILE = "download_logs.log"
|
||||||
TEMP_DATABASE_FILE = "metadata.db"
|
TEMP_DATABASE_FILE = "metadata.db"
|
||||||
DATABASE_STRUCTURE_FILE = "database_structure.sql"
|
TEMP_DIR = Path(tempfile.gettempdir(), "music-downloader")
|
||||||
DATABASE_STRUCTURE_FALLBACK = "https://raw.githubusercontent.com/HeIIow2/music-downloader/master/assets/database_structure.sql"
|
TEMP_DIR.mkdir(exist_ok=True)
|
||||||
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)
|
|
||||||
|
|
||||||
# configure logger default
|
# configure logger default
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
@ -33,18 +28,17 @@ INIT_PATH_LOGGER = logging.getLogger("init_path")
|
|||||||
DATABASE_LOGGER = logging.getLogger("database")
|
DATABASE_LOGGER = logging.getLogger("database")
|
||||||
METADATA_DOWNLOAD_LOGGER = logging.getLogger("metadata")
|
METADATA_DOWNLOAD_LOGGER = logging.getLogger("metadata")
|
||||||
URL_DOWNLOAD_LOGGER = logging.getLogger("AudioSource")
|
URL_DOWNLOAD_LOGGER = logging.getLogger("AudioSource")
|
||||||
|
TAGGING_LOGGER = logging.getLogger("tagging")
|
||||||
YOUTUBE_LOGGER = logging.getLogger("Youtube")
|
YOUTUBE_LOGGER = logging.getLogger("Youtube")
|
||||||
MUSIFY_LOGGER = logging.getLogger("Musify")
|
MUSIFY_LOGGER = logging.getLogger("Musify")
|
||||||
PATH_LOGGER = logging.getLogger("create-paths")
|
PATH_LOGGER = logging.getLogger("create-paths")
|
||||||
DOWNLOAD_LOGGER = logging.getLogger("download")
|
DOWNLOAD_LOGGER = logging.getLogger("download")
|
||||||
LYRICS_LOGGER = logging.getLogger("lyrics")
|
LYRICS_LOGGER = logging.getLogger("lyrics")
|
||||||
GENIUS_LOGGER = logging.getLogger("genius")
|
GENIUS_LOGGER = logging.getLogger("genius")
|
||||||
TAGGING_LOGGER = logging.getLogger("tagging")
|
|
||||||
|
|
||||||
ENCYCLOPAEDIA_METALLUM_LOGGER = logging.getLogger("ma")
|
ENCYCLOPAEDIA_METALLUM_LOGGER = logging.getLogger("ma")
|
||||||
|
|
||||||
NOT_A_GENRE = ".", "..", "misc_scripts", "Music", "script", ".git", ".idea"
|
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":
|
if current_os == "linux":
|
||||||
# XDG_USER_DIRS_FILE reference: https://freedesktop.org/wiki/Software/xdg-user-dirs/
|
# 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)
|
config.read_string(data)
|
||||||
xdg_config = config['XDG_USER_DIRS']
|
xdg_config = config['XDG_USER_DIRS']
|
||||||
MUSIC_DIR = os.path.expandvars(xdg_config['xdg_music_dir'].strip('"'))
|
MUSIC_DIR = os.path.expandvars(xdg_config['xdg_music_dir'].strip('"'))
|
||||||
|
|
||||||
except (FileNotFoundError, KeyError) as E:
|
except (FileNotFoundError, KeyError) as E:
|
||||||
logger.warning(f'''
|
logger.warning(
|
||||||
Missing file or No entry found for "xdg_music_dir" in: \'{XDG_USER_DIRS_FILE}\'.
|
f"Missing file or No entry found for \"xdg_music_dir\" in: \"{XDG_USER_DIRS_FILE}\".\n" \
|
||||||
Will fallback on default '$HOME/Music'.
|
f"Will fallback on default \"$HOME/Music\"."
|
||||||
----
|
)
|
||||||
''')
|
|
||||||
TOR = False
|
TOR = False
|
||||||
proxies = {
|
proxies = {
|
||||||
'http': 'socks5h://127.0.0.1:9150',
|
'http': 'socks5h://127.0.0.1:9150',
|
||||||
'https': 'socks5h://127.0.0.1:9150'
|
'https': 'socks5h://127.0.0.1:9150'
|
||||||
} if TOR else {}
|
} 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",
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user