From dcc49ff1fa597e1b7151995455a6c56e3820f139 Mon Sep 17 00:00:00 2001 From: Benedict Xavier Wanyonyi Date: Thu, 30 May 2024 17:27:28 +0300 Subject: [PATCH] feat: added animdl config manager --- app/Utility/animdl_config_manager.py | 34 ++++++++++++++++++++ app/Utility/media_card_loader.py | 1 + app/Utility/yaml_parser.py | 34 ++++++++++++++++++++ app/animdl_config.yml | 3 -- app/animdl_config_panel.json | 48 ++++++++++++++++++++++++++++ app/general_settings_panel.json | 35 ++++++++++++++++++++ app/main.py | 48 +++++++++++++++++++++++++--- 7 files changed, 196 insertions(+), 7 deletions(-) create mode 100644 app/Utility/animdl_config_manager.py create mode 100644 app/Utility/yaml_parser.py delete mode 100644 app/animdl_config.yml create mode 100644 app/animdl_config_panel.json create mode 100644 app/general_settings_panel.json diff --git a/app/Utility/animdl_config_manager.py b/app/Utility/animdl_config_manager.py new file mode 100644 index 0000000..be14005 --- /dev/null +++ b/app/Utility/animdl_config_manager.py @@ -0,0 +1,34 @@ +from typing import TypedDict +import plyer +import os + +from .yaml_parser import YamlParser + + +class AnimdlConfig(TypedDict): + default_player: str + default_provider: str + quality_string: str + + +user_profile_path = plyer.storagepath.get_home_dir() # type: ignore +animdl_config_folder_location = os.path.join(user_profile_path, ".animdl") +if not os.path.exists(animdl_config_folder_location): + os.mkdir(animdl_config_folder_location) + +animdl_config_location = os.path.join(animdl_config_folder_location, "config.yml") +animdl_config = YamlParser( + animdl_config_location, + {"default_player": "mpv", "default_provider": "AllAnime", "quality_string": "best"}, + AnimdlConfig, +) + + +def update_animdl_config(field_to_update: str, value): + current_data = animdl_config.data + current_data[f"{field_to_update}"] = value + animdl_config.write(current_data) + + +def get_animdl_config() -> AnimdlConfig: + return animdl_config.data diff --git a/app/Utility/media_card_loader.py b/app/Utility/media_card_loader.py index 0e036ff..eb1fe90 100644 --- a/app/Utility/media_card_loader.py +++ b/app/Utility/media_card_loader.py @@ -24,6 +24,7 @@ for link in yt_stream_links: Cache.append("yt_stream_links.anime", link[0], tuple(link[1])) +# TODO: Make this process more efficient # for youtube video links gotten from from pytube which is blocking class MediaCardDataLoader(object): """this class loads an anime media card and gets the trailer url from pytube""" diff --git a/app/Utility/yaml_parser.py b/app/Utility/yaml_parser.py new file mode 100644 index 0000000..e1d838c --- /dev/null +++ b/app/Utility/yaml_parser.py @@ -0,0 +1,34 @@ +import yaml + +import os + + +class YamlParser: + """makes managing yaml files easier""" + + data = {} + + def __init__(self, file_path: str, default, data_type): + self.file_path: str = file_path + self.data: data_type + if os.path.exists(file_path): + try: + with open(self.file_path, "r") as yaml_file: + self.data = yaml.safe_load(yaml_file) + except: + self.data = default + with open(file_path, "w") as yaml_file: + yaml.dump(default, yaml_file) + else: + self.data = default + with open(file_path, "w") as yaml_file: + yaml.dump(default, yaml_file) + + def read(self): + with open(self.file_path, "r") as yaml_file: + self.data = yaml.safe_load(yaml_file) + return self.data + + def write(self, new_obj): + with open(self.file_path, "w") as yaml_file: + yaml.dump(new_obj, yaml_file) diff --git a/app/animdl_config.yml b/app/animdl_config.yml deleted file mode 100644 index 77a2db4..0000000 --- a/app/animdl_config.yml +++ /dev/null @@ -1,3 +0,0 @@ -default_player: mpv -default_provider: allanime -quality_string: "1080/best" \ No newline at end of file diff --git a/app/animdl_config_panel.json b/app/animdl_config_panel.json new file mode 100644 index 0000000..36f1187 --- /dev/null +++ b/app/animdl_config_panel.json @@ -0,0 +1,48 @@ +[ + { + "type": "title", + "title": "Providers" + }, + { + "type": "options", + "title": "Default Provider", + "desc": "Sets the default provider animdl should use", + "section": "Providers", + "key": "default_provider", + "options": [ + "9anime", + "AllAnime", + "AnimePahe", + "AnimeOut", + "Animtime", + "Kawaifu", + "GoGoAnime", + "Haho", + "Marin", + "Zoro" + ] + }, + { + "type": "title", + "title": "Quality" + }, + { + "type": "string", + "title": "Quality String", + "desc": "Sets the animdl quality string", + "section": "Quality", + "key": "quality_string" + }, + { + "type": "title", + "title": "PlayerSelection" + }, + { + "type": "options", + "title": "Default Player", + "desc": "Sets the animdl default player to use", + "section": "PlayerSelection", + "key": "default_player", + "options": ["mpv", "vlc", "ffpyplayer", "celluloid", "iina"] + } +] diff --git a/app/general_settings_panel.json b/app/general_settings_panel.json new file mode 100644 index 0000000..e775149 --- /dev/null +++ b/app/general_settings_panel.json @@ -0,0 +1,35 @@ +[ + { + "type": "title", + "title": "Preferences" + }, + { + "type": "string", + "title": "Theme Color", + "desc": "Sets the theme color to be used for the app for more info on valid theme names refer to help", + "section": "Preferences", + "key": "theme_color" + }, + { + "type": "options", + "title": "Theme Style", + "desc": "Sets the app to dark or light theme", + "section": "Preferences", + "key": "theme_style", + "options":["Light","Dark"] + }, + { + "type": "path", + "title": "Downloads Directory", + "desc": "location to download your videos", + "section": "Preferences", + "key": "downloads_dir" + }, + { + "type": "bool", + "title": "Show Startup anime", + "desc": "whether to show the startup anime, switch it off for faster app startup times", + "section": "Preferences", + "key": "is_startup_anime_enable" + } +] diff --git a/app/main.py b/app/main.py index d2d7418..d6f465f 100644 --- a/app/main.py +++ b/app/main.py @@ -29,7 +29,12 @@ from kivymd.app import MDApp from View.screens import screens from libs.animdl import AnimdlApi -from Utility import themes_available, show_notification, user_data_helper +from Utility import ( + themes_available, + show_notification, + user_data_helper, + animdl_config_manager, +) # Ensure the user data fields exist @@ -53,7 +58,7 @@ class AniXStreamApp(MDApp): try: task() except Exception as e: - show_notification("An error occured while streaming",f"{e}") + show_notification("An error occured while streaming", f"{e}") self.queue.task_done() def downloads_worker(self, queue: Queue): @@ -62,7 +67,7 @@ class AniXStreamApp(MDApp): try: download_task() except Exception as e: - show_notification("An error occured while downloading",f"{e}") + show_notification("An error occured while downloading", f"{e}") self.downloads_queue.task_done() def __init__(self, **kwargs): @@ -116,6 +121,8 @@ class AniXStreamApp(MDApp): self.manager_screens.add_widget(view) def build_config(self, config): + + # General settings setup if vid_path := plyer.storagepath.get_videos_dir(): # type: ignore downloads_dir = os.path.join(vid_path, "anixstream") if not os.path.exists(downloads_dir): @@ -134,10 +141,37 @@ class AniXStreamApp(MDApp): }, ) + # animdl config settings setup + animdl_config = animdl_config_manager.get_animdl_config() + config.setdefaults( + "Providers", + { + "default_provider": animdl_config["default_provider"], + }, + ) + config.setdefaults( + "Quality", + { + "quality_string": animdl_config["quality_string"], + }, + ) + config.setdefaults( + "PlayerSelection", + { + "default_player": animdl_config["default_player"], + }, + ) + def build_settings(self, settings: Settings): - settings.add_json_panel("Settings", self.config, "settings.json") + settings.add_json_panel( + "Settings", self.config, "./general_settings_panel.json" + ) + settings.add_json_panel( + "Animdl Config", self.config, "./animdl_config_panel.json" + ) def on_config_change(self, config, section, key, value): + # TODO: Change to match case if section == "Preferences": match key: case "theme_color": @@ -151,6 +185,12 @@ class AniXStreamApp(MDApp): config.write() case "theme_style": self.theme_cls.theme_style = value + elif section == "Providers": + animdl_config_manager.update_animdl_config("default_provider", value) + elif section == "Quality": + animdl_config_manager.update_animdl_config("quality_string", value) + elif section == "PlayerSelection": + animdl_config_manager.update_animdl_config("default_player", value) def on_stop(self): del self.downloads_worker_thread