Compare commits
2 Commits
097211b3cd
...
ed2eeabd6a
Author | SHA1 | Date | |
---|---|---|---|
ed2eeabd6a | |||
b236291378 |
3
music_kraken/__meta__.py
Normal file
3
music_kraken/__meta__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
PROGRAMM: str = "music-kraken"
|
||||||
|
DESCRIPTION: str = """This program will first get the metadata of various songs from metadata providers like musicbrainz, and then search for download links on pages like bandcamp.
|
||||||
|
Then it will download the song and edit the metadata accordingly."""
|
@ -1,5 +0,0 @@
|
|||||||
from .informations import print_paths
|
|
||||||
from .main_downloader import download
|
|
||||||
from .options.settings import settings
|
|
||||||
from .options.frontend import set_frontend
|
|
||||||
|
|
77
music_kraken/development_cli/__init__.py
Normal file
77
music_kraken/development_cli/__init__.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import argparse
|
||||||
|
from functools import cached_property
|
||||||
|
|
||||||
|
from ..__meta__ import DESCRIPTION, PROGRAMM
|
||||||
|
from ..download import Downloader
|
||||||
|
from ..utils import BColors
|
||||||
|
from ..utils.string_processing import unify
|
||||||
|
from .utils import ask_for_bool, ask_for_create
|
||||||
|
|
||||||
|
|
||||||
|
class Selection:
|
||||||
|
def __init__(self, options: list):
|
||||||
|
self.options = options
|
||||||
|
|
||||||
|
def pprint(self):
|
||||||
|
return "\n".join(f"{i}: {option}" for i, option in enumerate(self.options))
|
||||||
|
|
||||||
|
def choose(self, input_: str):
|
||||||
|
try:
|
||||||
|
return self.options[int(input_)]
|
||||||
|
except (ValueError, IndexError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class DevelopmentCli:
|
||||||
|
def __init__(self, args: argparse.Namespace):
|
||||||
|
self.args = args
|
||||||
|
|
||||||
|
if args.genre:
|
||||||
|
self.genre = args.genre
|
||||||
|
|
||||||
|
self.downloader: Downloader = Downloader()
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def genre(self) -> str:
|
||||||
|
"""This is a cached property, which means if it isn't set in the constructor or before it is accessed,
|
||||||
|
the program will be thrown in a shell
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: the genre that should be used
|
||||||
|
"""
|
||||||
|
option_string = f"{BColors.HEADER}Genres{BColors.ENDC}"
|
||||||
|
genre_map = {}
|
||||||
|
|
||||||
|
_string_list = []
|
||||||
|
for i, genre in enumerate(self.downloader.get_existing_genres()):
|
||||||
|
option_string += f"\n{BColors.BOLD}{i}{BColors.ENDC}: {genre}"
|
||||||
|
|
||||||
|
genre_map[str(i)] = genre
|
||||||
|
genre_map[unify(genre)] = genre
|
||||||
|
|
||||||
|
genre = None
|
||||||
|
while genre is None:
|
||||||
|
print(option_string)
|
||||||
|
print()
|
||||||
|
|
||||||
|
i = input("> ")
|
||||||
|
u = unify(i)
|
||||||
|
if u in genre_map:
|
||||||
|
genre = genre_map[u]
|
||||||
|
break
|
||||||
|
|
||||||
|
if ask_for_create("genre", i):
|
||||||
|
genre = i
|
||||||
|
break
|
||||||
|
|
||||||
|
return genre
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog=PROGRAMM,
|
||||||
|
description=DESCRIPTION,
|
||||||
|
epilog='This is just a development cli. The real frontend is coming soon.'
|
||||||
|
)
|
||||||
|
parser.add_argument('--genre', '-g', action='store_const')
|
||||||
|
args = parser.parse_args()
|
@ -45,3 +45,7 @@ def ask_for_bool(msg: str) -> bool:
|
|||||||
i = input(f"{msg} ({BColors.OKGREEN.value}Y{BColors.ENDC.value}/{BColors.FAIL.value}N{BColors.ENDC.value})? ").lower()
|
i = input(f"{msg} ({BColors.OKGREEN.value}Y{BColors.ENDC.value}/{BColors.FAIL.value}N{BColors.ENDC.value})? ").lower()
|
||||||
return i in AGREE_INPUTS
|
return i in AGREE_INPUTS
|
||||||
|
|
||||||
|
|
||||||
|
def ask_for_create(name: str, value: str) -> bool:
|
||||||
|
return ask_for_bool(f"Do you want to create the {name} {BColors.OKBLUE}{value}{BColors.ENDC}?")
|
||||||
|
|
@ -415,6 +415,31 @@ class Downloader:
|
|||||||
|
|
||||||
return source.page.fetch_object_from_source(source=source, **kwargs)
|
return source.page.fetch_object_from_source(source=source, **kwargs)
|
||||||
|
|
||||||
|
# misc function
|
||||||
|
|
||||||
|
def get_existing_genres(self) -> Generator[str, None, None]:
|
||||||
|
"""Yields every existing genre, for the user to select from.
|
||||||
|
|
||||||
|
Yields:
|
||||||
|
Generator[str, None, None]: a generator that yields every existing genre.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def is_valid_genre(genre: Path) -> bool:
|
||||||
|
"""
|
||||||
|
gets the name of all subdirectories of shared.MUSIC_DIR,
|
||||||
|
but filters out all directories, where the name matches with any Patern
|
||||||
|
from shared.NOT_A_GENRE_REGEX.
|
||||||
|
"""
|
||||||
|
if not genre.is_dir():
|
||||||
|
return False
|
||||||
|
|
||||||
|
if any(re.match(regex_pattern, genre.name) for regex_pattern in main_settings["not_a_genre_regex"]):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
for genre in filter(is_valid_genre, main_settings["music_directory"].iterdir()):
|
||||||
|
yield genre.name
|
||||||
|
|
||||||
class Page:
|
class Page:
|
||||||
REGISTER = True
|
REGISTER = True
|
||||||
|
Loading…
Reference in New Issue
Block a user