mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-25 04:15:19 -08:00
feat(anilist interface): add rofi as tertiary option for the interface
This commit is contained in:
@@ -112,6 +112,8 @@ signal.signal(signal.SIGINT, handle_exit)
|
||||
)
|
||||
@click.option("--dub", help="Set the translation type to dub", is_flag=True)
|
||||
@click.option("--sub", help="Set the translation type to sub", is_flag=True)
|
||||
@click.option("--rofi", help="Use rofi for the ui", is_flag=True)
|
||||
@click.option("--rofi-theme", help="Rofi theme to use", type=click.Path())
|
||||
@click.pass_context
|
||||
def run_cli(
|
||||
ctx: click.Context,
|
||||
@@ -133,6 +135,8 @@ def run_cli(
|
||||
icons,
|
||||
dub,
|
||||
sub,
|
||||
rofi,
|
||||
rofi_theme,
|
||||
):
|
||||
ctx.obj = Config()
|
||||
if provider:
|
||||
@@ -176,3 +180,11 @@ def run_cli(
|
||||
ctx.obj.translation_type = "dub"
|
||||
if sub:
|
||||
ctx.obj.translation_type = "sub"
|
||||
if rofi:
|
||||
ctx.obj.use_fzf = False
|
||||
ctx.obj.use_rofi = True
|
||||
if rofi_theme:
|
||||
ctx.obj.rofi_theme = rofi_theme
|
||||
from ..libs.rofi import Rofi
|
||||
|
||||
Rofi.rofi_theme = rofi_theme
|
||||
|
||||
@@ -5,6 +5,7 @@ from rich import print
|
||||
|
||||
from ..AnimeProvider import AnimeProvider
|
||||
from ..constants import USER_CONFIG_PATH, USER_VIDEOS_DIR
|
||||
from ..libs.rofi import Rofi
|
||||
from ..Utility.user_data_helper import user_data_helper
|
||||
|
||||
|
||||
@@ -38,6 +39,8 @@ class Config(object):
|
||||
"icons": "false",
|
||||
"notification_duration": "2",
|
||||
"skip": "false",
|
||||
"use_rofi": "false",
|
||||
"rofi_theme": "",
|
||||
}
|
||||
)
|
||||
self.configparser.add_section("stream")
|
||||
@@ -46,12 +49,14 @@ class Config(object):
|
||||
if not os.path.exists(USER_CONFIG_PATH):
|
||||
with open(USER_CONFIG_PATH, "w") as config:
|
||||
self.configparser.write(config)
|
||||
|
||||
self.configparser.read(USER_CONFIG_PATH)
|
||||
|
||||
# --- set defaults ---
|
||||
self.downloads_dir = self.get_downloads_dir()
|
||||
self.provider = self.get_provider()
|
||||
self.use_fzf = self.get_use_fzf()
|
||||
self.use_rofi = self.get_use_rofi()
|
||||
self.skip = self.get_skip()
|
||||
self.icons = self.get_icons()
|
||||
self.preview = self.get_preview()
|
||||
@@ -66,6 +71,8 @@ class Config(object):
|
||||
self.server = self.get_server()
|
||||
self.format = self.get_format()
|
||||
self.preferred_language = self.get_preferred_language()
|
||||
self.rofi_theme = self.get_rofi_theme()
|
||||
Rofi.rofi_theme = self.rofi_theme
|
||||
|
||||
# ---- setup user data ------
|
||||
self.watch_history: dict = user_data_helper.user_data.get("watch_history", {})
|
||||
@@ -108,12 +115,18 @@ class Config(object):
|
||||
def get_provider(self):
|
||||
return self.configparser.get("general", "provider")
|
||||
|
||||
def get_rofi_theme(self):
|
||||
return self.configparser.get("general", "rofi_theme")
|
||||
|
||||
def get_downloads_dir(self):
|
||||
return self.configparser.get("general", "downloads_dir")
|
||||
|
||||
def get_use_fzf(self):
|
||||
return self.configparser.getboolean("general", "use_fzf")
|
||||
|
||||
def get_use_rofi(self):
|
||||
return self.configparser.getboolean("general", "use_rofi")
|
||||
|
||||
def get_skip(self):
|
||||
return self.configparser.getboolean("stream", "skip")
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ from ...constants import USER_CONFIG_PATH
|
||||
from ...libs.anilist.anilist_data_schema import AnilistBaseMediaDataSchema
|
||||
from ...libs.anime_provider.types import Anime, SearchResult, Server
|
||||
from ...libs.fzf import fzf
|
||||
from ...libs.rofi import Rofi
|
||||
from ...Utility.data import anime_normalizer
|
||||
from ...Utility.utils import anime_title_percentage_match, sanitize_filename
|
||||
from ..config import Config
|
||||
@@ -113,7 +114,7 @@ def player_controls(config: Config, anilist_config: QueryDict):
|
||||
):
|
||||
anilist_options(config, anilist_config)
|
||||
return
|
||||
else:
|
||||
elif not config.use_rofi:
|
||||
if not Confirm.ask(
|
||||
"Are you sure you wish to continue to the next episode, your progress for the current episodes will be erased?",
|
||||
default=True,
|
||||
@@ -164,6 +165,8 @@ def player_controls(config: Config, anilist_config: QueryDict):
|
||||
quality = fzf.run(
|
||||
options, prompt="Select Quality:", header="Quality Options"
|
||||
)
|
||||
elif config.use_rofi:
|
||||
quality = Rofi.run(options, "Select Quality")
|
||||
else:
|
||||
quality = fuzzy_inquirer("Select Quality", options)
|
||||
config.quality = options.index(quality) # set quality
|
||||
@@ -176,6 +179,8 @@ def player_controls(config: Config, anilist_config: QueryDict):
|
||||
translation_type = fzf.run(
|
||||
options, prompt="Select Translation Type: ", header="Lang Options"
|
||||
).lower()
|
||||
elif config.use_rofi:
|
||||
translation_type = Rofi.run(options, "Select Translation Type")
|
||||
else:
|
||||
translation_type = fuzzy_inquirer(
|
||||
"Select Translation Type", options
|
||||
@@ -214,6 +219,8 @@ def player_controls(config: Config, anilist_config: QueryDict):
|
||||
action = fzf.run(
|
||||
list(options.keys()), prompt="Select Action:", header="Player Controls"
|
||||
)
|
||||
elif config.use_rofi:
|
||||
action = Rofi.run(list(options.keys()), "Select Action")
|
||||
else:
|
||||
action = fuzzy_inquirer("Select Action", options.keys())
|
||||
options[action]()
|
||||
@@ -261,6 +268,8 @@ def fetch_streams(config: Config, anilist_config: QueryDict):
|
||||
prompt="Select Server: ",
|
||||
header="Servers",
|
||||
)
|
||||
elif config.use_rofi:
|
||||
server = Rofi.run(choices, "Select Server")
|
||||
else:
|
||||
server = fuzzy_inquirer("Select Server", choices)
|
||||
if server == "Back":
|
||||
@@ -370,6 +379,8 @@ def fetch_episode(config: Config, anilist_config: QueryDict):
|
||||
prompt="Select Episode:",
|
||||
header=anime_title,
|
||||
)
|
||||
elif config.use_rofi:
|
||||
episode_number = Rofi.run(choices, "Select Episode")
|
||||
else:
|
||||
episode_number = fuzzy_inquirer("Select Episode", choices)
|
||||
|
||||
@@ -457,6 +468,8 @@ def provide_anime(config: Config, anilist_config: QueryDict):
|
||||
header="Anime Search Results",
|
||||
)
|
||||
|
||||
elif config.use_rofi:
|
||||
anime_title = Rofi.run(choices, "Select Search Result")
|
||||
else:
|
||||
anime_title = fuzzy_inquirer("Select Search Result", choices)
|
||||
if anime_title == "Back":
|
||||
@@ -501,6 +514,10 @@ def anilist_options(config, anilist_config: QueryDict):
|
||||
"Choose the list you want to add to",
|
||||
"Add your animelist",
|
||||
)
|
||||
elif config.use_rofi:
|
||||
anime_list = Rofi.run(
|
||||
list(anime_lists.keys()), "Choose list you want to add to"
|
||||
)
|
||||
else:
|
||||
anime_list = fuzzy_inquirer(
|
||||
"Choose the list you want to add to", list(anime_lists.keys())
|
||||
@@ -559,6 +576,8 @@ def anilist_options(config, anilist_config: QueryDict):
|
||||
translation_type = fzf.run(
|
||||
options, prompt="Select Translation Type:", header="Language Options"
|
||||
)
|
||||
elif config.use_rofi:
|
||||
translation_type = Rofi.run(options, "Select Translation Type")
|
||||
else:
|
||||
translation_type = fuzzy_inquirer("Select translation type", options)
|
||||
|
||||
@@ -636,6 +655,8 @@ def anilist_options(config, anilist_config: QueryDict):
|
||||
action = fzf.run(
|
||||
list(options.keys()), prompt="Select Action:", header="Anime Menu"
|
||||
)
|
||||
elif config.use_rofi:
|
||||
action = Rofi.run(list(options.keys()), "Select Action")
|
||||
else:
|
||||
action = fuzzy_inquirer("Select Action", options.keys())
|
||||
options[action](config, anilist_config)
|
||||
@@ -668,6 +689,27 @@ def select_anime(config: Config, anilist_config: QueryDict):
|
||||
prompt="Select Anime: ",
|
||||
header="Search Results",
|
||||
)
|
||||
elif config.use_rofi:
|
||||
# TODO: Make this faster
|
||||
if config.preview and False:
|
||||
from .utils import SEARCH_RESULTS_CACHE, get_preview
|
||||
|
||||
get_preview(search_results, config, wait=True)
|
||||
choices = []
|
||||
for anime in search_results:
|
||||
title = sanitize_filename(
|
||||
str(
|
||||
anime["title"][config.preferred_language]
|
||||
or anime["title"]["romaji"]
|
||||
)
|
||||
)
|
||||
anime_cache = os.path.join(SEARCH_RESULTS_CACHE, title)
|
||||
icon_path = f"{anime_cache}/image"
|
||||
choices.append(f"{title}\0icon\x1f{icon_path}")
|
||||
choices.append("Back")
|
||||
selected_anime_title = Rofi.run_with_icons(choices, "Select Anime")
|
||||
else:
|
||||
selected_anime_title = Rofi.run(choices, "Select Anime")
|
||||
else:
|
||||
selected_anime_title = fuzzy_inquirer("Select Anime", choices)
|
||||
# "bat %s/{}" % SEARCH_RESULTS_CACHE
|
||||
@@ -749,7 +791,12 @@ def anilist(config: Config, anilist_config: QueryDict):
|
||||
import subprocess
|
||||
|
||||
subprocess.run([os.environ.get("EDITOR", "open"), USER_CONFIG_PATH])
|
||||
config.load_config()
|
||||
if config.use_rofi:
|
||||
config.load_config()
|
||||
config.use_rofi = True
|
||||
config.use_fzf = False
|
||||
else:
|
||||
config.load_config()
|
||||
|
||||
anilist(config, anilist_config)
|
||||
|
||||
@@ -793,6 +840,9 @@ def anilist(config: Config, anilist_config: QueryDict):
|
||||
prompt="Select Action: ",
|
||||
header="Anilist Menu",
|
||||
)
|
||||
elif config.use_rofi:
|
||||
|
||||
action = Rofi.run(list(options.keys()), "Select Action")
|
||||
else:
|
||||
action = fuzzy_inquirer("Select Action", options.keys())
|
||||
anilist_data = options[action]()
|
||||
|
||||
58
fastanime/libs/rofi/__init__.py
Normal file
58
fastanime/libs/rofi/__init__.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import subprocess
|
||||
from shutil import which
|
||||
from sys import exit
|
||||
|
||||
|
||||
class RofiApi:
|
||||
ROFI_EXECUTABLE = which("rofi")
|
||||
|
||||
rofi_theme = ""
|
||||
|
||||
def run_with_icons(self, options: list[str], prompt_text: str) -> str:
|
||||
rofi_input = "\n".join(options)
|
||||
|
||||
if not self.ROFI_EXECUTABLE:
|
||||
raise Exception("Rofi not found")
|
||||
|
||||
args = [self.ROFI_EXECUTABLE]
|
||||
if self.rofi_theme:
|
||||
args.extend(["-no-config", "-theme", self.rofi_theme])
|
||||
args.extend(["-p", prompt_text, "-i", "-show-icons", "-dmenu"])
|
||||
result = subprocess.run(
|
||||
args,
|
||||
input=rofi_input,
|
||||
stdout=subprocess.PIPE,
|
||||
text=True,
|
||||
)
|
||||
|
||||
choice = result.stdout.strip()
|
||||
if not choice:
|
||||
exit(1)
|
||||
|
||||
return choice
|
||||
|
||||
def run(self, options: list[str], prompt_text: str) -> str:
|
||||
rofi_input = "\n".join(options)
|
||||
|
||||
if not self.ROFI_EXECUTABLE:
|
||||
raise Exception("Rofi not found")
|
||||
|
||||
args = [self.ROFI_EXECUTABLE]
|
||||
if self.rofi_theme:
|
||||
args.extend(["-no-config", "-theme", self.rofi_theme])
|
||||
args.extend(["-p", prompt_text, "-i", "-dmenu"])
|
||||
result = subprocess.run(
|
||||
args,
|
||||
input=rofi_input,
|
||||
stdout=subprocess.PIPE,
|
||||
text=True,
|
||||
)
|
||||
|
||||
choice = result.stdout.strip()
|
||||
if not choice or choice not in options:
|
||||
exit(1)
|
||||
|
||||
return choice
|
||||
|
||||
|
||||
Rofi = RofiApi()
|
||||
Reference in New Issue
Block a user