Compare commits

..

11 Commits

Author SHA1 Message Date
Benex254
e79321ed50 chore: bump version 2024-08-19 13:05:03 +03:00
Benex254
f7b5898dfa fix: some stuff 2024-08-19 13:04:30 +03:00
Benex254
144bf53081 chore: bump version 2024-08-19 11:01:13 +03:00
Benex254
16dded9724 fix: inability to properly detect terminal 2024-08-19 10:51:39 +03:00
Benex254
c47b158bff fix: logging issue 2024-08-19 10:51:11 +03:00
Benex254
9a36e15d9d feat: intergrate subs to python-mpv based player 2024-08-19 10:37:04 +03:00
Benex254
d6b2bd7761 fix: ep title 2024-08-19 10:36:20 +03:00
Benex254
2346552dc4 fix: logging issue 2024-08-19 00:38:51 +03:00
Benex254
ba275055db fix: logging issue 2024-08-19 00:38:29 +03:00
Benex254
de4ddf2f3a chore: bump version 2024-08-19 00:21:48 +03:00
Benex254
9c94d824d1 fix: rearrange servers available 2024-08-19 00:21:16 +03:00
15 changed files with 120 additions and 104 deletions

View File

@@ -37,12 +37,12 @@ class AnimeProvider:
self.provider = provider
self.dynamic = dynamic
self.retries = retries
self.lazyload_provider()
self.lazyload_provider(self.provider)
def lazyload_provider(self):
def lazyload_provider(self, provider):
"""updates the current provider being used"""
_, anime_provider_cls_name = anime_sources[self.provider].split(".", 1)
package = f"fastanime.libs.anime_provider.{self.provider}"
_, anime_provider_cls_name = anime_sources[provider].split(".", 1)
package = f"fastanime.libs.anime_provider.{provider}"
provider_api = importlib.import_module(".api", package)
anime_provider = getattr(provider_api, anime_provider_cls_name)
self.anime_provider = anime_provider()
@@ -73,7 +73,7 @@ class AnimeProvider:
user_query, translation_type, nsfw, unknown
)
except Exception as e:
logging.error(e)
logger.error(e)
results = None
return results
@@ -95,7 +95,7 @@ class AnimeProvider:
try:
results = anime_provider.get_anime(anime_id)
except Exception as e:
logging.error(e)
logger.error(e)
results = None
return results
@@ -123,6 +123,6 @@ class AnimeProvider:
anime, episode, translation_type
)
except Exception as e:
logging.error(e)
logger.error(e)
results = None
return results # pyright:ignore

View File

@@ -6,7 +6,7 @@ if sys.version_info < (3, 10):
) # noqa: F541
__version__ = "v2.3.0"
__version__ = "v2.3.3"
APP_NAME = "FastAnime"
AUTHOR = "Benex254"

View File

@@ -192,7 +192,7 @@ def run_cli(
FORMAT = "%(message)s"
logging.basicConfig(
level="NOTSET", format=FORMAT, datefmt="[%X]", handlers=[RichHandler()]
level="debug", format=FORMAT, datefmt="[%X]", handlers=[RichHandler()]
)
logger = logging.getLogger(__name__)
logger.info("logging has been initialized")
@@ -209,6 +209,10 @@ def run_cli(
datefmt="[%d/%m/%Y@%H:%M:%S]",
filemode="w",
)
else:
import logging
logging.basicConfig(level=logging.CRITICAL)
if rich_traceback:
from rich.traceback import install

View File

@@ -21,7 +21,11 @@ from ...Utility.data import anime_normalizer
from ...Utility.utils import anime_title_percentage_match
from ..utils.mpv import run_mpv
from ..utils.tools import exit_app
from ..utils.utils import filter_by_quality, fuzzy_inquirer
from ..utils.utils import (
filter_by_quality,
fuzzy_inquirer,
move_preferred_subtitle_lang_to_top,
)
from .utils import aniskip
if TYPE_CHECKING:
@@ -113,7 +117,9 @@ def media_player_controls(
current_episode_number,
):
custom_args.extend(args)
subtitles = selected_server["subtitles"]
subtitles = move_preferred_subtitle_lang_to_top(
selected_server["subtitles"], config.sub_lang
)
if config.sync_play:
from ..utils.syncplay import SyncPlayer
@@ -126,30 +132,16 @@ def media_player_controls(
elif config.use_mpv_mod:
from ..utils.player import player
mpv = player.create_player(
player.create_player(
current_episode_stream_link,
config.anime_provider,
fastanime_runtime_state,
config,
selected_server["episode_title"],
start_time,
headers=selected_server["headers"],
subtitles=subtitles,
)
# TODO: implement custom aniskip
if custom_args and None:
chapters_file = custom_args[0].split("=", 1)
script_opts = custom_args[1].split("=", 1)
mpv._set_property("chapters-file", chapters_file[1])
mpv._set_property("script-opts", script_opts[1])
if not start_time == "0":
mpv.start = start_time
mpv.wait_until_playing()
if subtitles:
mpv.sub_add(
subtitles[0]["url"], "select", None, subtitles[0]["language"]
)
mpv.wait_for_shutdown()
mpv.terminate()
stop_time = player.last_stop_time
total_time = player.last_total_time
else:
@@ -510,6 +502,8 @@ def provider_anime_episode_servers_menu(
)
if start_time != "0" and episode_in_history == current_episode_number:
print("[green]Continuing from:[/] ", start_time)
else:
start_time = "0"
custom_args = []
if config.skip:
if args := aniskip(
@@ -517,7 +511,9 @@ def provider_anime_episode_servers_menu(
current_episode_number,
):
custom_args.extend(args)
subtitles = selected_server["subtitles"]
subtitles = move_preferred_subtitle_lang_to_top(
selected_server["subtitles"], config.sub_lang
)
if config.sync_play:
from ..utils.syncplay import SyncPlayer
@@ -530,32 +526,19 @@ def provider_anime_episode_servers_menu(
elif config.use_mpv_mod:
from ..utils.player import player
mpv = player.create_player(
if start_time == "0" and episode_in_history != current_episode_number:
start_time = "0"
player.create_player(
current_stream_link,
anime_provider,
fastanime_runtime_state,
config,
selected_server["episode_title"],
start_time,
headers=selected_server["headers"],
subtitles=subtitles,
)
# TODO: implement custom aniskip intergration
if custom_args and None:
chapters_file = custom_args[0].split("=", 1)
script_opts = custom_args[1].split("=", 1)
mpv._set_property("chapters-file", chapters_file[1])
mpv._set_property("script-opts", script_opts[1])
if not start_time == "0" and episode_in_history == current_episode_number:
mpv.start = start_time
mpv.wait_until_playing()
if subtitles:
# subs = ""
# for subtitle in subtitles:
# subs += f"{subtitle['url']},"
mpv.sub_add(subtitles[0]["url"], "select", None, subtitles[0]["language"])
# mpv.sub_files = subs
mpv.wait_for_shutdown()
mpv.terminate()
stop_time = player.last_stop_time
total_time = player.last_total_time
current_episode_number = fastanime_runtime_state.provider_current_episode_number
@@ -699,14 +682,14 @@ def provider_anime_episodes_menu(
if current_episode_number == "Back":
media_actions_menu(config, fastanime_runtime_state)
return
# try to get the start time and if not found default to "0"
start_time = user_watch_history.get(str(anime_id_anilist), {}).get(
"start_time", "0"
)
config.update_watch_history(
anime_id_anilist, current_episode_number, start_time=start_time
)
#
# # try to get the start time and if not found default to "0"
# start_time = user_watch_history.get(str(anime_id_anilist), {}).get(
# "start_time", "0"
# )
# config.update_watch_history(
# anime_id_anilist, current_episode_number, start_time=start_time
# )
# update runtime data
fastanime_runtime_state.provider_available_episodes = total_episodes
@@ -1140,7 +1123,9 @@ def media_actions_menu(
config: [TODO:description]
fastanime_runtime_state: [TODO:description]
"""
options = ["allanime", "animepahe"]
from ...libs.anime_provider import anime_sources
options = list(anime_sources.keys())
if config.use_fzf:
provider = fzf.run(
options, prompt="Select Translation Type:", header="Language Options"
@@ -1155,7 +1140,7 @@ def media_actions_menu(
config.provider = provider
config.anime_provider.provider = provider
config.anime_provider.lazyload_provider()
config.anime_provider.lazyload_provider(provider)
media_actions_menu(config, fastanime_runtime_state)
@@ -1445,6 +1430,9 @@ def fastanime_main_menu(
else:
config.load_config()
config.anime_provider.provider = config.provider
config.anime_provider.lazyload_provider(config.provider)
fastanime_main_menu(config, fastanime_runtime_state)
icons = config.icons

View File

@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
import mpv
from ...anilist import AniList
from .utils import filter_by_quality
from .utils import filter_by_quality, move_preferred_subtitle_lang_to_top
if TYPE_CHECKING:
from typing import Literal
@@ -22,6 +22,7 @@ def format_time(duration_in_secs: float):
class MpvPlayer(object):
anime_provider: "AnimeProvider"
config: "Config"
subs = []
mpv_player: "mpv.MPV"
last_stop_time: str = "0"
last_total_time: str = "0"
@@ -70,7 +71,7 @@ class MpvPlayer(object):
elif type == "reload":
if current_episode_number not in total_episodes:
self.mpv_player.show_text("Episode not available")
return
return None, None
self.mpv_player.show_text("Replaying Episode...")
elif type == "custom":
if not ep_no or ep_no not in total_episodes:
@@ -78,7 +79,7 @@ class MpvPlayer(object):
self.mpv_player.show_text(
f"Acceptable episodes are: {total_episodes}",
)
return
return None, None
self.mpv_player.show_text(f"Fetching episode {ep_no}")
current_episode_number = ep_no
@@ -113,14 +114,14 @@ class MpvPlayer(object):
)
if not episode_streams:
self.mpv_player.show_text("No streams were found")
return None
return None, None
# always select the first
if server == "top":
selected_server = next(episode_streams, None)
if not selected_server:
self.mpv_player.show_text("Sth went wrong when loading the episode")
return
return None, None
else:
episode_streams_dict = {
episode_stream["server"]: episode_stream
@@ -131,17 +132,20 @@ class MpvPlayer(object):
self.mpv_player.show_text(
f"Invalid server!!; servers available are: {episode_streams_dict.keys()}",
)
return None
return None, None
self.current_media_title = selected_server["episode_title"]
links = selected_server["links"]
stream_link_ = filter_by_quality(quality, links)
if not stream_link_:
self.mpv_player.show_text("Quality not found")
return
return None, None
self.mpv_player._set_property("start", "0")
stream_link = stream_link_["link"]
fastanime_runtime_state.provider_current_episode_stream_link = stream_link
self.subs = move_preferred_subtitle_lang_to_top(
selected_server["subtitles"], config.sub_lang
)
return stream_link
def create_player(
@@ -151,8 +155,11 @@ class MpvPlayer(object):
fastanime_runtime_state,
config: "Config",
title,
start_time,
headers={},
subtitles=[],
):
self.subs = subtitles
self.anime_provider = anime_provider
self.fastanime_runtime_state = fastanime_runtime_state
self.config = config
@@ -171,17 +178,6 @@ class MpvPlayer(object):
osc=True,
ytdl=True,
)
mpv_player.force_window = config.force_window
# mpv_player.cache = "yes"
# mpv_player.cache_pause = "no"
mpv_player.title = title
mpv_headers = ""
if headers:
for header_name, header_value in headers.items():
mpv_headers += f"{header_name}:{header_value},"
mpv_player.http_header_fields = mpv_headers
mpv_player.play(stream_link)
# -- events --
@mpv_player.event_callback("file-loaded")
@@ -190,6 +186,22 @@ class MpvPlayer(object):
self.player_fetching = False
if isinstance(d, float):
self.last_total_time = format_time(d)
try:
if not mpv_player.core_shutdown:
if self.subs:
for i, subtitle in enumerate(self.subs):
if i == 0:
flag = "select"
else:
flag = "auto"
mpv_player.sub_add(
subtitle["url"], flag, None, subtitle["language"]
)
self.subs = []
except mpv.ShutdownError:
pass
except Exception:
pass
@mpv_player.property_observer("time-pos")
def handle_time_start_update(*args):
@@ -218,7 +230,9 @@ class MpvPlayer(object):
def _next_episode():
url = self.get_episode("next")
if url:
mpv_player.loadfile(url, options=f"title={self.current_media_title}")
mpv_player.loadfile(
url,
)
mpv_player.title = self.current_media_title
@mpv_player.on_key_press("shift+p")
@@ -327,7 +341,23 @@ class MpvPlayer(object):
mpv_player.register_message_handler("select-quality", select_quality)
self.mpv_player = mpv_player
return mpv_player
mpv_player.force_window = config.force_window
# mpv_player.cache = "yes"
# mpv_player.cache_pause = "no"
mpv_player.title = title
mpv_headers = ""
if headers:
for header_name, header_value in headers.items():
mpv_headers += f"{header_name}:{header_value},"
mpv_player.http_header_fields = mpv_headers
mpv_player.play(stream_link)
if not start_time == "0":
mpv_player.start = start_time
mpv_player.wait_for_shutdown()
mpv_player.terminate()
player = MpvPlayer()

View File

@@ -15,25 +15,14 @@ class FastAnimeRuntimeState(dict):
def exit_app(exit_code=0, *args):
import os
import shutil
import sys
from rich.console import Console
from ...constants import APP_NAME, ICON_PATH, USER_NAME
def is_running_in_terminal():
try:
shutil.get_terminal_size()
return (
sys.stdin
and sys.stdin.isatty()
and sys.stdout.isatty()
and os.getenv("TERM") is not None
)
except OSError:
return False
if not is_running_in_terminal():
console = Console()
if not console.is_terminal:
from plyer import notification
notification.notify(
@@ -43,7 +32,6 @@ def exit_app(exit_code=0, *args):
title="Shutting down",
) # pyright:ignore
else:
from rich import print
print("Have a good day :smile:", USER_NAME)
console.clear()
console.print("Have a good day :smile:", USER_NAME)
sys.exit(exit_code)

View File

@@ -1,6 +1,6 @@
from .allanime.constants import SERVERS_AVAILABLE as ALLANIME_SERVERS
from .animepahe.constants import SERVERS_AVAILABLE as ANIMEPAHESERVERS
from .aniwatch.constants import SERVERS_AVAILABLE as ANIWATCHSERVERS
from .allanime import SERVERS_AVAILABLE as ALLANIME_SERVERS
from .animepahe import SERVERS_AVAILABLE as ANIMEPAHESERVERS
from .aniwatch import SERVERS_AVAILABLE as ANIWATCHSERVERS
anime_sources = {
"allanime": "api.AllAnimeAPI",

View File

@@ -0,0 +1 @@
SERVERS_AVAILABLE = ["sharepoint", "dropbox", "gogoanime", "weTransfer", "wixmp", "Yt"]

View File

@@ -4,4 +4,3 @@ ALLANIME_BASE = "allanime.day"
ALLANIME_REFERER = "https://allanime.to/"
ALLANIME_API_ENDPOINT = "https://api.{}/api/".format(ALLANIME_BASE)
USER_AGENT = random_user_agent()
SERVERS_AVAILABLE = ["sharepoint", "dropbox", "gogoanime", "weTransfer", "wixmp", "Yt"]

View File

@@ -0,0 +1 @@
SERVERS_AVAILABLE = ["kwik"]

View File

@@ -1,6 +1,5 @@
from yt_dlp.utils.networking import random_user_agent
SERVERS_AVAILABLE = ["kwik"]
USER_AGENT = random_user_agent()
ANIMEPAHE = "animepahe.ru"
ANIMEPAHE_BASE = f"https://{ANIMEPAHE}"

View File

@@ -0,0 +1 @@
SERVERS_AVAILABLE = ["HD1", "HD2", "StreamSB", "StreamTape"]

View File

@@ -12,7 +12,7 @@ from ..base_provider import AnimeProvider
from ..common import fetch_anime_info_from_bal
from ..mini_anilist import search_for_anime_with_anilist
from ..utils import give_random_quality
from .constants import SERVERS_AVAILABLE
from . import SERVERS_AVAILABLE
from .types import AniWatchStream
logger = logging.getLogger(__name__)
@@ -54,7 +54,13 @@ class AniWatchApi(AnimeProvider):
self.episodes_info = [
{
"id": episode["data-id"],
"title": f"{episode['title'] or ZORO['title']}; Episode {episode['data-number']}",
"title": (
(episode["title"] or "").replace(
f"Episode {episode['data-number']}", ""
)
or ZORO[aniwatch_id]["title"]
)
+ f"; Episode {episode['data-number']}",
"episode": episode["data-number"],
}
for episode in episodes_info_dicts

View File

@@ -1 +0,0 @@
SERVERS_AVAILABLE = ["HD1", "HD2", "StreamSB", "StreamTape"]

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "fastanime"
version = "2.3.0"
version = "2.3.3"
description = "A browser anime site experience from the terminal"
authors = ["Benextempest <benextempest@gmail.com>"]
license = "UNLICENSE"