mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-12 15:50:01 -08:00
chore:switch to poetry as build tool and package manager
This commit is contained in:
@@ -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
|
||||
- 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:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
args: [ --fix ]
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.10.0
|
||||
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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -6,7 +6,6 @@ from datetime import date, datetime
|
||||
|
||||
from kivy.logger import Logger
|
||||
|
||||
|
||||
today = date.today()
|
||||
now = datetime.now()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
from .anilist import anilist
|
||||
from .download import download
|
||||
from .search import search
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -1,5 +1,2 @@
|
||||
from ..utils import fzf
|
||||
|
||||
|
||||
def binge_interface(anime, back):
|
||||
print(anime)
|
||||
|
||||
@@ -1,5 +1,2 @@
|
||||
from ..utils import fzf
|
||||
|
||||
|
||||
def download_interface(anime, back):
|
||||
print(anime)
|
||||
|
||||
@@ -1,5 +1,2 @@
|
||||
from ..utils import fzf
|
||||
|
||||
|
||||
def info_interface(anime, back):
|
||||
print(anime)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import sys
|
||||
|
||||
from rich import print
|
||||
|
||||
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -1,5 +1,2 @@
|
||||
from ..utils import fzf
|
||||
|
||||
|
||||
def watchlist_interface(anime, back):
|
||||
print(anime)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import subprocess
|
||||
import logging
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -19,6 +19,7 @@ def fzf(options, prompt="Select Anime: ", *custom_commands):
|
||||
return None
|
||||
|
||||
result = subprocess.run(
|
||||
(
|
||||
[
|
||||
FZF,
|
||||
"--reverse",
|
||||
@@ -27,7 +28,8 @@ def fzf(options, prompt="Select Anime: ", *custom_commands):
|
||||
prompt,
|
||||
]
|
||||
if not custom_commands
|
||||
else [FZF, *custom_commands],
|
||||
else [FZF, *custom_commands]
|
||||
),
|
||||
input=options_str,
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import subprocess
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -31,3 +31,6 @@ class BaseScreenModel:
|
||||
if observer.name == name_screen:
|
||||
observer.model_is_changed()
|
||||
break
|
||||
|
||||
|
||||
__all__ = ["BaseScreenModel"]
|
||||
|
||||
@@ -19,3 +19,6 @@ class DownloadsScreenModel(BaseScreenModel):
|
||||
)
|
||||
if d["status"] == "finished":
|
||||
print("Done downloading, now converting ...")
|
||||
|
||||
|
||||
__all__ = ["DownloadsScreenModel"]
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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(
|
||||
[
|
||||
@@ -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"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from kivy.properties import StringProperty, ListProperty
|
||||
from kivy.properties import ListProperty, StringProperty
|
||||
from kivymd.uix.boxlayout import MDBoxLayout
|
||||
|
||||
|
||||
|
||||
@@ -39,3 +39,7 @@ class DownloadsScreenView(BaseScreenView):
|
||||
# d["speed"],
|
||||
# d.get("percent"),
|
||||
# )
|
||||
#
|
||||
|
||||
|
||||
__all__ = ["DownloadsScreenView"]
|
||||
|
||||
@@ -5,3 +5,6 @@ from ...View.base_screen import BaseScreenView
|
||||
|
||||
class HomeScreenView(BaseScreenView):
|
||||
main_container = ObjectProperty()
|
||||
|
||||
|
||||
__all__ = ["HomeScreenView"]
|
||||
|
||||
@@ -19,3 +19,6 @@ class MyListScreenView(BaseScreenView):
|
||||
|
||||
def update_layout(self, widget):
|
||||
self.user_anime_list_container.data.append(widget)
|
||||
|
||||
|
||||
__all__ = ["MyListScreenView"]
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
from .filters import Filters
|
||||
from .pagination import SearchResultsPagination
|
||||
from .trending_sidebar import TrendingAnimeSideBar
|
||||
@@ -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"]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
from .media_card import MediaCard,MediaCardsContainer
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
from .media_card import MediaCard,MediaCardsContainer
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
from .media_player import MediaPopupVideoPlayer
|
||||
from .media_popup import MediaPopup
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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: ")
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
|
||||
# Dictionary to map hex values to characters
|
||||
hex_to_char = {
|
||||
"01": "9",
|
||||
|
||||
@@ -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:
|
||||
|
||||
28
poetry.lock
generated
28
poetry.lock
generated
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
{
|
||||
"venv": ".venv",
|
||||
"venvPath": ".",
|
||||
"typeCheckingMode": "standard"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user