From 71ec30995310d18cb4e6e1e0649e3a3f3b0c41b6 Mon Sep 17 00:00:00 2001 From: Lars Noack Date: Mon, 27 May 2024 14:13:18 +0200 Subject: [PATCH] feat: reworked the genre select --- music_kraken/cli/main_downloader.py | 19 ++++++++++++++---- music_kraken/download/components.py | 30 ++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/music_kraken/cli/main_downloader.py b/music_kraken/cli/main_downloader.py index ddd1ffc..d2c989a 100644 --- a/music_kraken/cli/main_downloader.py +++ b/music_kraken/cli/main_downloader.py @@ -27,17 +27,28 @@ PAGE_NAME_FILL = "-" MAX_PAGE_LEN = 21 +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 get_genre(): select_genre = components.GenreSelect() - select_genre._ask_for_creating_option = lambda key: ask_for_bool(f"Create the genre \"{key}\"") + select_genre.human_io = GenreIO genre: Optional[components.Option] = None while genre is None: - for genre in select_genre: - print(genre) + print(select_genre.pprint()) + print() - genre = select_genre.choose(input("Id or new genre: ")) + genre = select_genre.choose(input("> ")) return genre.value diff --git a/music_kraken/download/components.py b/music_kraken/download/components.py index f11d41c..ef07565 100644 --- a/music_kraken/download/components.py +++ b/music_kraken/download/components.py @@ -1,12 +1,25 @@ +from __future__ import annotations + import re from pathlib import Path from typing import Any, Callable, Dict, Generator, List, Optional +from ..utils import BColors from ..utils.config import main_settings from ..utils.exception import MKComposeException from ..utils.string_processing import unify +class HumanIO: + @staticmethod + def ask_to_create(option: Option) -> bool: + return True + + @staticmethod + def not_found(key: Any) -> None: + return None + + class Option: """ This could represent a data object, a string or a page. @@ -56,12 +69,12 @@ class Select: option_factory: Callable[[Any], Option] = None, raw_options: List[Any] = None, parse_option_key: Callable[[Any], Any] = lambda x: x, - ask_for_creating_option: Callable[[Option], bool] = lambda x: True, + human_io: HumanIO = HumanIO, sort: bool = False, **kwargs ): self._parse_option_key: Callable[[Any], Any] = parse_option_key - self._ask_for_creating_option: Callable[[Option], bool] = ask_for_creating_option + self.human_io: HumanIO = human_io self._key_to_option: Dict[Any, Option] = dict() self._options: List[Option] = [] @@ -117,12 +130,19 @@ class Select: def choose(self, key: Any) -> Optional[Option]: if key not in self: - if self.can_create_options and self._ask_for_creating_option(key): - return self.create_option(key) + if self.can_create_options: + c = self.create_option(key) + if self.human_io.ask_to_create(c): + return c + + self.human_io.not_found(key) return None return self[key] + def pprint(self) -> str: + return "\n".join(str(option) for option in self) + class StringSelect(Select): @@ -134,7 +154,7 @@ class StringSelect(Select): super().__init__(**kwargs) def next_option(self, value: Any) -> Optional[Option]: - o = Option(value=value, keys=[self._current_index], text=f"{self._current_index:0>2}: {value}") + o = Option(value=value, keys=[self._current_index], text=f"{BColors.BOLD.value}{self._current_index: >2}{BColors.ENDC.value}: {value}") self._current_index += 1 return o