feat(cli): add auto-select provider results

This commit is contained in:
Benex254
2024-08-05 09:47:02 +03:00
parent 8f6d24cb52
commit 9541bafc2f
7 changed files with 95 additions and 23 deletions

View File

@@ -4,6 +4,12 @@ import shutil
from datetime import datetime
from functools import lru_cache
from fuzzywuzzy import fuzz
from fastanime.libs.anilist.anilist_data_schema import AnilistBaseMediaDataSchema
from .data import anime_normalizer
# TODO: make it use color_text instead of fixed vals
# from .kivy_markup_helper import color_text
@@ -98,6 +104,32 @@ def sanitize_filename(filename: str):
return sanitized
def anime_title_percentage_match(
possible_user_requested_anime_title: str, anime: AnilistBaseMediaDataSchema
) -> float:
"""Returns the percentage match between the possible title and user title
Args:
possible_user_requested_anime_title (str): an Animdl search result title
title (str): the anime title the user wants
Returns:
int: the percentage match
"""
if normalized_anime_title := anime_normalizer.get(
possible_user_requested_anime_title
):
possible_user_requested_anime_title = normalized_anime_title
# compares both the romaji and english names and gets highest Score
title_a = str(anime["title"]["romaji"])
title_b = str(anime["title"]["english"])
percentage_ratio = max(
fuzz.ratio(title_a.lower(), possible_user_requested_anime_title.lower()),
fuzz.ratio(title_b.lower(), possible_user_requested_anime_title.lower()),
)
return percentage_ratio
if __name__ == "__main__":
# Example usage
unsafe_filename = "CON:example?file*name.txt"

View File

@@ -48,7 +48,8 @@ signal.signal(signal.SIGINT, handle_exit)
@click.option("-c/-no-c", "--continue/--no-continue", "continue_", type=bool)
@click.option("-q", "--quality", type=int)
@click.option("-t", "--translation_type")
@click.option("-a", "--auto-next", type=bool)
@click.option("-A/-no-A", "--auto-next/--no-auto-next", type=bool)
@click.option("-a/-no-a", "--auto-select/--no-auto-select", type=bool)
@click.option(
"-S",
"--sort-by",
@@ -63,6 +64,7 @@ def run_cli(
translation_type,
quality,
auto_next,
auto_select,
sort_by,
downloads_dir,
):
@@ -75,6 +77,8 @@ def run_cli(
ctx.obj.quality = quality
if auto_next:
ctx.obj.auto_next = auto_next
if auto_select:
ctx.obj.auto_select = auto_select
if sort_by:
ctx.obj.sort_by = sort_by
if downloads_dir:

View File

@@ -1,4 +1,6 @@
import click
from fuzzywuzzy import fuzz
from rich import print
from ...libs.anime_provider.allanime.api import anime_provider
from ...libs.anime_provider.types import Anime
@@ -35,9 +37,15 @@ def download(config: Config, anime_title, episode_range):
search_result["title"]: search_result for search_result in search_results
}
search_result = fzf.run(
list(search_results_.keys()), "Please Select title: ", "FastAnime"
)
if config.auto_select:
search_result = max(
search_results_.keys(), key=lambda title: fuzz.ratio(title, anime_title)
)
print("[cyan]Auto selecting:[/] ", search_result)
else:
search_result = fzf.run(
list(search_results_.keys()), "Please Select title: ", "FastAnime"
)
anime: Anime = anime_provider.get_anime(search_results_[search_result]["id"])
@@ -51,7 +59,7 @@ def download(config: Config, anime_title, episode_range):
try:
episode = str(episode)
if episode not in episodes:
print("Episode not found skipping")
print(f"[cyan]Warning[/]: Episode {episode} not found, skipping")
continue
streams = anime_provider.get_episode_streams(
anime, episode, config.translation_type

View File

@@ -1,4 +1,6 @@
import click
from fuzzywuzzy import fuzz
from rich import print
from ...cli.config import Config
from ...libs.anime_provider.allanime.api import anime_provider
@@ -24,16 +26,23 @@ def search(
search_results_ = {
search_result["title"]: search_result for search_result in search_results
}
if config.auto_select:
search_result = max(
search_results_.keys(), key=lambda title: fuzz.ratio(title, anime_title)
)
print("[cyan]Auto Selecting:[/] ", search_result)
search_result = fzf.run(
list(search_results_.keys()), "Please Select title: ", "FastAnime"
)
else:
search_result = fzf.run(
list(search_results_.keys()), "Please Select title: ", "FastAnime"
)
anime: Anime = anime_provider.get_anime(search_results_[search_result]["id"])
def stream_anime():
episodes = anime["availableEpisodesDetail"][config.translation_type]
episode = fzf.run(episodes, "Select an episode: ", header="Episodes")
episode = fzf.run(episodes, "Select an episode: ", header=search_result)
streams = anime_provider.get_episode_streams(
anime, episode, config.translation_type
)

View File

@@ -21,6 +21,7 @@ class Config(object):
"continue_from_history": "False",
"quality": "0",
"auto_next": "True",
"auto_select": "True",
"sort_by": "search match",
"downloads_dir": USER_VIDEOS_DIR,
"translation_type": "sub",
@@ -41,6 +42,7 @@ class Config(object):
self.sort_by = self.get_sort_by()
self.continue_from_history = self.get_continue_from_history()
self.auto_next = self.get_auto_next()
self.auto_select = self.get_auto_select()
self.quality = self.get_quality()
self.server = self.get_server()
self.preferred_language = self.get_preferred_language()
@@ -84,6 +86,9 @@ class Config(object):
def get_auto_next(self):
return self.configparser.getboolean("stream", "auto_next")
def get_auto_select(self):
return self.configparser.getboolean("stream", "auto_select")
def get_quality(self):
return self.configparser.getint("stream", "quality")

View File

@@ -14,7 +14,11 @@ from ...libs.anime_provider.types import Anime, SearchResult, Server
from ...libs.fzf import fzf
from ...Utility import anilist_data_helper
from ...Utility.data import anime_normalizer
from ...Utility.utils import remove_html_tags, sanitize_filename
from ...Utility.utils import (
anime_title_percentage_match,
remove_html_tags,
sanitize_filename,
)
from ..config import Config
from ..utils.mpv import mpv
from ..utils.tools import QueryDict, exit_app
@@ -303,6 +307,7 @@ def fetch_episode(config: Config, anilist_config: QueryDict):
continue_from_history: bool = config.continue_from_history
user_watch_history: dict = config.watch_history
anime_id: int = anilist_config.anime_id
anime_title: str = anilist_config.anime_title
# internal config
anime: Anime = anilist_config.anime
@@ -317,7 +322,7 @@ def fetch_episode(config: Config, anilist_config: QueryDict):
episode_number = fzf.run(
[*episodes, "Back"],
prompt="Select Episode:",
header="Episodes",
header=anime_title,
)
if episode_number == "Back":
@@ -354,6 +359,8 @@ def provide_anime(config: Config, anilist_config: QueryDict):
# internal config
selected_anime_title = anilist_config.selected_anime_title
anime_data: AnilistBaseMediaDataSchema = anilist_config.selected_anime_anilist
# search and get the requested title from provider
search_results = anime_provider.search_for_anime(
selected_anime_title, translation_type
@@ -371,15 +378,22 @@ def provide_anime(config: Config, anilist_config: QueryDict):
):
_title = _title
anime_title = fzf.run(
[*search_results.keys(), "Back"],
prompt="Select Search Result:",
header="Anime Search Results",
)
if config.auto_select:
anime_title = max(
search_results.keys(),
key=lambda title: anime_title_percentage_match(title, anime_data),
)
print(f"[cyan]Auto selecting[/]: {anime_title}")
else:
anime_title = fzf.run(
[*search_results.keys(), "Back"],
prompt="Select Search Result:",
header="Anime Search Results",
)
if anime_title == "Back":
anilist_options(config, anilist_config)
return
if anime_title == "Back":
anilist_options(config, anilist_config)
return
anilist_config.anime_title = anime_normalizer.get(anime_title) or anime_title
anilist_config._anime = search_results[anime_title]
fetch_anime_episode(config, anilist_config)

View File

@@ -151,7 +151,7 @@ class AllAnimeAPI:
yield {
"server": "gogoanime",
"episode_title": allanime_episode["notes"]
or f"{anime["title"]} Episode:{episode_number}",
or f"{anime["title"]}: Episode {episode_number}",
"links": resp.json()["links"],
} # pyright:ignore
case "Kir":
@@ -160,7 +160,7 @@ class AllAnimeAPI:
yield {
"server": "wetransfer",
"episode_title": allanime_episode["notes"]
or f"{anime["title"]} Episode:{episode_number}",
or f"{anime["title"]}: Episode {episode_number}",
"links": resp.json()["links"],
} # pyright:ignore
case "S-mp4":
@@ -169,7 +169,7 @@ class AllAnimeAPI:
yield {
"server": "sharepoint",
"episode_title": allanime_episode["notes"]
or f"{anime["title"]} Episode:{episode_number}",
or f"{anime["title"]}: Episode {episode_number}",
"links": resp.json()["links"],
} # pyright:ignore
case "Sak":
@@ -178,7 +178,7 @@ class AllAnimeAPI:
yield {
"server": "dropbox",
"episode_title": allanime_episode["notes"]
or f"{anime["title"]} Episode:{episode_number}",
or f"{anime["title"]}: Episode {episode_number}",
"links": resp.json()["links"],
} # pyright:ignore
except Timeout: