cleaned up download
This commit is contained in:
parent
37854e30e0
commit
bdf05adcb1
@ -72,7 +72,7 @@ def cli():
|
|||||||
print("The given url couldn't be downloaded")
|
print("The given url couldn't be downloaded")
|
||||||
return
|
return
|
||||||
|
|
||||||
page = search.get_page_from_query(parsed)
|
page = search._get_page_from_query(parsed)
|
||||||
if page is not None:
|
if page is not None:
|
||||||
search.choose_page(page)
|
search.choose_page(page)
|
||||||
return
|
return
|
||||||
|
100
src/music_kraken/pages/download_center/multiple_options.py
Normal file
100
src/music_kraken/pages/download_center/multiple_options.py
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
from collections import defaultdict
|
||||||
|
from typing import Tuple, List, Dict, Type
|
||||||
|
|
||||||
|
from . import page_attributes
|
||||||
|
from ..abstract import Page
|
||||||
|
from ...objects import Options, DatabaseObject, Source
|
||||||
|
|
||||||
|
|
||||||
|
class MultiPageOptions:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
max_displayed_options: int = 10,
|
||||||
|
option_digits: int = 3,
|
||||||
|
derived_from: DatabaseObject = None
|
||||||
|
) -> None:
|
||||||
|
self.max_displayed_options = max_displayed_options
|
||||||
|
self.option_digits: int = option_digits
|
||||||
|
|
||||||
|
self._length = 0
|
||||||
|
self._current_option_dict: Dict[Type[Page], Options] = defaultdict(lambda: Options())
|
||||||
|
|
||||||
|
self._derive_from = derived_from
|
||||||
|
|
||||||
|
def __getitem__(self, key: Type[Page]):
|
||||||
|
return self._current_option_dict[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: Type[Page], value: Options):
|
||||||
|
self._current_option_dict[key] = value
|
||||||
|
|
||||||
|
self._length = 0
|
||||||
|
for key in self._current_option_dict:
|
||||||
|
self._length += 1
|
||||||
|
|
||||||
|
def __len__(self) -> int:
|
||||||
|
return self._length
|
||||||
|
|
||||||
|
def get_page_str(self, page: Type[Page]) -> str:
|
||||||
|
page_name_fill = "-"
|
||||||
|
max_page_len = 21
|
||||||
|
|
||||||
|
return f"({page_attributes.PAGE_NAME_MAP[page]}) ------------------------{page.__name__:{page_name_fill}<{max_page_len}}------------"
|
||||||
|
|
||||||
|
def string_from_all_pages(self) -> str:
|
||||||
|
if self._length == 1:
|
||||||
|
for key in self._current_option_dict:
|
||||||
|
return self.string_from_single_page(key)
|
||||||
|
|
||||||
|
lines: List[str] = []
|
||||||
|
|
||||||
|
j = 0
|
||||||
|
for page, options in self._current_option_dict.items():
|
||||||
|
lines.append(self.get_page_str(page))
|
||||||
|
|
||||||
|
i = -1
|
||||||
|
|
||||||
|
option_obj: DatabaseObject
|
||||||
|
for i, option_obj in enumerate(options):
|
||||||
|
if i >= self.max_displayed_options:
|
||||||
|
lines.append("...")
|
||||||
|
break
|
||||||
|
|
||||||
|
lines.append(f"{j + i:0{self.option_digits}} {option_obj.option_string}")
|
||||||
|
|
||||||
|
j += i + 1
|
||||||
|
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
def choose_from_all_pages(self, index: int) -> Tuple[DatabaseObject, Type[Page]]:
|
||||||
|
if self._length == 1:
|
||||||
|
for key in self._current_option_dict:
|
||||||
|
return self.choose_from_single_page(key, index), key
|
||||||
|
|
||||||
|
sum_of_length = 0
|
||||||
|
for page, options in self._current_option_dict.items():
|
||||||
|
option_len = min((len(options), self.max_displayed_options))
|
||||||
|
|
||||||
|
index_of_list = index - sum_of_length
|
||||||
|
|
||||||
|
if index_of_list < option_len:
|
||||||
|
return options[index_of_list], page
|
||||||
|
|
||||||
|
sum_of_length += option_len
|
||||||
|
|
||||||
|
raise IndexError("index is out of range")
|
||||||
|
|
||||||
|
def string_from_single_page(self, page: Type[Page]) -> str:
|
||||||
|
lines: List[str] = [self.get_page_str(page)]
|
||||||
|
|
||||||
|
option_obj: DatabaseObject
|
||||||
|
for i, option_obj in enumerate(self._current_option_dict[page]):
|
||||||
|
lines.append(f"{i:0{self.option_digits}} {option_obj.option_string}")
|
||||||
|
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
def choose_from_single_page(self, page: Type[Page], index: int) -> DatabaseObject:
|
||||||
|
return self._current_option_dict[page][index]
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return self.string_from_all_pages()
|
||||||
|
|
@ -3,117 +3,10 @@ from typing import Tuple, List, Set, Dict, Type, Union, Optional
|
|||||||
|
|
||||||
from . import page_attributes
|
from . import page_attributes
|
||||||
from .download import Download
|
from .download import Download
|
||||||
|
from .multiple_options import MultiPageOptions
|
||||||
from ..abstract import Page
|
from ..abstract import Page
|
||||||
from ...objects import Options, DatabaseObject, Source
|
from ...objects import Options, DatabaseObject, Source
|
||||||
|
from ...utils.shared import DOWNLOAD_LOGGER as LOGGER
|
||||||
|
|
||||||
class MultiPageOptions:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
max_displayed_options: int = 10,
|
|
||||||
option_digits: int = 3,
|
|
||||||
database_object: DatabaseObject = None,
|
|
||||||
page: Type[Page] = None
|
|
||||||
) -> None:
|
|
||||||
self.max_displayed_options = max_displayed_options
|
|
||||||
self.option_digits: int = option_digits
|
|
||||||
|
|
||||||
self._length = 0
|
|
||||||
self._current_option_dict: Dict[Type[Page], Options] = defaultdict(lambda: Options())
|
|
||||||
|
|
||||||
self.database_object = database_object
|
|
||||||
self.page = page
|
|
||||||
|
|
||||||
if database_object is not None and page is not None:
|
|
||||||
self[page] = database_object.options
|
|
||||||
|
|
||||||
def __getitem__(self, key: Type[Page]):
|
|
||||||
return self._current_option_dict[key]
|
|
||||||
|
|
||||||
def __setitem__(self, key: Type[Page], value: Options):
|
|
||||||
self._current_option_dict[key] = value
|
|
||||||
|
|
||||||
self._length = 0
|
|
||||||
for key in self._current_option_dict:
|
|
||||||
self._length += 1
|
|
||||||
|
|
||||||
def __len__(self) -> int:
|
|
||||||
return self._length
|
|
||||||
|
|
||||||
def get_page_str(self, page: Type[Page]) -> str:
|
|
||||||
page_name_fill = "-"
|
|
||||||
max_page_len = 21
|
|
||||||
|
|
||||||
return f"({page_attributes.PAGE_NAME_MAP[page]}) ------------------------{page.__name__:{page_name_fill}<{max_page_len}}------------"
|
|
||||||
|
|
||||||
def string_from_all_pages(self) -> str:
|
|
||||||
if self._length == 1:
|
|
||||||
for key in self._current_option_dict:
|
|
||||||
return self.string_from_single_page(key)
|
|
||||||
|
|
||||||
lines: List[str] = []
|
|
||||||
|
|
||||||
j = 0
|
|
||||||
for page, options in self._current_option_dict.items():
|
|
||||||
lines.append(self.get_page_str(page))
|
|
||||||
|
|
||||||
i = -1
|
|
||||||
|
|
||||||
option_obj: DatabaseObject
|
|
||||||
for i, option_obj in enumerate(options):
|
|
||||||
if i >= self.max_displayed_options:
|
|
||||||
lines.append("...")
|
|
||||||
break
|
|
||||||
|
|
||||||
lines.append(f"{j + i:0{self.option_digits}} {option_obj.option_string}")
|
|
||||||
|
|
||||||
j += i + 1
|
|
||||||
|
|
||||||
return "\n".join(lines)
|
|
||||||
|
|
||||||
def choose_from_all_pages(self, index: int) -> Tuple[DatabaseObject, Type[Page]]:
|
|
||||||
if self._length == 1:
|
|
||||||
for key in self._current_option_dict:
|
|
||||||
return self.choose_from_single_page(key, index), key
|
|
||||||
|
|
||||||
sum_of_length = 0
|
|
||||||
for page, options in self._current_option_dict.items():
|
|
||||||
option_len = min((len(options), self.max_displayed_options))
|
|
||||||
|
|
||||||
index_of_list = index - sum_of_length
|
|
||||||
|
|
||||||
if index_of_list < option_len:
|
|
||||||
return options[index_of_list], page
|
|
||||||
|
|
||||||
sum_of_length += option_len
|
|
||||||
|
|
||||||
raise IndexError("index is out of range")
|
|
||||||
|
|
||||||
def string_from_single_page(self, page: Type[Page]) -> str:
|
|
||||||
lines: List[str] = [self.get_page_str(page)]
|
|
||||||
|
|
||||||
option_obj: DatabaseObject
|
|
||||||
for i, option_obj in enumerate(self._current_option_dict[page]):
|
|
||||||
lines.append(f"{i:0{self.option_digits}} {option_obj.option_string}")
|
|
||||||
|
|
||||||
return "\n".join(lines)
|
|
||||||
|
|
||||||
def choose_from_single_page(self, page: Type[Page], index: int) -> DatabaseObject:
|
|
||||||
return self._current_option_dict[page][index]
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return self.string_from_all_pages()
|
|
||||||
|
|
||||||
def download(self) -> bool:
|
|
||||||
if self._length != 1:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if self.database_object is None or self.page is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
self.page.download(self.database_object)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class Search(Download):
|
class Search(Download):
|
||||||
@ -142,31 +35,22 @@ class Search(Download):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self._current_option.__repr__()
|
return self._current_option.__repr__()
|
||||||
|
|
||||||
@property
|
def next_options(self, derive_from: DatabaseObject = None) -> MultiPageOptions:
|
||||||
def next_options(self) -> MultiPageOptions:
|
|
||||||
mpo = MultiPageOptions(
|
|
||||||
max_displayed_options=self.max_displayed_options,
|
|
||||||
option_digits=self.option_digits
|
|
||||||
)
|
|
||||||
self._option_history.append(mpo)
|
|
||||||
self._current_option = mpo
|
|
||||||
return mpo
|
|
||||||
|
|
||||||
def next_options_from_music_obj(self, database_obj: DatabaseObject, page: Type[Page]) -> MultiPageOptions:
|
|
||||||
mpo = MultiPageOptions(
|
mpo = MultiPageOptions(
|
||||||
max_displayed_options=self.max_displayed_options,
|
max_displayed_options=self.max_displayed_options,
|
||||||
option_digits=self.option_digits,
|
option_digits=self.option_digits,
|
||||||
database_object=database_obj,
|
derived_from=derive_from
|
||||||
page=page
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self._option_history.append(mpo)
|
self._option_history.append(mpo)
|
||||||
self._current_option = mpo
|
self._current_option = mpo
|
||||||
|
|
||||||
return mpo
|
return mpo
|
||||||
|
|
||||||
@property
|
|
||||||
def _previous_options(self) -> MultiPageOptions:
|
def _previous_options(self) -> MultiPageOptions:
|
||||||
self._option_history.pop()
|
self._option_history.pop()
|
||||||
self._current_option = self._option_history[-1]
|
self._current_option = self._option_history[-1]
|
||||||
|
|
||||||
return self._option_history[-1]
|
return self._option_history[-1]
|
||||||
|
|
||||||
def search(self, query: str):
|
def search(self, query: str):
|
||||||
@ -177,40 +61,62 @@ class Search(Download):
|
|||||||
the letter behind it defines the *type* of parameter,
|
the letter behind it defines the *type* of parameter,
|
||||||
followed by a space "#a Psychonaut 4 #r Tired, Numb and #t Drop by Drop"
|
followed by a space "#a Psychonaut 4 #r Tired, Numb and #t Drop by Drop"
|
||||||
if no # is in the query it gets treated as "unspecified query"
|
if no # is in the query it gets treated as "unspecified query"
|
||||||
|
|
||||||
|
doesn't set derived_from thus,
|
||||||
|
can't download right after
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for page in self.pages:
|
for page in self.pages:
|
||||||
self._current_option[page] = page.search_by_query(query=query)
|
self._current_option[page] = page.search_by_query(query=query)
|
||||||
|
|
||||||
def choose_page(self, page: Type[Page]):
|
def choose_page(self, page: Type[Page]):
|
||||||
|
"""
|
||||||
|
doesn't set derived_from thus,
|
||||||
|
can't download right after
|
||||||
|
"""
|
||||||
|
|
||||||
if page not in page_attributes.ALL_PAGES:
|
if page not in page_attributes.ALL_PAGES:
|
||||||
raise ValueError(f"Page \"{page.__name__}\" does not exist in page_attributes.ALL_PAGES")
|
raise ValueError(f"Page \"{page.__name__}\" does not exist in page_attributes.ALL_PAGES")
|
||||||
|
|
||||||
prev_mpo = self._current_option
|
prev_mpo = self._current_option
|
||||||
mpo = self.next_options
|
mpo = self.next_options()
|
||||||
|
|
||||||
mpo[page] = prev_mpo[page]
|
mpo[page] = prev_mpo[page]
|
||||||
|
|
||||||
def get_page_from_query(self, query: str) -> Optional[Type[Page]]:
|
def _get_page_from_query(self, query: str) -> Optional[Type[Page]]:
|
||||||
|
"""
|
||||||
|
query can be for example:
|
||||||
|
"a" or "EncyclopaediaMetallum" to choose a page
|
||||||
|
"""
|
||||||
|
|
||||||
page = page_attributes.NAME_PAGE_MAP.get(query.lower().strip())
|
page = page_attributes.NAME_PAGE_MAP.get(query.lower().strip())
|
||||||
|
|
||||||
if page in self.pages:
|
if page in self.pages:
|
||||||
return page
|
return page
|
||||||
|
|
||||||
|
def _get_page_from_source(self, source: Source) -> Optional[Type[Page]]:
|
||||||
|
return page_attributes.SOURCE_PAGE_MAP.get(source.page_enum)
|
||||||
|
|
||||||
def choose_index(self, index: int):
|
def choose_index(self, index: int):
|
||||||
db_object, page = self._current_option.choose_from_all_pages(index=index)
|
db_object, page = self._current_option.choose_from_all_pages(index=index)
|
||||||
|
|
||||||
music_object = self.fetch_details(db_object)
|
music_object = self.fetch_details(db_object)
|
||||||
|
|
||||||
mpo = self.next_options_from_music_obj(music_object, page)
|
mpo = self.next_options_from_music_obj(music_object, page)
|
||||||
|
|
||||||
|
mpo[page] = music_object.options
|
||||||
|
|
||||||
def goto_previous(self):
|
def goto_previous(self):
|
||||||
try:
|
try:
|
||||||
self._current_option = self._previous_options
|
self._previous_options()
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def search_url(self, url: str) -> bool:
|
def search_url(self, url: str) -> bool:
|
||||||
|
"""
|
||||||
|
sets derived_from, thus
|
||||||
|
can download directly after
|
||||||
|
"""
|
||||||
|
|
||||||
source = Source.match_url(url=url)
|
source = Source.match_url(url=url)
|
||||||
if source is None:
|
if source is None:
|
||||||
return False
|
return False
|
||||||
@ -220,10 +126,20 @@ class Search(Download):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
page = page_attributes.SOURCE_PAGE_MAP[source.page_enum]
|
page = page_attributes.SOURCE_PAGE_MAP[source.page_enum]
|
||||||
mpo = self.next_options
|
mpo = self.next_options(derive_from=new_object)
|
||||||
mpo[page] = new_object.options
|
mpo[page] = new_object.options
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def download_chosen(self) -> bool:
|
def download_chosen(self) -> bool:
|
||||||
return self._current_option.download()
|
if self._current_option._derive_from is None:
|
||||||
|
LOGGER.warning(f"can't download from an non choosen stuff")
|
||||||
|
return False
|
||||||
|
|
||||||
|
source: Source
|
||||||
|
for source in self._current_option._derive_from.source_collection:
|
||||||
|
page = self._get_page_from_source(source=source)
|
||||||
|
|
||||||
|
if page in self.audio_pages:
|
||||||
|
return page.download(music_object=self._current_option._derive_from)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user