diff --git a/music_kraken/cli/main_downloader.py b/music_kraken/cli/main_downloader.py index 6b834ef..97ac247 100644 --- a/music_kraken/cli/main_downloader.py +++ b/music_kraken/cli/main_downloader.py @@ -91,7 +91,9 @@ class CliDownloader: self.page_dict = dict() print() + print(self.current_results.pprint()) + """ page_count = 0 for option in self.current_results.formatted_generator(): if isinstance(option, ResultOption): @@ -106,10 +108,13 @@ class CliDownloader: self.page_dict[option.__name__] = option page_count += 1 + """ print() - def set_current_options(self, current_options: Results): + def set_current_options(self, current_options: Generator[DatabaseObject, None, None]): + current_options = components.DataObjectSelect(current_options) + if main_settings["result_history"]: self._result_history.append(current_options) diff --git a/music_kraken/download/__init__.py b/music_kraken/download/__init__.py index 1a4aa6d..7484eef 100644 --- a/music_kraken/download/__init__.py +++ b/music_kraken/download/__init__.py @@ -117,21 +117,14 @@ class Downloader: def get_pages(self, *page_types: List[Type[Page]]) -> Generator[Page, None, None]: if len(page_types) == 0: - page_types = _registered_pages.keys() + page_types = self._registered_pages.keys() for page_type in page_types: yield from self._registered_pages[page_type] - def search(self, query: Query) -> SearchResults: - result = SearchResults() - + def search(self, query: Query) -> Generator[DataObject, None, None]: for page in self.get_pages(): - result.add( - page=type(page), - search_result=page.search(query=query) - ) - - return result + yield from page.search(query=query) def fetch_details(self, data_object: DataObject, stop_at_level: int = 1, **kwargs) -> DataObject: source: Source diff --git a/music_kraken/download/components.py b/music_kraken/download/components.py index ef07565..c3763e6 100644 --- a/music_kraken/download/components.py +++ b/music_kraken/download/components.py @@ -1,12 +1,16 @@ from __future__ import annotations import re +from collections import defaultdict from pathlib import Path from typing import Any, Callable, Dict, Generator, List, Optional +from ..objects import OuterProxy as DataObject from ..utils import BColors from ..utils.config import main_settings +from ..utils.enums import SourceType from ..utils.exception import MKComposeException +from ..utils.shared import ALPHABET from ..utils.string_processing import unify @@ -41,7 +45,10 @@ class Option: self._raw_keys = set(keys or []) self._raw_keys.add(self.text) - self._raw_keys.add(self.value) + try: + self._raw_keys.add(self.value) + except TypeError: + pass self._raw_keys.add(str(self.value)) self.keys = set(self.parse_key(key) for key in self._raw_keys) @@ -178,3 +185,54 @@ class GenreSelect(StringSelect): def __init__(self): super().__init__(sort=True, raw_options=(genre.name for genre in filter(self.is_valid_genre, main_settings["music_directory"].iterdir()))) + +class DataObjectSelect(Select): + def __init__(self, data_objects: Generator[DataObject]): + self._source_type_to_data_objects: Dict[SourceType, List[Option]] = defaultdict(list) + + self._data_object_index: int = 0 + self._source_type_index: int = 0 + + super().__init__() + + self.extend(data_objects) + + def option_from_data_object(self, data_object: DataObject) -> Option: + index = self._data_object_index + self._data_object_index += 1 + return Option( + value=data_object, + keys=[index, data_object.option_string, data_object.title_string], + text=f"{BColors.BOLD.value}{index: >2}{BColors.ENDC.value}: {data_object.option_string}", + ) + + def option_from_source_type(self, source_type: SourceType) -> Option: + index = ALPHABET[self._source_type_index % len(ALPHABET)] + self._source_type_index += 1 + + return Option( + value=self._source_type_to_data_objects[source_type], + keys=[index, source_type], + text=f"{BColors.HEADER.value}({index}) --------------------------------{source_type.name:{'-'}<{21}}--------------------{BColors.ENDC.value}", + ) + + def append(self, option: Union[Option, DataObject]): + if isinstance(option, DataObject): + data_object = option + option = self.option_from_data_object(data_object) + else: + data_object = option.value + + for source_type in data_object.source_collection.source_types(only_with_page=True): + if source_type not in self._source_type_to_data_objects: + st_option = self.option_from_source_type(source_type) + self._source_type_to_data_objects[source_type].append(st_option) + super().append(st_option) + + self._source_type_to_data_objects[source_type].append(option) + + super().append(option) + + def __iter__(self): + for options in self._source_type_to_data_objects.values(): + yield from options \ No newline at end of file diff --git a/music_kraken/utils/shared.py b/music_kraken/utils/shared.py index b75cf7f..52613af 100644 --- a/music_kraken/utils/shared.py +++ b/music_kraken/utils/shared.py @@ -1,11 +1,11 @@ -import random -from dotenv import load_dotenv -from pathlib import Path import os +import random +from pathlib import Path +from dotenv import load_dotenv -from .path_manager import LOCATIONS from .config import main_settings +from .path_manager import LOCATIONS if not load_dotenv(Path(__file__).parent.parent.parent / ".env"): load_dotenv(Path(__file__).parent.parent.parent / ".env.example") @@ -51,3 +51,6 @@ have fun :3""".strip() URL_PATTERN = r"https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+" INT_PATTERN = r"^\d*$" FLOAT_PATTERN = r"^[\d|\,|\.]*$" + + +ALPHABET = "abcdefghijklmnopqrstuvwxyz"