2022-11-24 13:34:36 +00:00
|
|
|
from typing import List
|
2022-11-23 07:24:05 +00:00
|
|
|
import musicbrainzngs
|
|
|
|
import logging
|
|
|
|
import os
|
|
|
|
|
2022-11-24 13:34:36 +00:00
|
|
|
from . import (
|
|
|
|
database,
|
2022-11-24 13:56:51 +00:00
|
|
|
audio_source,
|
2022-11-24 14:42:50 +00:00
|
|
|
target,
|
|
|
|
metadata
|
2022-11-24 13:34:36 +00:00
|
|
|
)
|
|
|
|
|
2022-11-23 07:24:05 +00:00
|
|
|
from .utils.shared import (
|
|
|
|
MUSIC_DIR,
|
|
|
|
NOT_A_GENRE
|
|
|
|
)
|
2022-11-16 09:37:41 +00:00
|
|
|
from .metadata import (
|
|
|
|
metadata_search,
|
|
|
|
metadata_fetch
|
|
|
|
)
|
2022-11-24 13:56:51 +00:00
|
|
|
|
2022-11-16 09:37:41 +00:00
|
|
|
from .lyrics import lyrics
|
|
|
|
|
2022-11-22 13:53:29 +00:00
|
|
|
logging.getLogger("musicbrainzngs").setLevel(logging.WARNING)
|
|
|
|
musicbrainzngs.set_useragent("metadata receiver", "0.1", "https://github.com/HeIIow2/music-downloader")
|
2022-11-15 12:04:44 +00:00
|
|
|
|
2022-11-24 13:34:36 +00:00
|
|
|
# define the most important values and function for import in the __init__ file
|
|
|
|
Song = database.song.Song
|
2022-11-24 14:42:50 +00:00
|
|
|
MetadataSearch = metadata.metadata_search.Search
|
2022-11-24 13:34:36 +00:00
|
|
|
|
|
|
|
cache = database.cache
|
|
|
|
|
2022-11-24 14:42:50 +00:00
|
|
|
def fetch_metadata(type: str, id_: str):
|
|
|
|
metadata_downloader = metadata_fetch.MetadataDownloader()
|
|
|
|
metadata_downloader.download({'type': type, 'id': id_})
|
|
|
|
|
|
|
|
def fetch_metadata_from_search(search_instace: MetadataSearch):
|
|
|
|
current_option = search_instace.current_option
|
|
|
|
fetch_metadata(type=current_option.type, id_= current_option.id)
|
|
|
|
|
2022-11-24 13:56:51 +00:00
|
|
|
def set_targets(genre: str):
|
|
|
|
target.set_target.UrlPath(genre=genre)
|
|
|
|
|
2022-11-24 13:34:36 +00:00
|
|
|
def fetch_sources(songs: List[Song], skip_existing_files: bool = True):
|
|
|
|
audio_source.fetch_sources(songs=songs, skip_existing_files=skip_existing_files)
|
|
|
|
|
|
|
|
def fetch_audios(songs: List[Song], override_existing: bool = False):
|
|
|
|
audio_source.fetch_audios(songs=songs, override_existing=override_existing)
|
|
|
|
|
2022-11-22 13:25:01 +00:00
|
|
|
|
2022-11-24 13:56:51 +00:00
|
|
|
|
2022-11-15 12:04:44 +00:00
|
|
|
def get_existing_genre():
|
|
|
|
valid_directories = []
|
|
|
|
for elem in os.listdir(MUSIC_DIR):
|
|
|
|
if elem not in NOT_A_GENRE:
|
|
|
|
valid_directories.append(elem)
|
|
|
|
|
|
|
|
return valid_directories
|
|
|
|
|
2022-11-23 18:15:55 +00:00
|
|
|
|
2022-11-23 07:10:22 +00:00
|
|
|
def help_search_metadata():
|
|
|
|
msg = """
|
2022-11-23 22:44:25 +00:00
|
|
|
- - - Available Options - - -
|
2022-11-22 08:24:25 +00:00
|
|
|
.. - Previous Options
|
|
|
|
(query_string) - Search for songs, albums, bands...
|
|
|
|
(int) - Select an item from the search results
|
|
|
|
d - Start the download
|
|
|
|
h - Help
|
|
|
|
q - Quit / Exit
|
2022-11-23 22:44:25 +00:00
|
|
|
|
|
|
|
- - - How the Query works (examples) - - -
|
|
|
|
> #a <any artist>
|
|
|
|
searches for the artist <any artist>
|
|
|
|
|
|
|
|
> #a <any artist> #r <any releas>
|
|
|
|
searches for the release (album) <any release> by the artist <any artist>
|
|
|
|
|
|
|
|
> #r <any release> Me #t <any track>
|
|
|
|
searches for the track <any track> from the release <any relaese>
|
2022-11-23 07:10:22 +00:00
|
|
|
"""
|
|
|
|
print(msg)
|
2022-11-22 08:24:25 +00:00
|
|
|
|
2022-11-23 07:10:22 +00:00
|
|
|
|
2022-11-23 07:24:05 +00:00
|
|
|
def execute_input(_input: str, search: metadata_search.Search) -> bool:
|
|
|
|
"""
|
|
|
|
:returns: True if it should break out of the loop else False
|
|
|
|
"""
|
|
|
|
_input = _input.strip().lower()
|
|
|
|
if _input in ("d", "ok", "dl", "download"):
|
|
|
|
return True
|
|
|
|
if _input in ("q", "quit", "exit"):
|
|
|
|
exit()
|
|
|
|
if _input in ("h", "help"):
|
|
|
|
help_search_metadata()
|
|
|
|
return False
|
|
|
|
if _input.isdigit():
|
|
|
|
print()
|
|
|
|
print(search.choose(int(_input)))
|
|
|
|
return False
|
2022-11-23 18:15:55 +00:00
|
|
|
if _input == "..":
|
2022-11-23 07:24:05 +00:00
|
|
|
print()
|
|
|
|
print(search.get_previous_options())
|
|
|
|
return False
|
2022-11-23 18:15:55 +00:00
|
|
|
|
2022-11-23 07:24:05 +00:00
|
|
|
print()
|
|
|
|
print(search.search_from_query(_input))
|
2022-11-23 07:10:22 +00:00
|
|
|
|
2022-11-23 18:15:55 +00:00
|
|
|
|
2022-11-23 07:24:05 +00:00
|
|
|
def search_for_metadata():
|
2022-11-24 14:42:50 +00:00
|
|
|
search = MetadataSearch()
|
2022-11-23 07:10:22 +00:00
|
|
|
|
|
|
|
while True:
|
2022-11-23 16:12:40 +00:00
|
|
|
_input = input("\"help\" for an overview of commands: ")
|
2022-11-23 07:24:05 +00:00
|
|
|
if execute_input(_input=_input, search=search):
|
|
|
|
break
|
2022-11-22 08:24:25 +00:00
|
|
|
|
2022-11-23 07:24:05 +00:00
|
|
|
print(f"downloading: {search.current_option}")
|
2022-11-15 12:04:44 +00:00
|
|
|
return search.current_option
|
|
|
|
|
|
|
|
|
|
|
|
def get_genre():
|
|
|
|
existing_genres = get_existing_genre()
|
|
|
|
print("printing available genres:")
|
|
|
|
for i, genre_option in enumerate(existing_genres):
|
|
|
|
print(f"{i}: {genre_option}")
|
|
|
|
|
|
|
|
genre = input("Input the ID for an existing genre or text for a new one: ")
|
|
|
|
|
|
|
|
if genre.isdigit():
|
|
|
|
genre_id = int(genre)
|
|
|
|
if genre_id >= len(existing_genres):
|
|
|
|
logging.warning("An invalid genre id has been given")
|
|
|
|
return get_genre()
|
|
|
|
return existing_genres[genre_id]
|
|
|
|
|
|
|
|
return genre
|
|
|
|
|
|
|
|
|
2022-11-23 07:24:05 +00:00
|
|
|
def cli(start_at: int = 0, only_lyrics: bool = False):
|
2022-11-15 12:04:44 +00:00
|
|
|
if start_at <= 2 and not only_lyrics:
|
|
|
|
genre = get_genre()
|
|
|
|
logging.info(f"{genre} has been set as genre.")
|
|
|
|
|
|
|
|
if start_at <= 0:
|
|
|
|
search = search_for_metadata()
|
|
|
|
logging.info("Starting Downloading of metadata")
|
2022-11-24 14:42:50 +00:00
|
|
|
fetch_metadata_from_search(search)
|
|
|
|
|
2022-11-15 12:04:44 +00:00
|
|
|
|
|
|
|
if start_at <= 1 and not only_lyrics:
|
|
|
|
logging.info("creating Paths")
|
2022-11-24 13:56:51 +00:00
|
|
|
set_targets(genre=genre)
|
2022-11-15 12:04:44 +00:00
|
|
|
|
|
|
|
if start_at <= 2 and not only_lyrics:
|
|
|
|
logging.info("Fetching Download Links")
|
2022-11-24 13:34:36 +00:00
|
|
|
fetch_sources(cache.get_tracks_without_src())
|
2022-11-15 12:04:44 +00:00
|
|
|
|
|
|
|
if start_at <= 3 and not only_lyrics:
|
|
|
|
logging.info("starting to download the mp3's")
|
2022-11-24 13:34:36 +00:00
|
|
|
fetch_audios(cache.get_tracks_to_download())
|
2022-11-15 12:04:44 +00:00
|
|
|
|
|
|
|
if start_at <= 4:
|
|
|
|
logging.info("starting to fetch the lyrics")
|
2022-11-16 09:37:41 +00:00
|
|
|
lyrics.fetch_lyrics()
|
2022-11-22 08:24:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
def gtk_gui():
|
2022-11-22 10:13:05 +00:00
|
|
|
# please maximaly a minimal gui, the fully fleshed out gui should be made externally
|
|
|
|
# to avoid ending up with a huge monolyth
|
2022-11-22 08:24:25 +00:00
|
|
|
pass
|