Compare commits

..

No commits in common. "e53e50b5d23d46d3f55723ff09487dae9c39687f" and "ed2eeabd6a964f7ede8eb4f93562267ed228a756" have entirely different histories.

4 changed files with 72 additions and 58 deletions

View File

@ -5,7 +5,21 @@ from ..__meta__ import DESCRIPTION, PROGRAMM
from ..download import Downloader from ..download import Downloader
from ..utils import BColors from ..utils import BColors
from ..utils.string_processing import unify from ..utils.string_processing import unify
from .utils import HELP_MESSAGE, ask_for_bool, ask_for_create 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: class DevelopmentCli:
@ -53,30 +67,11 @@ class DevelopmentCli:
return genre return genre
def help_screen(self) -> None:
print(HELP_MESSAGE)
def shell(self) -> None:
print(f"Welcome to the {PROGRAMM} shell!")
print(f"Type '{BColors.OKBLUE}help{BColors.ENDC}' for a list of commands.")
print("")
while True:
i = input("> ")
if i == "help":
self.help_screen()
elif i == "genre":
self.genre
elif i == "exit":
break
else:
print("Unknown command. Type 'help' for a list of commands.")
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
prog=PROGRAMM, prog=PROGRAMM,
description=DESCRIPTION, description=DESCRIPTION,
epilog='This is just a development cli. The real frontend is coming soon.' epilog='This is just a development cli. The real frontend is coming soon.'
) )
parser.add_argument('--genre', '-g', action='store_const', required=False, help="choose a genre to download from") parser.add_argument('--genre', '-g', action='store_const')
args = parser.parse_args() args = parser.parse_args()

View File

@ -0,0 +1,53 @@
import re
from pathlib import Path
from typing import Dict, Generator, List, Set, Type, Union
from ..download import Downloader, Page, components
from ..utils.config import main_settings
from .utils import ask_for_bool, cli_function
class GenreIO(components.HumanIO):
@staticmethod
def ask_to_create(option: components.Option) -> bool:
output()
return ask_for_bool(f"create the genre {BColors.OKBLUE.value}{option.value}{BColors.ENDC.value}")
@staticmethod
def not_found(key: str) -> None:
output(f"\ngenre {BColors.BOLD.value}{key}{BColors.ENDC.value} not found\n", color=BColors.FAIL)
def _genre_generator() -> Generator[str, None, None]:
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
def get_genre() -> str:
select_genre = components.Select(
human_io=GenreIO,
can_create_options=True,
data=_genre_generator(),
)
genre: Optional[components.Option[str]] = None
while genre is None:
print(select_genre.pprint())
print()
genre = select_genre.choose(input("> "))
return genre.value

View File

@ -40,44 +40,10 @@ def print_cute_message():
print(message) print(message)
def highlight_placeholder(text: str) -> str: AGREE_INPUTS = {"y", "yes", "ok"}
return text.replace("<", f"{BColors.BOLD}<").replace(">", f">{BColors.ENDC}")
HELP_MESSAGE = highlight_placeholder(f"""{BColors.HEADER}To search:{BColors.ENDC}
> s: <query/url>
> s: https://musify.club/release/some-random-release-183028492
> s: #a <artist> #r <release> #t <track>
If you found the same object twice from different sources you can merge those objects.
Then it will use those sources. To do so, use the {BColors.BOLD}m{BColors.ENDC} command.
{BColors.HEADER}To download:{BColors.ENDC}
> d: <id/url>
> dm: 0, 3, 4 # merge all objects into one and download this object
> d: 1
> d: https://musify.club/release/some-random-release-183028492
{BColors.HEADER}To inspect an object:{BColors.ENDC}
If you inspect an object, you see its adjacent object. This means for example the releases of an artist, or the tracks of a release.
You can also merge objects with the {BColors.BOLD}m{BColors.ENDC} command here.
> g: <id/url>
> gm: 0, 3, 4 # merge all objects into one and inspect this object
> g: 1
> g: https://musify.club/release/some-random-release-183028492""")
class COMMANDS:
AGREE = {"y", "yes", "ok"}
DISAGREE = {"n", "no"}
EXIT = {"exit"}
HELP = {"help", "h"}
def ask_for_bool(msg: str) -> bool: 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 COMMANDS.AGREE return i in AGREE_INPUTS
def ask_for_create(name: str, value: str) -> bool: def ask_for_create(name: str, value: str) -> bool:

View File

@ -1,7 +1,7 @@
from enum import Enum from enum import Enum
class BColors: class BColors(Enum):
# https://stackoverflow.com/a/287944 # https://stackoverflow.com/a/287944
HEADER = "\033[95m" HEADER = "\033[95m"
OKBLUE = "\033[94m" OKBLUE = "\033[94m"