diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 48ee030..64d4c1e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,25 @@ +default_language_version: + python: python3.10 + repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.3.0 + - repo: https://github.com/pre-commit/mirrors-isort + rev: v5.10.1 # You can replace this with the latest version hooks: - - id: check-yaml - - id: end-of-file-fixer - - id: trailing-whitespace -- repo: https://github.com/psf/black - rev: 22.10.0 + - id: isort + name: isort + args: ["--profile", "black"] # Ensure compatibility with Black + + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.4.10 hooks: - - id: black + # Run the linter. + - id: ruff + args: [ --fix ] + + - repo: https://github.com/psf/black + rev: 23.3.0 # You can replace this with the latest version + hooks: + - id: black + name: black + language_version: python3.10 # Specify your Python version diff --git a/fastanime/Utility/downloader/downloader.py b/fastanime/Utility/downloader/downloader.py index 6429fb1..0857700 100644 --- a/fastanime/Utility/downloader/downloader.py +++ b/fastanime/Utility/downloader/downloader.py @@ -1,10 +1,11 @@ -from threading import Thread from queue import Queue +from threading import Thread import yt_dlp + from ... import downloads_dir -from ..utils import sanitize_filename from ..show_notification import show_notification +from ..utils import sanitize_filename class MyLogger: diff --git a/fastanime/Utility/user_data_helper.py b/fastanime/Utility/user_data_helper.py index 27582d5..1956c4f 100644 --- a/fastanime/Utility/user_data_helper.py +++ b/fastanime/Utility/user_data_helper.py @@ -6,7 +6,6 @@ from datetime import date, datetime from kivy.logger import Logger - today = date.today() now = datetime.now() diff --git a/fastanime/Utility/utils.py b/fastanime/Utility/utils.py index 57e0f7f..d27d564 100644 --- a/fastanime/Utility/utils.py +++ b/fastanime/Utility/utils.py @@ -1,7 +1,8 @@ import os +import re import shutil from datetime import datetime -import re + # TODO: make it use color_text instead of fixed vals # from .kivy_markup_helper import color_text diff --git a/fastanime/__init__.py b/fastanime/__init__.py index 6c167b4..1295467 100644 --- a/fastanime/__init__.py +++ b/fastanime/__init__.py @@ -1,11 +1,10 @@ +import logging import os import sys -import logging - -from rich import print -from rich.traceback import install import plyer +from rich import print +from rich.traceback import install install() # Create a logger instance @@ -55,7 +54,7 @@ def FastAnime(gui=False, log=False): handlers=[RichHandler()], # Use RichHandler to format the logs ) - print(f"Hello {os.environ.get("USERNAME")} from the fastanime team") + print(f"Hello {os.environ.get('USERNAME','User')} from the fastanime team") if gui: print(__name__) from .gui.gui import run_gui diff --git a/fastanime/__main__.py b/fastanime/__main__.py index 314102c..d5688d8 100644 --- a/fastanime/__main__.py +++ b/fastanime/__main__.py @@ -1,5 +1,5 @@ -import sys import os +import sys if __package__ is None and not getattr(sys, "frozen", False): # direct call of __main__.py diff --git a/fastanime/cli/__init__.py b/fastanime/cli/__init__.py index 14319d7..e126b88 100644 --- a/fastanime/cli/__init__.py +++ b/fastanime/cli/__init__.py @@ -1,6 +1,7 @@ import click from rich import print -from .commands import search, download, anilist + +from .commands import anilist, download, search commands = {"search": search, "download": download, "anilist": anilist} diff --git a/fastanime/cli/commands/__init__.py b/fastanime/cli/commands/__init__.py index a1dfaab..e69de29 100644 --- a/fastanime/cli/commands/__init__.py +++ b/fastanime/cli/commands/__init__.py @@ -1,3 +0,0 @@ -from .anilist import anilist -from .download import download -from .search import search diff --git a/fastanime/cli/commands/anilist/__init__.py b/fastanime/cli/commands/anilist/__init__.py index 3ff80da..48a8faf 100644 --- a/fastanime/cli/commands/anilist/__init__.py +++ b/fastanime/cli/commands/anilist/__init__.py @@ -1,13 +1,12 @@ import click from .favourites import favourites +from .popular import popular from .recent import recent from .search import search -from .popular import popular from .trending import trending from .upcoming import upcoming - commands = { "favourites": favourites, "recent": recent, diff --git a/fastanime/cli/commands/anilist/search.py b/fastanime/cli/commands/anilist/search.py index 3050040..e570281 100644 --- a/fastanime/cli/commands/anilist/search.py +++ b/fastanime/cli/commands/anilist/search.py @@ -1,7 +1,8 @@ import click + from ....libs.anilist.anilist import AniList -from .utils import get_search_result from ...interfaces.anime_interface import anime_interface +from .utils import get_search_result @click.command() diff --git a/fastanime/cli/commands/anilist/trending.py b/fastanime/cli/commands/anilist/trending.py index 4f82f0a..2c633c1 100644 --- a/fastanime/cli/commands/anilist/trending.py +++ b/fastanime/cli/commands/anilist/trending.py @@ -1,7 +1,8 @@ import click + from ....libs.anilist.anilist import AniList -from .utils import get_search_result from ...interfaces.anime_interface import anime_interface +from .utils import get_search_result @click.command() diff --git a/fastanime/cli/commands/anilist/utils.py b/fastanime/cli/commands/anilist/utils.py index 9cf0e6d..1bc414c 100644 --- a/fastanime/cli/commands/anilist/utils.py +++ b/fastanime/cli/commands/anilist/utils.py @@ -1,8 +1,8 @@ -from ...utils.fzf import fzf from ....libs.anilist.anilist_data_schema import ( - AnilistDataSchema, AnilistBaseMediaDataSchema, + AnilistDataSchema, ) +from ...utils.fzf import fzf def get_search_result( diff --git a/fastanime/cli/interfaces/__init__.py b/fastanime/cli/interfaces/__init__.py index 4901da0..653cb2d 100644 --- a/fastanime/cli/interfaces/__init__.py +++ b/fastanime/cli/interfaces/__init__.py @@ -1,6 +1,4 @@ -from .stream_interface import stream_interface -from .info_interface import info_interface -from .binge_interface import binge_interface -from .download_interface import download_interface -from .quit import bye -from .watchlist_interface import watchlist_interface +def bye(): + import sys + + sys.exit() diff --git a/fastanime/cli/interfaces/anime_interface.py b/fastanime/cli/interfaces/anime_interface.py index a00a85a..6cdea54 100644 --- a/fastanime/cli/interfaces/anime_interface.py +++ b/fastanime/cli/interfaces/anime_interface.py @@ -1,12 +1,11 @@ -import rich from ..utils.fzf import fzf from . import ( + binge_interface, + bye, + download_interface, info_interface, stream_interface, - binge_interface, - download_interface, watchlist_interface, - bye, ) options = { diff --git a/fastanime/cli/interfaces/binge_interface.py b/fastanime/cli/interfaces/binge_interface.py index 08c50fa..a0231bd 100644 --- a/fastanime/cli/interfaces/binge_interface.py +++ b/fastanime/cli/interfaces/binge_interface.py @@ -1,5 +1,2 @@ -from ..utils import fzf - - def binge_interface(anime, back): print(anime) diff --git a/fastanime/cli/interfaces/download_interface.py b/fastanime/cli/interfaces/download_interface.py index f91e3ec..568a553 100644 --- a/fastanime/cli/interfaces/download_interface.py +++ b/fastanime/cli/interfaces/download_interface.py @@ -1,5 +1,2 @@ -from ..utils import fzf - - def download_interface(anime, back): print(anime) diff --git a/fastanime/cli/interfaces/info_interface.py b/fastanime/cli/interfaces/info_interface.py index ad91fa9..03966c4 100644 --- a/fastanime/cli/interfaces/info_interface.py +++ b/fastanime/cli/interfaces/info_interface.py @@ -1,5 +1,2 @@ -from ..utils import fzf - - def info_interface(anime, back): print(anime) diff --git a/fastanime/cli/interfaces/quit.py b/fastanime/cli/interfaces/quit.py index 64cc97d..f89635a 100644 --- a/fastanime/cli/interfaces/quit.py +++ b/fastanime/cli/interfaces/quit.py @@ -1,4 +1,5 @@ import sys + from rich import print diff --git a/fastanime/cli/interfaces/stream_interface.py b/fastanime/cli/interfaces/stream_interface.py index ec03e55..71c9b1b 100644 --- a/fastanime/cli/interfaces/stream_interface.py +++ b/fastanime/cli/interfaces/stream_interface.py @@ -1,9 +1,11 @@ -from ..utils.fzf import fzf +import logging + +from fuzzywuzzy import fuzz + from ...libs.anime_provider.allanime.api import anime_provider from ...Utility.data import anime_normalizer +from ..utils.fzf import fzf from ..utils.mpv import mpv -from fuzzywuzzy import fuzz -import logging logger = logging.getLogger(__name__) diff --git a/fastanime/cli/interfaces/watchlist_interface.py b/fastanime/cli/interfaces/watchlist_interface.py index 8ab0364..cee2edf 100644 --- a/fastanime/cli/interfaces/watchlist_interface.py +++ b/fastanime/cli/interfaces/watchlist_interface.py @@ -1,5 +1,2 @@ -from ..utils import fzf - - def watchlist_interface(anime, back): print(anime) diff --git a/fastanime/cli/utils/fzf.py b/fastanime/cli/utils/fzf.py index 866ee88..9ae9f40 100644 --- a/fastanime/cli/utils/fzf.py +++ b/fastanime/cli/utils/fzf.py @@ -1,6 +1,6 @@ -import subprocess import logging import shutil +import subprocess logger = logging.getLogger(__name__) @@ -19,15 +19,17 @@ def fzf(options, prompt="Select Anime: ", *custom_commands): return None result = subprocess.run( - [ - FZF, - "--reverse", - "--cycle", - "--prompt", - prompt, - ] - if not custom_commands - else [FZF, *custom_commands], + ( + [ + FZF, + "--reverse", + "--cycle", + "--prompt", + prompt, + ] + if not custom_commands + else [FZF, *custom_commands] + ), input=options_str, text=True, stdout=subprocess.PIPE, diff --git a/fastanime/cli/utils/mpv.py b/fastanime/cli/utils/mpv.py index 50e8080..cae3d2e 100644 --- a/fastanime/cli/utils/mpv.py +++ b/fastanime/cli/utils/mpv.py @@ -1,5 +1,5 @@ -import subprocess import shutil +import subprocess import sys diff --git a/fastanime/gui/Controller/__init__.py b/fastanime/gui/Controller/__init__.py index c02ce2b..8b13789 100644 --- a/fastanime/gui/Controller/__init__.py +++ b/fastanime/gui/Controller/__init__.py @@ -1,5 +1 @@ -from .anime_screen import AnimeScreenController -from .downloads_screen import DownloadsScreenController -from .home_screen import HomeScreenController -from .my_list_screen import MyListScreenController -from .search_screen import SearchScreenController + diff --git a/fastanime/gui/Controller/anime_screen.py b/fastanime/gui/Controller/anime_screen.py index 6d129bd..abdd855 100644 --- a/fastanime/gui/Controller/anime_screen.py +++ b/fastanime/gui/Controller/anime_screen.py @@ -1,7 +1,7 @@ from kivy.cache import Cache -from ..Model import AnimeScreenModel -from ..View import AnimeScreenView +from ..Model.anime_screen import AnimeScreenModel +from ..View.AnimeScreen.anime_screen import AnimeScreenView Cache.register("data.anime", limit=20, timeout=600) @@ -33,3 +33,6 @@ class AnimeScreenController: self.fetch_streams(title) self.view.current_title = title self.view.caller_screen_name = caller_screen_name + + +__all__ = ["AnimeScreenController"] diff --git a/fastanime/gui/Controller/downloads_screen.py b/fastanime/gui/Controller/downloads_screen.py index da57abd..96b2d22 100644 --- a/fastanime/gui/Controller/downloads_screen.py +++ b/fastanime/gui/Controller/downloads_screen.py @@ -1,5 +1,5 @@ -from ..Model import DownloadsScreenModel -from ..View import DownloadsScreenView +from ..Model.download_screen import DownloadsScreenModel +from ..View.DownloadsScreen.download_screen import DownloadsScreenView class DownloadsScreenController: @@ -11,3 +11,6 @@ class DownloadsScreenController: def get_view(self) -> DownloadsScreenView: return self.view + + +__all__ = ["DownloadsScreenController"] diff --git a/fastanime/gui/Controller/home_screen.py b/fastanime/gui/Controller/home_screen.py index d54d565..25c06be 100644 --- a/fastanime/gui/Controller/home_screen.py +++ b/fastanime/gui/Controller/home_screen.py @@ -1,14 +1,12 @@ from inspect import isgenerator - from kivy.clock import Clock from kivy.logger import Logger - -from ..Model import HomeScreenModel -from ..Utility import show_notification -from ..View import HomeScreenView -from ..View.components import MediaCardsContainer +from ...Utility.show_notification import show_notification +from ..Model.home_screen import HomeScreenModel +from ..View.components.media_card.media_card import MediaCardsContainer +from ..View.HomeScreen.home_screen import HomeScreenView # TODO:Move the update home screen to homescreen.py @@ -141,3 +139,6 @@ class HomeScreenController: f"Theres probably a problem with your internet connection or anilist servers are down.\nFailed include:{', '.join(self.populate_errors)}", ) self.populate_errors = [] + + +__all__ = ["HomeScreenController"] diff --git a/fastanime/gui/Controller/my_list_screen.py b/fastanime/gui/Controller/my_list_screen.py index eac9627..0bf1790 100644 --- a/fastanime/gui/Controller/my_list_screen.py +++ b/fastanime/gui/Controller/my_list_screen.py @@ -1,13 +1,14 @@ from inspect import isgenerator from math import ceil + from kivy.logger import Logger # from kivy.clock import Clock from kivy.utils import difference -from ..Model import MyListScreenModel -from ..Utility import user_data_helper -from ..View import MyListScreenView +from ...Utility import user_data_helper +from ..Model.my_list_screen import MyListScreenModel +from ..View.MylistScreen.my_list_screen import MyListScreenView class MyListScreenController: @@ -44,3 +45,6 @@ class MyListScreenController: self.view.update_layout(result_card) self.model.already_in_user_anime_list = _user_anime_list return animes_to_add + + +__all__ = ["MyListScreenController"] diff --git a/fastanime/gui/Controller/search_screen.py b/fastanime/gui/Controller/search_screen.py index f159fff..4ef2984 100644 --- a/fastanime/gui/Controller/search_screen.py +++ b/fastanime/gui/Controller/search_screen.py @@ -3,8 +3,8 @@ from inspect import isgenerator from kivy.clock import Clock from kivy.logger import Logger -from ..Model import SearchScreenModel -from ..View import SearchScreenView +from ..Model.search_screen import SearchScreenModel +from ..View.SearchScreen.search_screen import SearchScreenView class SearchScreenController: @@ -43,3 +43,6 @@ class SearchScreenController: else: Logger.error(f"Home Screen:Failed to search for {anime_title}") self.view.is_searching = False + + +__all__ = ["SearchScreenController"] diff --git a/fastanime/gui/Model/__init__.py b/fastanime/gui/Model/__init__.py index b22905b..8b13789 100644 --- a/fastanime/gui/Model/__init__.py +++ b/fastanime/gui/Model/__init__.py @@ -1,5 +1 @@ -from .anime_screen import AnimeScreenModel -from .download_screen import DownloadsScreenModel -from .home_screen import HomeScreenModel -from .my_list_screen import MyListScreenModel -from .search_screen import SearchScreenModel + diff --git a/fastanime/gui/Model/anime_screen.py b/fastanime/gui/Model/anime_screen.py index 4751913..f2ea78b 100644 --- a/fastanime/gui/Model/anime_screen.py +++ b/fastanime/gui/Model/anime_screen.py @@ -2,10 +2,10 @@ from fuzzywuzzy import fuzz from kivy.cache import Cache from kivy.logger import Logger -from ..libs.anilist import AniList -from ..libs.anime_provider.allanime.api import anime_provider +from ...libs.anilist.anilist import AniList +from ...libs.anime_provider.allanime.api import anime_provider +from ...Utility.data import anime_normalizer from .base_model import BaseScreenModel -from ..Utility.data import anime_normalizer def anime_title_percentage_match( @@ -110,3 +110,6 @@ class AnimeScreenModel(BaseScreenModel): def get_anime_data(self, id: int): return AniList.get_anime(id) + + +__all__ = ["AnimeScreenModel"] diff --git a/fastanime/gui/Model/base_model.py b/fastanime/gui/Model/base_model.py index 554a4f4..a018c74 100644 --- a/fastanime/gui/Model/base_model.py +++ b/fastanime/gui/Model/base_model.py @@ -31,3 +31,6 @@ class BaseScreenModel: if observer.name == name_screen: observer.model_is_changed() break + + +__all__ = ["BaseScreenModel"] diff --git a/fastanime/gui/Model/download_screen.py b/fastanime/gui/Model/download_screen.py index 0ac76ad..d9994fb 100644 --- a/fastanime/gui/Model/download_screen.py +++ b/fastanime/gui/Model/download_screen.py @@ -19,3 +19,6 @@ class DownloadsScreenModel(BaseScreenModel): ) if d["status"] == "finished": print("Done downloading, now converting ...") + + +__all__ = ["DownloadsScreenModel"] diff --git a/fastanime/gui/Model/home_screen.py b/fastanime/gui/Model/home_screen.py index a55dd18..a63081e 100644 --- a/fastanime/gui/Model/home_screen.py +++ b/fastanime/gui/Model/home_screen.py @@ -1,4 +1,4 @@ -from ..libs.anilist import AniList +from ...libs.anilist.anilist import AniList from ..Utility.media_card_loader import media_card_loader from .base_model import BaseScreenModel @@ -77,3 +77,6 @@ class HomeScreenModel(BaseScreenModel): return _data_generator() else: return data + + +__all__ = ["HomeScreenModel"] diff --git a/fastanime/gui/Model/my_list_screen.py b/fastanime/gui/Model/my_list_screen.py index e145713..d5d9575 100644 --- a/fastanime/gui/Model/my_list_screen.py +++ b/fastanime/gui/Model/my_list_screen.py @@ -1,6 +1,6 @@ -from ..libs.anilist import AniList -from ..Utility import media_card_loader, show_notification - +from ...libs.anilist.anilist import AniList +from ...Utility.show_notification import show_notification +from ..Utility.media_card_loader import media_card_loader from .base_model import BaseScreenModel diff --git a/fastanime/gui/Model/search_screen.py b/fastanime/gui/Model/search_screen.py index 1765380..24e6c91 100644 --- a/fastanime/gui/Model/search_screen.py +++ b/fastanime/gui/Model/search_screen.py @@ -1,5 +1,6 @@ -from ..libs.anilist import AniList -from ..Utility import media_card_loader, show_notification +from ...libs.anilist.anilist import AniList +from ...Utility.show_notification import show_notification +from ..Utility.media_card_loader import media_card_loader from .base_model import BaseScreenModel @@ -31,3 +32,6 @@ class SearchScreenModel(BaseScreenModel): for anime_item in self.data["data"]["Page"]["media"]: yield media_card_loader.media_card(anime_item) self.pagination_info = self.data["data"]["Page"]["pageInfo"] + + +__all__ = ["SearchScreenModel"] diff --git a/fastanime/Utility/media_card_loader.py b/fastanime/gui/Utility/media_card_loader.py similarity index 94% rename from fastanime/Utility/media_card_loader.py rename to fastanime/gui/Utility/media_card_loader.py index 52edd6a..e83440b 100644 --- a/fastanime/Utility/media_card_loader.py +++ b/fastanime/gui/Utility/media_card_loader.py @@ -1,9 +1,9 @@ +import yt_dlp from kivy.cache import Cache from kivy.logger import Logger -import yt_dlp -from ..libs.anilist.anilist_data_schema import AnilistBaseMediaDataSchema -from ..Utility import anilist_data_helper, user_data_helper +from ...libs.anilist.anilist_data_schema import AnilistBaseMediaDataSchema +from ...Utility import anilist_data_helper, user_data_helper Cache.register("trailer_urls.anime", timeout=360) @@ -48,9 +48,9 @@ class MediaCardDataLoader(object): # TODO: switch to season and year # - media_card_data["first_aired_on"] = ( - f'{anilist_data_helper.format_anilist_date_object(anime_item["startDate"])}' - ) + media_card_data[ + "first_aired_on" + ] = f'{anilist_data_helper.format_anilist_date_object(anime_item["startDate"])}' media_card_data["studios"] = anilist_data_helper.format_list_data_with_comma( [ diff --git a/fastanime/gui/View/AnimeScreen/anime_screen.py b/fastanime/gui/View/AnimeScreen/anime_screen.py index 57d1830..1b4f856 100644 --- a/fastanime/gui/View/AnimeScreen/anime_screen.py +++ b/fastanime/gui/View/AnimeScreen/anime_screen.py @@ -1,5 +1,4 @@ from kivy.properties import ListProperty, ObjectProperty, StringProperty - from kivy.uix.widget import Factory from kivymd.uix.button import MDButton @@ -79,3 +78,6 @@ class AnimeScreenView(BaseScreenView): def add_to_user_anime_list(self, *args): self.app.add_anime_to_user_anime_list(self.model.anime_id) + + +__all__ = ["AnimeScreenView"] diff --git a/fastanime/gui/View/DownloadsScreen/components/task_card.py b/fastanime/gui/View/DownloadsScreen/components/task_card.py index c7ac5e5..89c0a77 100644 --- a/fastanime/gui/View/DownloadsScreen/components/task_card.py +++ b/fastanime/gui/View/DownloadsScreen/components/task_card.py @@ -1,4 +1,4 @@ -from kivy.properties import StringProperty, ListProperty +from kivy.properties import ListProperty, StringProperty from kivymd.uix.boxlayout import MDBoxLayout diff --git a/fastanime/gui/View/DownloadsScreen/download_screen.py b/fastanime/gui/View/DownloadsScreen/download_screen.py index d137166..72675ef 100644 --- a/fastanime/gui/View/DownloadsScreen/download_screen.py +++ b/fastanime/gui/View/DownloadsScreen/download_screen.py @@ -39,3 +39,7 @@ class DownloadsScreenView(BaseScreenView): # d["speed"], # d.get("percent"), # ) + # + + +__all__ = ["DownloadsScreenView"] diff --git a/fastanime/gui/View/HomeScreen/home_screen.py b/fastanime/gui/View/HomeScreen/home_screen.py index f346b7f..0b98702 100644 --- a/fastanime/gui/View/HomeScreen/home_screen.py +++ b/fastanime/gui/View/HomeScreen/home_screen.py @@ -5,3 +5,6 @@ from ...View.base_screen import BaseScreenView class HomeScreenView(BaseScreenView): main_container = ObjectProperty() + + +__all__ = ["HomeScreenView"] diff --git a/fastanime/gui/View/MylistScreen/my_list_screen.py b/fastanime/gui/View/MylistScreen/my_list_screen.py index 598becb..c7cef44 100644 --- a/fastanime/gui/View/MylistScreen/my_list_screen.py +++ b/fastanime/gui/View/MylistScreen/my_list_screen.py @@ -19,3 +19,6 @@ class MyListScreenView(BaseScreenView): def update_layout(self, widget): self.user_anime_list_container.data.append(widget) + + +__all__ = ["MyListScreenView"] diff --git a/fastanime/gui/View/SearchScreen/components/__init__.py b/fastanime/gui/View/SearchScreen/components/__init__.py index b102669..e69de29 100644 --- a/fastanime/gui/View/SearchScreen/components/__init__.py +++ b/fastanime/gui/View/SearchScreen/components/__init__.py @@ -1,3 +0,0 @@ -from .filters import Filters -from .pagination import SearchResultsPagination -from .trending_sidebar import TrendingAnimeSideBar \ No newline at end of file diff --git a/fastanime/gui/View/SearchScreen/search_screen.py b/fastanime/gui/View/SearchScreen/search_screen.py index 4b346b5..bc18231 100644 --- a/fastanime/gui/View/SearchScreen/search_screen.py +++ b/fastanime/gui/View/SearchScreen/search_screen.py @@ -2,8 +2,9 @@ from kivy.clock import Clock from kivy.properties import ObjectProperty, StringProperty from ...View.base_screen import BaseScreenView - -from .components import Filters, SearchResultsPagination, TrendingAnimeSideBar +from .components.filters import Filters +from .components.pagination import SearchResultsPagination +from .components.trending_sidebar import TrendingAnimeSideBar class SearchScreenView(BaseScreenView): @@ -46,9 +47,9 @@ class SearchScreenView(BaseScreenView): self.search_results_container.data.append(widget) def update_pagination(self, pagination_info): - self.search_results_pagination.current_page = self.current_page = ( - pagination_info["currentPage"] - ) + self.search_results_pagination.current_page = ( + self.current_page + ) = pagination_info["currentPage"] self.search_results_pagination.total_pages = self.total_pages = max( int(pagination_info["total"] / 30), 1 ) @@ -66,3 +67,6 @@ class SearchScreenView(BaseScreenView): def update_trending_sidebar(self, trending_anime): self.trending_anime_sidebar.data.append(trending_anime) + + +__all__ = ["SearchScreenView"] diff --git a/fastanime/gui/View/__init__.py b/fastanime/gui/View/__init__.py index 2fb097f..8b13789 100644 --- a/fastanime/gui/View/__init__.py +++ b/fastanime/gui/View/__init__.py @@ -1,6 +1 @@ -# screens -from .AnimeScreen.anime_screen import AnimeScreenView -from .DownloadsScreen.download_screen import DownloadsScreenView -from .HomeScreen.home_screen import HomeScreenView -from .MylistScreen.my_list_screen import MyListScreenView -from .SearchScreen.search_screen import SearchScreenView + diff --git a/fastanime/gui/View/base_screen.py b/fastanime/gui/View/base_screen.py index 879969b..f2d9737 100644 --- a/fastanime/gui/View/base_screen.py +++ b/fastanime/gui/View/base_screen.py @@ -6,7 +6,7 @@ from kivymd.uix.navigationrail import MDNavigationRail, MDNavigationRailItem from kivymd.uix.screen import MDScreen from kivymd.uix.tooltip import MDTooltip -from ..Utility.observer import Observer +from ...Utility.observer import Observer class NavRail(MDNavigationRail): @@ -69,7 +69,7 @@ class BaseScreenView(MDScreen, Observer): super().__init__(**kw) # Often you need to get access to the application object from the view # class. You can do this using this attribute. - from .. import FastAnime + from ...gui import FastAnime self.app: FastAnime = MDApp.get_running_app() # type: ignore # Adding a view class as observer. diff --git a/fastanime/gui/View/components/__init__.py b/fastanime/gui/View/components/__init__.py index e413fec..e69de29 100644 --- a/fastanime/gui/View/components/__init__.py +++ b/fastanime/gui/View/components/__init__.py @@ -1 +0,0 @@ -from .media_card import MediaCard,MediaCardsContainer diff --git a/fastanime/gui/View/components/media_card/__init__.py b/fastanime/gui/View/components/media_card/__init__.py index e413fec..e69de29 100644 --- a/fastanime/gui/View/components/media_card/__init__.py +++ b/fastanime/gui/View/components/media_card/__init__.py @@ -1 +0,0 @@ -from .media_card import MediaCard,MediaCardsContainer diff --git a/fastanime/gui/View/components/media_card/components/__init__.py b/fastanime/gui/View/components/media_card/components/__init__.py index 591be5d..e69de29 100644 --- a/fastanime/gui/View/components/media_card/components/__init__.py +++ b/fastanime/gui/View/components/media_card/components/__init__.py @@ -1,2 +0,0 @@ -from .media_player import MediaPopupVideoPlayer -from .media_popup import MediaPopup diff --git a/fastanime/gui/View/screens.py b/fastanime/gui/View/screens.py index c75195a..681288e 100644 --- a/fastanime/gui/View/screens.py +++ b/fastanime/gui/View/screens.py @@ -1,17 +1,13 @@ -from ..Controller import ( - AnimeScreenController, - DownloadsScreenController, - HomeScreenController, - MyListScreenController, - SearchScreenController, -) -from ..Model import ( - AnimeScreenModel, - DownloadsScreenModel, - HomeScreenModel, - MyListScreenModel, - SearchScreenModel, -) +from ..Controller.anime_screen import AnimeScreenController +from ..Controller.downloads_screen import DownloadsScreenController +from ..Controller.home_screen import HomeScreenController +from ..Controller.my_list_screen import MyListScreenController +from ..Controller.search_screen import SearchScreenController +from ..Model.anime_screen import AnimeScreenModel +from ..Model.download_screen import DownloadsScreenModel +from ..Model.home_screen import HomeScreenModel +from ..Model.my_list_screen import MyListScreenModel +from ..Model.search_screen import SearchScreenModel screens = { "home screen": { diff --git a/fastanime/gui/__init__.py b/fastanime/gui/__init__.py index e69de29..69b2d8b 100644 --- a/fastanime/gui/__init__.py +++ b/fastanime/gui/__init__.py @@ -0,0 +1,147 @@ +import os +import random + +from kivy.config import Config +from kivy.loader import Loader +from kivy.logger import Logger +from kivy.resources import resource_add_path, resource_find +from kivy.uix.screenmanager import FadeTransition, ScreenManager +from kivy.uix.settings import Settings, SettingsWithSidebar +from kivymd.app import MDApp + +from .. import assets_folder, configs_folder, downloads_dir +from ..libs.mpv.player import mpv_player +from ..Utility import user_data_helper +from ..Utility.data import themes_available +from ..Utility.downloader.downloader import downloader +from ..Utility.show_notification import show_notification +from .View.components.media_card.components.media_popup import MediaPopup +from .View.screens import screens + + +def setup_app(): + os.environ["KIVY_VIDEO"] = "ffpyplayer" # noqa: E402 + Config.set("graphics", "width", "1000") # noqa: E402 + Config.set("graphics", "minimum_width", "1000") # noqa: E402 + Config.set("kivy", "window_icon", resource_find("logo.ico")) # noqa: E402 + Config.write() # noqa: E402 + + Loader.num_workers = 5 + Loader.max_upload_per_frame = 10 + + resource_add_path(assets_folder) + resource_add_path(configs_folder) + + +class FastAnime(MDApp): + default_anime_image = resource_find(random.choice(["default_1.jpg", "default.jpg"])) + default_banner_image = resource_find(random.choice(["banner_1.jpg", "banner.jpg"])) + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.icon = resource_find("logo.png") + + self.load_all_kv_files(self.directory) + self.theme_cls.theme_style = "Dark" + self.theme_cls.primary_palette = "Lightcoral" + self.manager_screens = ScreenManager() + self.manager_screens.transition = FadeTransition() + + def build(self) -> ScreenManager: + self.settings_cls = SettingsWithSidebar + + self.generate_application_screens() + + if config := self.config: + if theme_color := config.get("Preferences", "theme_color"): + self.theme_cls.primary_palette = theme_color + if theme_style := config.get("Preferences", "theme_style"): + self.theme_cls.theme_style = theme_style + + self.anime_screen = self.manager_screens.get_screen("anime screen") + self.search_screen = self.manager_screens.get_screen("search screen") + self.download_screen = self.manager_screens.get_screen("downloads screen") + self.home_screen = self.manager_screens.get_screen("home screen") + return self.manager_screens + + def on_start(self, *args): + self.media_card_popup = MediaPopup() + + def generate_application_screens(self) -> None: + for i, name_screen in enumerate(screens.keys()): + model = screens[name_screen]["model"]() + controller = screens[name_screen]["controller"](model) + view = controller.get_view() + view.manager_screens = self.manager_screens + view.name = name_screen + self.manager_screens.add_widget(view) + + def build_config(self, config): + # General settings setup + config.setdefaults( + "Preferences", + { + "theme_color": "Cyan", + "theme_style": "Dark", + "downloads_dir": downloads_dir, + }, + ) + + def build_settings(self, settings: Settings): + settings.add_json_panel( + "Settings", self.config, resource_find("general_settings_panel.json") + ) + + def on_config_change(self, config, section, key, value): + # TODO: Change to match case + if section == "Preferences": + match key: + case "theme_color": + if value in themes_available: + self.theme_cls.primary_palette = value + else: + Logger.warning( + "AniXStream Settings: An invalid theme has been entered and will be ignored" + ) + config.set("Preferences", "theme_color", "Cyan") + config.write() + case "theme_style": + self.theme_cls.theme_style = value + + def on_stop(self): + pass + + def search_for_anime(self, search_field, **kwargs): + if self.manager_screens.current != "search screen": + self.manager_screens.current = "search screen" + self.search_screen.handle_search_for_anime(search_field, **kwargs) + + def add_anime_to_user_anime_list(self, id: int): + updated_list = user_data_helper.get_user_anime_list() + updated_list.append(id) + user_data_helper.update_user_anime_list(updated_list) + + def remove_anime_from_user_anime_list(self, id: int): + updated_list = user_data_helper.get_user_anime_list() + if updated_list.count(id): + updated_list.remove(id) + user_data_helper.update_user_anime_list(updated_list) + + def show_anime_screen(self, id: int, title, caller_screen_name: str): + self.manager_screens.current = "anime screen" + self.anime_screen.controller.update_anime_view(id, title, caller_screen_name) + + def play_on_mpv(self, anime_video_url: str): + if mpv_player.mpv_process: + mpv_player.stop_mpv() + mpv_player.run_mpv(anime_video_url) + + def download_anime_video(self, url: str, anime_title: tuple): + self.download_screen.new_download_task(anime_title) + show_notification("New Download", f"{anime_title[0]} episode: {anime_title[1]}") + progress_hook = self.download_screen.on_episode_download_progress + downloader.download_file(url, anime_title, progress_hook) + + +def run_gui(): + FastAnime().run() diff --git a/fastanime/gui/gui.py b/fastanime/gui/gui.py deleted file mode 100644 index b8c501a..0000000 --- a/fastanime/gui/gui.py +++ /dev/null @@ -1,151 +0,0 @@ -import os -import random - -from kivy.config import Config -from kivy.loader import Loader -from kivy.logger import Logger -from kivy.resources import resource_add_path, resource_find -from kivy.uix.screenmanager import FadeTransition, ScreenManager -from kivy.uix.settings import Settings, SettingsWithSidebar - -from kivymd.app import MDApp - -from ..Utility.show_notification import show_notification - -from .. import downloads_dir, assets_folder, configs_folder -from ..libs.mpv.player import mpv_player -from ..Utility import ( - themes_available, - user_data_helper, -) -from ..Utility.downloader.downloader import downloader -from .View.components.media_card.components.media_popup import MediaPopup -from .View.screens import screens - - -def setup_app(): - os.environ["KIVY_VIDEO"] = "ffpyplayer" # noqa: E402 - Config.set("graphics", "width", "1000") # noqa: E402 - Config.set("graphics", "minimum_width", "1000") # noqa: E402 - Config.set("kivy", "window_icon", resource_find("logo.ico")) # noqa: E402 - Config.write() # noqa: E402 - - Loader.num_workers = 5 - Loader.max_upload_per_frame = 10 - - resource_add_path(assets_folder) - resource_add_path(configs_folder) - - -class FastAnime(MDApp): - default_anime_image = resource_find(random.choice(["default_1.jpg", "default.jpg"])) - default_banner_image = resource_find(random.choice(["banner_1.jpg", "banner.jpg"])) - - def __init__(self, **kwargs): - super().__init__(**kwargs) - self.icon = resource_find("logo.png") - - self.load_all_kv_files(self.directory) - self.theme_cls.theme_style = "Dark" - self.theme_cls.primary_palette = "Lightcoral" - self.manager_screens = ScreenManager() - self.manager_screens.transition = FadeTransition() - - def build(self) -> ScreenManager: - self.settings_cls = SettingsWithSidebar - - self.generate_application_screens() - - if config := self.config: - if theme_color := config.get("Preferences", "theme_color"): - self.theme_cls.primary_palette = theme_color - if theme_style := config.get("Preferences", "theme_style"): - self.theme_cls.theme_style = theme_style - - self.anime_screen = self.manager_screens.get_screen("anime screen") - self.search_screen = self.manager_screens.get_screen("search screen") - self.download_screen = self.manager_screens.get_screen("downloads screen") - self.home_screen = self.manager_screens.get_screen("home screen") - return self.manager_screens - - def on_start(self, *args): - self.media_card_popup = MediaPopup() - - def generate_application_screens(self) -> None: - for i, name_screen in enumerate(screens.keys()): - model = screens[name_screen]["model"]() - controller = screens[name_screen]["controller"](model) - view = controller.get_view() - view.manager_screens = self.manager_screens - view.name = name_screen - self.manager_screens.add_widget(view) - - def build_config(self, config): - # General settings setup - config.setdefaults( - "Preferences", - { - "theme_color": "Cyan", - "theme_style": "Dark", - "downloads_dir": downloads_dir, - }, - ) - - def build_settings(self, settings: Settings): - settings.add_json_panel( - "Settings", self.config, resource_find("general_settings_panel.json") - ) - - def on_config_change(self, config, section, key, value): - # TODO: Change to match case - if section == "Preferences": - match key: - case "theme_color": - if value in themes_available: - self.theme_cls.primary_palette = value - else: - Logger.warning( - "AniXStream Settings: An invalid theme has been entered and will be ignored" - ) - config.set("Preferences", "theme_color", "Cyan") - config.write() - case "theme_style": - self.theme_cls.theme_style = value - - def on_stop(self): - pass - - def search_for_anime(self, search_field, **kwargs): - if self.manager_screens.current != "search screen": - self.manager_screens.current = "search screen" - self.search_screen.handle_search_for_anime(search_field, **kwargs) - - def add_anime_to_user_anime_list(self, id: int): - updated_list = user_data_helper.get_user_anime_list() - updated_list.append(id) - user_data_helper.update_user_anime_list(updated_list) - - def remove_anime_from_user_anime_list(self, id: int): - updated_list = user_data_helper.get_user_anime_list() - if updated_list.count(id): - updated_list.remove(id) - user_data_helper.update_user_anime_list(updated_list) - - def show_anime_screen(self, id: int, title, caller_screen_name: str): - self.manager_screens.current = "anime screen" - self.anime_screen.controller.update_anime_view(id, title, caller_screen_name) - - def play_on_mpv(self, anime_video_url: str): - if mpv_player.mpv_process: - mpv_player.stop_mpv() - mpv_player.run_mpv(anime_video_url) - - def download_anime_video(self, url: str, anime_title: tuple): - self.download_screen.new_download_task(anime_title) - show_notification("New Download", f"{anime_title[0]} episode: {anime_title[1]}") - progress_hook = self.download_screen.on_episode_download_progress - downloader.download_file(url, anime_title, progress_hook) - - -def run_gui(): - FastAnime().run() diff --git a/fastanime/libs/anilist/__init__.py b/fastanime/libs/anilist/__init__.py index 1fe87ca..17f4885 100644 --- a/fastanime/libs/anilist/__init__.py +++ b/fastanime/libs/anilist/__init__.py @@ -1,6 +1,3 @@ """ his module contains an abstraction for interaction with the anilist api making it easy and efficient """ - -from .anilist import AniList -from .anilist_data_schema import AnilistBaseMediaDataSchema diff --git a/fastanime/libs/anilist/anilist.py b/fastanime/libs/anilist/anilist.py index 2681ad7..c249995 100644 --- a/fastanime/libs/anilist/anilist.py +++ b/fastanime/libs/anilist/anilist.py @@ -4,21 +4,22 @@ This is the core module availing all the abstractions of the anilist api import requests +from .anilist_data_schema import AnilistDataSchema from .queries_graphql import ( + airing_schedule_query, + anime_characters_query, + anime_query, + anime_relations_query, most_favourite_query, - most_recently_updated_query, most_popular_query, - trending_query, + most_recently_updated_query, most_scored_query, recommended_query, search_query, - anime_characters_query, - anime_relations_query, - airing_schedule_query, + trending_query, upcoming_anime_query, - anime_query, ) -from .anilist_data_schema import AnilistDataSchema + # from kivy.network.urlrequest import UrlRequestRequests diff --git a/fastanime/libs/anime_provider/allanime/api.py b/fastanime/libs/anime_provider/allanime/api.py index 0df5939..99bf7b2 100644 --- a/fastanime/libs/anime_provider/allanime/api.py +++ b/fastanime/libs/anime_provider/allanime/api.py @@ -2,20 +2,18 @@ import json import logging import requests -from rich.progress import Progress from rich import print -from .gql_queries import ALLANIME_SHOW_GQL, ALLANIME_SEARCH_GQL, ALLANIME_EPISODES_GQL +from rich.progress import Progress + from .constants import ( + ALLANIME_API_ENDPOINT, ALLANIME_BASE, ALLANIME_REFERER, - ALLANIME_API_ENDPOINT, USER_AGENT, ) +from .data_types import AllAnimeEpisode, AllAnimeSearchResults +from .gql_queries import ALLANIME_EPISODES_GQL, ALLANIME_SEARCH_GQL, ALLANIME_SHOW_GQL from .utils import decode_hex_string -from .data_types import ( - AllAnimeEpisode, - AllAnimeSearchResults, -) Logger = logging.getLogger(__name__) @@ -156,6 +154,7 @@ if __name__ == "__main__": # lets see if it works :) import subprocess import sys + from .utils import run_fzf anime = input("Enter the anime name: ") diff --git a/fastanime/libs/anime_provider/allanime/utils.py b/fastanime/libs/anime_provider/allanime/utils.py index 1c8c323..0f6419b 100644 --- a/fastanime/libs/anime_provider/allanime/utils.py +++ b/fastanime/libs/anime_provider/allanime/utils.py @@ -1,7 +1,6 @@ import re import subprocess - # Dictionary to map hex values to characters hex_to_char = { "01": "9", diff --git a/fastanime/libs/mpv/player.py b/fastanime/libs/mpv/player.py index b8cd62b..84f702f 100644 --- a/fastanime/libs/mpv/player.py +++ b/fastanime/libs/mpv/player.py @@ -1,7 +1,7 @@ -from subprocess import Popen, PIPE, DEVNULL import os -import threading import shutil +import threading +from subprocess import DEVNULL, PIPE, Popen class MPVPlayer: diff --git a/poetry.lock b/poetry.lock index 1f67dc2..6eb13cc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -28,6 +28,21 @@ files = [ [package.dependencies] asyncgui = ">=0.6,<0.7" +[[package]] +name = "autoflake" +version = "2.3.1" +description = "Removes unused imports and unused variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "autoflake-2.3.1-py3-none-any.whl", hash = "sha256:3ae7495db9084b7b32818b4140e6dc4fc280b712fb414f5b8fe57b0a8e85a840"}, + {file = "autoflake-2.3.1.tar.gz", hash = "sha256:c98b75dc5b0a86459c4f01a1d32ac7eb4338ec4317a4469515ff1e687ecd909e"}, +] + +[package.dependencies] +pyflakes = ">=3.0.0" +tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} + [[package]] name = "black" version = "24.4.2" @@ -1149,6 +1164,17 @@ files = [ {file = "pycryptodomex-3.20.0.tar.gz", hash = "sha256:7a710b79baddd65b806402e14766c721aee8fb83381769c27920f26476276c1e"}, ] +[[package]] +name = "pyflakes" +version = "3.2.0" +description = "passive checker of Python programs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, + {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, +] + [[package]] name = "pygments" version = "2.18.0" @@ -1640,4 +1666,4 @@ test = ["pytest (>=8.1,<9.0)"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "16fcc1829bd365e509f0349614c06f367a57f3e21b22f53488853ada0330b136" +content-hash = "bf1db7c60cc63389fb818e8c9dbcec4b2b1d52a4b6c968d8c3459ebb31382852" diff --git a/pyproject.toml b/pyproject.toml index 44059e4..e8a0456 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ pytest = "^8.2.2" ruff = "^0.4.10" pre-commit = "^3.7.1" +autoflake = "^2.3.1" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" diff --git a/pyrightconfig.json b/pyrightconfig.json index 4703a54..3f13fc2 100644 --- a/pyrightconfig.json +++ b/pyrightconfig.json @@ -1,5 +1,3 @@ { - "venv": ".venv", - "venvPath": ".", "typeCheckingMode": "standard" }