Compare commits

..

8 Commits

Author SHA1 Message Date
Benex254
6eb28cfa3d feat(mpv): show feedback on toggle translation type 2024-08-14 20:43:26 +03:00
Benex254
542d39fa6a chore: bump version 2024-08-14 20:40:45 +03:00
Benex254
e5e328148f fix: failed quality selection 2024-08-14 20:39:58 +03:00
Benex254
cea1a67d64 chore: bump version 2024-08-14 20:07:35 +03:00
Benex254
97c6dc7968 feat(animepahe): make it random 2024-08-14 20:07:35 +03:00
Benex254
d97072e298 feat(anime_pahe): load all pages 2024-08-14 20:07:35 +03:00
Benex254
7cd246478e feat: improve error handling when fetching servers 2024-08-14 20:07:35 +03:00
BenedictX
8afe1df3a9 Update README.md 2024-08-13 20:57:16 +03:00
9 changed files with 92 additions and 15 deletions

View File

@@ -164,7 +164,8 @@ The only required external dependency, unless you won't be streaming, is [MPV](h
**Other external dependencies that will just make your experience better:** **Other external dependencies that will just make your experience better:**
- [fzf](https://github.com/junegunn/fzf) :fire: which is used as a better alternative to the ui. - [fzf](https://github.com/junegunn/fzf) 🔥 which is used as a better alternative to the ui.
- [rofi](https://github.com/davatorium/rofi) 🔥 which is used as another alternative ui + the the desktop entry ui
- [chafa](https://github.com/hpjansson/chafa) currently the best cross platform and cross terminal image viewer for the terminal. - [chafa](https://github.com/hpjansson/chafa) currently the best cross platform and cross terminal image viewer for the terminal.
- [icat](https://sw.kovidgoyal.net/kitty/kittens/icat/) an image viewer that only works in [kitty terminal](https://sw.kovidgoyal.net/kitty/), which is currently the best terminal in my opinion, and by far the best image renderer for the terminal thanks to kitty's terminal graphics protocol. Its terminal graphics is so op that you can [run a browser on it](https://github.com/chase/awrit?tab=readme-ov-file)!! - [icat](https://sw.kovidgoyal.net/kitty/kittens/icat/) an image viewer that only works in [kitty terminal](https://sw.kovidgoyal.net/kitty/), which is currently the best terminal in my opinion, and by far the best image renderer for the terminal thanks to kitty's terminal graphics protocol. Its terminal graphics is so op that you can [run a browser on it](https://github.com/chase/awrit?tab=readme-ov-file)!!
- [bash](https://www.gnu.org/software/bash/) is used as the preview script language. - [bash](https://www.gnu.org/software/bash/) is used as the preview script language.

View File

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

View File

@@ -112,7 +112,10 @@ def download(config: "Config", anime_title, episode_range, highest_priority):
if config.server == "top": if config.server == "top":
with Progress() as progress: with Progress() as progress:
progress.add_task("Fetching top server...", total=None) progress.add_task("Fetching top server...", total=None)
server = next(streams) server = next(streams, None)
if not server:
print("Sth went wrong when fetching the server")
continue
stream_link = filter_by_quality(config.quality, server["links"]) stream_link = filter_by_quality(config.quality, server["links"])
if not stream_link: if not stream_link:
print("Quality not found") print("Quality not found")

View File

@@ -130,7 +130,12 @@ def search(config: Config, anime_title: str, episode_range: str):
if config.server == "top": if config.server == "top":
with Progress() as progress: with Progress() as progress:
progress.add_task("Fetching top server...", total=None) progress.add_task("Fetching top server...", total=None)
server = next(streams) server = next(streams, None)
if not server:
print("Sth went wrong when fetching the episode")
input("Enter to continue")
stream_anime()
return
stream_link = filter_by_quality(config.quality, server["links"]) stream_link = filter_by_quality(config.quality, server["links"])
if not stream_link: if not stream_link:
print("Quality not found") print("Quality not found")

View File

@@ -366,7 +366,22 @@ def provider_anime_episode_servers_menu(
with Progress() as progress: with Progress() as progress:
progress.add_task("Fetching top server...", total=None) progress.add_task("Fetching top server...", total=None)
try: try:
selected_server = next(episode_streams_generator) selected_server = next(episode_streams_generator, None)
if not selected_server:
if config.use_rofi:
if Rofi.confirm("Sth went wrong enter to continue"):
provider_anime_episode_servers_menu(
config, fastanime_runtime_state
)
else:
exit_app(1)
else:
print("Sth went wrong")
input("Enter to continue...")
provider_anime_episode_servers_menu(
config, fastanime_runtime_state
)
return
server_name = "top" server_name = "top"
except Exception as e: except Exception as e:
print("Failed to get streams. Reason:", e) print("Failed to get streams. Reason:", e)

View File

@@ -117,7 +117,10 @@ class MpvPlayer(object):
# always select the first # always select the first
if server == "top": if server == "top":
selected_server = next(episode_streams) selected_server = next(episode_streams, None)
if not selected_server:
self.mpv_player.show_text("Sth went wrong when loading the episode")
return
else: else:
episode_streams_dict = { episode_streams_dict = {
episode_stream["server"]: episode_stream episode_stream["server"]: episode_stream
@@ -231,6 +234,7 @@ class MpvPlayer(object):
@mpv_player.on_key_press("shift+t") @mpv_player.on_key_press("shift+t")
def _toggle_translation_type(): def _toggle_translation_type():
translation_type = "sub" if config.translation_type == "dub" else "dub" translation_type = "sub" if config.translation_type == "dub" else "dub"
mpv_player.show_text("Changing translation type...")
anime = anime_provider.get_anime( anime = anime_provider.get_anime(
fastanime_runtime_state.provider_anime_search_result["id"], fastanime_runtime_state.provider_anime_search_result["id"],
fastanime_runtime_state.selected_anime_anilist, fastanime_runtime_state.selected_anime_anilist,

View File

@@ -19,7 +19,7 @@ BG_GREEN = "\033[48;2;120;233;12;m"
GREEN = "\033[38;2;45;24;45;m" GREEN = "\033[38;2;45;24;45;m"
def filter_by_quality(quality: str, stream_links: "list[EpisodeStream]"): def filter_by_quality(quality: str, stream_links: "list[EpisodeStream]", default=True):
"""Helper function used to filter a list of EpisodeStream objects to one that has a corresponding quality """Helper function used to filter a list of EpisodeStream objects to one that has a corresponding quality
Args: Args:
@@ -30,8 +30,20 @@ def filter_by_quality(quality: str, stream_links: "list[EpisodeStream]"):
an EpisodeStream object or None incase the quality was not found an EpisodeStream object or None incase the quality was not found
""" """
for stream_link in stream_links: for stream_link in stream_links:
if stream_link["quality"] == quality: q = float(quality)
Q = float(stream_link["quality"])
# some providers have inaccurate eg qualities 718 instead of 720
if Q < q + 80 and Q > q - 80:
return stream_link return stream_link
else:
if stream_links and default:
try:
print("Qualities were: ", stream_links)
print("Using default of quality: ", stream_links[0]["quality"])
return stream_links[0]
except Exception as e:
print(e)
return
def format_bytes_to_human(num_of_bytes: float, suffix: str = "B"): def format_bytes_to_human(num_of_bytes: float, suffix: str = "B"):

View File

@@ -1,7 +1,9 @@
import logging import logging
import random
import re import re
import shutil import shutil
import subprocess import subprocess
import time
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from yt_dlp.utils import ( from yt_dlp.utils import (
@@ -68,20 +70,55 @@ class AnimePaheApi(AnimeProvider):
return {} return {}
def get_anime(self, session_id: str, *args): def get_anime(self, session_id: str, *args):
page = 1
try: try:
anime_result: "AnimeSearchResult" = [ anime_result: "AnimeSearchResult" = [
anime anime
for anime in self.search_page["data"] for anime in self.search_page["data"]
if anime["session"] == session_id if anime["session"] == session_id
][0] ][0]
url = ( data: "AnimePaheAnimePage" = {} # pyright:ignore
f"{ANIMEPAHE_ENDPOINT}m=release&id={session_id}&sort=episode_asc&page=1"
url = f"{ANIMEPAHE_ENDPOINT}m=release&id={session_id}&sort=episode_asc&page={page}"
def _pages_loader(
url,
page,
):
response = self.session.get(url, headers=REQUEST_HEADERS)
if response.status_code == 200:
if not data:
data.update(response.json())
if ep_data := response.json().get("data"):
data["data"].extend(ep_data)
if data["next_page_url"]:
# TODO: Refine this
time.sleep(
random.choice(
[
0.25,
0.1,
0.5,
0.75,
1,
]
)
)
page += 1
url = f"{ANIMEPAHE_ENDPOINT}m=release&id={session_id}&sort=episode_asc&page={page}"
_pages_loader(
url,
page,
)
_pages_loader(
url,
page,
) )
response = self.session.get(url, headers=REQUEST_HEADERS)
if not response.status_code == 200: if not data:
return {} return {}
data: "AnimePaheAnimePage" = response.json() self.anime = data # pyright:ignore
self.anime = data
episodes = list(map(str, range(data["total"]))) episodes = list(map(str, range(data["total"])))
title = "" title = ""
return { return {

View File

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