mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-08 22:00:38 -08:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de8b6b7f2f | ||
|
|
54e0942233 | ||
|
|
8ea0c121c2 | ||
|
|
eddaad64e7 | ||
|
|
43be7a52cf | ||
|
|
b689760a25 | ||
|
|
e53246b79b | ||
|
|
b0fc94cdc5 | ||
|
|
449f6c1e59 | ||
|
|
ab4734b79d | ||
|
|
93d0f6a1a5 | ||
|
|
19c75c48b2 | ||
|
|
5341b0a844 | ||
|
|
24e7e6a16b | ||
|
|
4b310e60b8 | ||
|
|
4d50cffd86 | ||
|
|
f6fedf0500 | ||
|
|
7b431450fe | ||
|
|
66b247330b | ||
|
|
c6b8cfc294 | ||
|
|
6895426d67 | ||
|
|
cc69dc35f6 | ||
|
|
ed81f37ae4 | ||
|
|
c6858b00c4 | ||
|
|
a44034a5d4 | ||
|
|
f768518721 |
15
.github/FUNDING.yml
vendored
15
.github/FUNDING.yml
vendored
@@ -1,15 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: benexl # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: benexl # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
polar: # Replace with a single Polar username
|
||||
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
|
||||
thanks_dev: # Replace with a single thanks.dev username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
5
.github/workflows/test.yml
vendored
5
.github/workflows/test.yml
vendored
@@ -22,6 +22,11 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install dbus-python build dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install libdbus-1-dev libglib2.0-dev
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
|
||||
71
README.md
71
README.md
@@ -1,3 +1,15 @@
|
||||
>[!IMPORTANT]
|
||||
> looking for a new project name
|
||||
>
|
||||
>if you have any that is not already being used by someone on pypi please share on discord
|
||||
>
|
||||
>and let me warn yah am not good at naming things so help before disaster strikes again lol
|
||||
>
|
||||
>i dont want it to end up like viu where i added cli lol since viu was taken
|
||||
>
|
||||
>
|
||||
|
||||
|
||||
<p align="center">
|
||||
<h1 align="center">Viu</h1>
|
||||
</p>
|
||||
@@ -8,8 +20,8 @@
|
||||
</p>
|
||||
<div align="center">
|
||||
|
||||
[](https://pypi.org/project/viu_cli/)
|
||||
[](https://pypi.org/project/viu_cli/)
|
||||
[](https://pypi.org/project/viu-media/)
|
||||
[](https://pypi.org/project/viu-media/)
|
||||
[](https://github.com/Benexl/Viu/actions)
|
||||
[](https://discord.gg/HBEmAwvbHV)
|
||||
[](https://github.com/Benexl/Viu/issues)
|
||||
@@ -23,47 +35,6 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<b>Screenshots</b>
|
||||
</summary>
|
||||
<b>Fzf:</b>
|
||||
<img width="1346" height="710" alt="250815_13h29m15s_screenshot" src="https://github.com/user-attachments/assets/d8fb8473-a0fe-47b1-b112-5cd8bec51937" />
|
||||
<img width="1346" height="710" alt="250815_13h29m43s_screenshot" src="https://github.com/user-attachments/assets/16a2555d-f81e-4044-9e65-e61205dfe899" />
|
||||
<img width="1346" height="710" alt="250815_13h30m09s_screenshot" src="https://github.com/user-attachments/assets/f521670a-c04f-4f5e-a62a-6c849fbf49bd" />
|
||||
<img width="1346" height="710" alt="250815_13h30m33s_screenshot" src="https://github.com/user-attachments/assets/27fd2ef9-ec1f-4677-b816-038eaaca1391" />
|
||||
<img width="1346" height="710" alt="250815_13h31m07s_screenshot" src="https://github.com/user-attachments/assets/6a64aa99-507e-449a-9e4a-9daa4fe496a3" />
|
||||
<img width="1346" height="710" alt="250815_13h31m44s_screenshot" src="https://github.com/user-attachments/assets/a2896d1f-0e23-4ff3-b0c6-121d21a9f99a" />
|
||||
|
||||
<b>Rofi:</b>
|
||||
<img width="1366" height="729" alt="250815_13h23m12s_screenshot" src="https://github.com/user-attachments/assets/6d18d950-11e5-41fc-a7fe-1f9eaa481e46" />
|
||||
<img width="1366" height="765" alt="250815_13h24m09s_screenshot" src="https://github.com/user-attachments/assets/af852fee-17bf-4f24-ada9-7cf0e6f3451c" />
|
||||
<img width="1366" height="768" alt="250815_13h24m57s_screenshot" src="https://github.com/user-attachments/assets/d3b4e2ab-10bd-40ae-88ed-0720b57957c1" />
|
||||
<img width="1366" height="735" alt="250815_13h26m47s_screenshot" src="https://github.com/user-attachments/assets/64682b09-c88e-4d4c-ae26-a3aa34dd08a1" />
|
||||
<img width="1366" height="768" alt="250815_13h28m05s_screenshot" src="https://github.com/user-attachments/assets/d6cd6931-0113-462c-86bb-abe6f3e12d68" />
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<b>Riced Preview Examples</b>
|
||||
</summary>
|
||||
|
||||
**Anilist Results Menu (FZF):**
|
||||

|
||||
|
||||
**Episodes Menu with Preview (FZF):**
|
||||

|
||||
|
||||
**No Image Preview Mode:**
|
||||

|
||||
|
||||
**Desktop Notifications + Episodes Menu:**
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
## Core Features
|
||||
|
||||
@@ -98,13 +69,13 @@ The best way to install Viu is with [**uv**](https://github.com/astral-sh/uv), a
|
||||
|
||||
```bash
|
||||
# Install with all optional features for the full experience
|
||||
uv tool install "viu_cli[standard]"
|
||||
uv tool install "viu-media[standard]"
|
||||
|
||||
# Or, pick and choose the extras you need:
|
||||
uv tool install viu_cli # Core functionality only
|
||||
uv tool install "viu_cli[download]" # For advanced downloading with yt-dlp
|
||||
uv tool install "viu_cli[discord]" # For Discord Rich Presence
|
||||
uv tool install "viu_cli[notifications]" # For desktop notifications
|
||||
uv tool install viu-media # Core functionality only
|
||||
uv tool install "viu-media[download]" # For advanced downloading with yt-dlp
|
||||
uv tool install "viu-media[discord]" # For Discord Rich Presence
|
||||
uv tool install "viu-media[notifications]" # For desktop notifications
|
||||
```
|
||||
|
||||
### Other Installation Methods
|
||||
@@ -129,12 +100,12 @@ uv tool install "viu_cli[notifications]" # For desktop notifications
|
||||
|
||||
#### Using pipx (for isolated environments)
|
||||
```bash
|
||||
pipx install "viu_cli[standard]"
|
||||
pipx install "viu-media[standard]"
|
||||
```
|
||||
|
||||
#### Using pip
|
||||
```bash
|
||||
pip install "viu_cli[standard]"
|
||||
pip install "viu-media[standard]"
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
@@ -67,8 +67,6 @@
|
||||
# Needs to be adapted for the nix derivation build
|
||||
doCheck = false;
|
||||
|
||||
pythonImportsCheck = [ "viu" ];
|
||||
|
||||
meta = {
|
||||
description = "Your browser anime experience from the terminal";
|
||||
homepage = "https://github.com/Benexl/Viu";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "viu_cli"
|
||||
version = "3.2.6"
|
||||
name = "viu-media"
|
||||
version = "3.2.7"
|
||||
description = "A browser anime site experience from the terminal"
|
||||
license = "UNLICENSE"
|
||||
readme = "README.md"
|
||||
@@ -14,7 +14,7 @@ dependencies = [
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
viu = 'viu_cli:Cli'
|
||||
viu = 'viu_media:Cli'
|
||||
|
||||
[project.optional-dependencies]
|
||||
standard = [
|
||||
|
||||
2
fa → viu
2
fa → viu
@@ -3,4 +3,4 @@ provider_type=$1
|
||||
provider_name=$2
|
||||
[ -z "$provider_type" ] && echo "Please specify provider type" && exit
|
||||
[ -z "$provider_name" ] && echo "Please specify provider type" && exit
|
||||
uv run python -m viu_cli.libs.provider.${provider_type}.${provider_name}.provider
|
||||
uv run python -m viu_media.libs.provider.${provider_type}.${provider_name}.provider
|
||||
@@ -1,85 +0,0 @@
|
||||
from enum import Enum
|
||||
from typing import Dict, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from ...libs.media_api.params import MediaSearchParams, UserMediaListSearchParams
|
||||
from ...libs.media_api.types import MediaItem, PageInfo
|
||||
from ...libs.provider.anime.types import Anime, SearchResults, Server
|
||||
|
||||
|
||||
# TODO: is internal directive a good name
|
||||
class InternalDirective(Enum):
|
||||
MAIN = "MAIN"
|
||||
|
||||
BACK = "BACK"
|
||||
|
||||
BACKX2 = "BACKX2"
|
||||
|
||||
BACKX3 = "BACKX3"
|
||||
|
||||
BACKX4 = "BACKX4"
|
||||
|
||||
EXIT = "EXIT"
|
||||
|
||||
CONFIG_EDIT = "CONFIG_EDIT"
|
||||
|
||||
RELOAD = "RELOAD"
|
||||
|
||||
|
||||
class MenuName(Enum):
|
||||
MAIN = "MAIN"
|
||||
AUTH = "AUTH"
|
||||
EPISODES = "EPISODES"
|
||||
RESULTS = "RESULTS"
|
||||
SERVERS = "SERVERS"
|
||||
WATCH_HISTORY = "WATCH_HISTORY"
|
||||
PROVIDER_SEARCH = "PROVIDER_SEARCH"
|
||||
PLAYER_CONTROLS = "PLAYER_CONTROLS"
|
||||
USER_MEDIA_LIST = "USER_MEDIA_LIST"
|
||||
SESSION_MANAGEMENT = "SESSION_MANAGEMENT"
|
||||
MEDIA_ACTIONS = "MEDIA_ACTIONS"
|
||||
DOWNLOADS = "DOWNLOADS"
|
||||
DYNAMIC_SEARCH = "DYNAMIC_SEARCH"
|
||||
MEDIA_REVIEW = "MEDIA_REVIEW"
|
||||
MEDIA_CHARACTERS = "MEDIA_CHARACTERS"
|
||||
MEDIA_AIRING_SCHEDULE = "MEDIA_AIRING_SCHEDULE"
|
||||
PLAY_DOWNLOADS = "PLAY_DOWNLOADS"
|
||||
DOWNLOADS_PLAYER_CONTROLS = "DOWNLOADS_PLAYER_CONTROLS"
|
||||
DOWNLOAD_EPISODES = "DOWNLOAD_EPISODES"
|
||||
|
||||
|
||||
class StateModel(BaseModel):
|
||||
model_config = ConfigDict(frozen=True)
|
||||
|
||||
|
||||
class MediaApiState(StateModel):
|
||||
search_result: Optional[Dict[int, MediaItem]] = None
|
||||
search_params: Optional[Union[MediaSearchParams, UserMediaListSearchParams]] = None
|
||||
page_info: Optional[PageInfo] = None
|
||||
media_id: Optional[int] = None
|
||||
|
||||
@property
|
||||
def media_item(self) -> Optional[MediaItem]:
|
||||
if self.search_result and self.media_id:
|
||||
return self.search_result[self.media_id]
|
||||
|
||||
|
||||
class ProviderState(StateModel):
|
||||
search_results: Optional[SearchResults] = None
|
||||
anime: Optional[Anime] = None
|
||||
episode: Optional[str] = None
|
||||
servers: Optional[Dict[str, Server]] = None
|
||||
server_name: Optional[str] = None
|
||||
start_time: Optional[str] = None
|
||||
|
||||
@property
|
||||
def server(self) -> Optional[Server]:
|
||||
if self.servers and self.server_name:
|
||||
return self.servers[self.server_name]
|
||||
|
||||
|
||||
class State(StateModel):
|
||||
menu_name: MenuName
|
||||
provider: ProviderState = Field(default_factory=ProviderState)
|
||||
media_api: MediaApiState = Field(default_factory=MediaApiState)
|
||||
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 276 KiB After Width: | Height: | Size: 276 KiB |
@@ -44,7 +44,7 @@ commands = {
|
||||
|
||||
@click.group(
|
||||
cls=LazyGroup,
|
||||
root="viu_cli.cli.commands",
|
||||
root="viu_media.cli.commands",
|
||||
invoke_without_command=True,
|
||||
lazy_subcommands=commands,
|
||||
context_settings=dict(auto_envvar_prefix=PROJECT_NAME),
|
||||
@@ -18,7 +18,7 @@ commands = {
|
||||
@click.group(
|
||||
cls=LazyGroup,
|
||||
name="anilist",
|
||||
root="viu_cli.cli.commands.anilist.commands",
|
||||
root="viu_media.cli.commands.anilist.commands",
|
||||
invoke_without_command=True,
|
||||
help="A beautiful interface that gives you access to a commplete streaming experience",
|
||||
short_help="Access all streaming options",
|
||||
@@ -45,7 +45,9 @@ def auth(config: AppConfig, status: bool, logout: bool):
|
||||
open_success = webbrowser.open(ANILIST_AUTH, new=2)
|
||||
if open_success:
|
||||
feedback.info("Your browser has been opened to obtain an AniList token.")
|
||||
feedback.info(f"or you can visit the site manually [magenta][link={ANILIST_AUTH}]here[/link][/magenta].")
|
||||
feedback.info(
|
||||
f"or you can visit the site manually [magenta][link={ANILIST_AUTH}]here[/link][/magenta]."
|
||||
)
|
||||
else:
|
||||
feedback.warning(
|
||||
f"Failed to open the browser. Please visit the site manually [magenta][link={ANILIST_AUTH}]here[/link][/magenta]."
|
||||
@@ -1,10 +1,10 @@
|
||||
from typing import TYPE_CHECKING, Dict, List
|
||||
|
||||
import click
|
||||
from viu_cli.cli.utils.completion import anime_titles_shell_complete
|
||||
from viu_cli.core.config import AppConfig
|
||||
from viu_cli.core.exceptions import ViuError
|
||||
from viu_cli.libs.media_api.types import (
|
||||
from viu_media.cli.utils.completion import anime_titles_shell_complete
|
||||
from viu_media.core.config import AppConfig
|
||||
from viu_media.core.exceptions import ViuError
|
||||
from viu_media.libs.media_api.types import (
|
||||
MediaFormat,
|
||||
MediaGenre,
|
||||
MediaItem,
|
||||
@@ -112,15 +112,15 @@ if TYPE_CHECKING:
|
||||
)
|
||||
@click.pass_obj
|
||||
def download(config: AppConfig, **options: "Unpack[DownloadOptions]"):
|
||||
from viu_cli.cli.service.download.service import DownloadService
|
||||
from viu_cli.cli.service.feedback import FeedbackService
|
||||
from viu_cli.cli.service.registry import MediaRegistryService
|
||||
from viu_cli.cli.service.watch_history import WatchHistoryService
|
||||
from viu_cli.cli.utils.parser import parse_episode_range
|
||||
from viu_cli.libs.media_api.api import create_api_client
|
||||
from viu_cli.libs.media_api.params import MediaSearchParams
|
||||
from viu_cli.libs.provider.anime.provider import create_provider
|
||||
from viu_cli.libs.selectors import create_selector
|
||||
from viu_media.cli.service.download.service import DownloadService
|
||||
from viu_media.cli.service.feedback import FeedbackService
|
||||
from viu_media.cli.service.registry import MediaRegistryService
|
||||
from viu_media.cli.service.watch_history import WatchHistoryService
|
||||
from viu_media.cli.utils.parser import parse_episode_range
|
||||
from viu_media.libs.media_api.api import create_api_client
|
||||
from viu_media.libs.media_api.params import MediaSearchParams
|
||||
from viu_media.libs.provider.anime.provider import create_provider
|
||||
from viu_media.libs.selectors import create_selector
|
||||
from rich.progress import Progress
|
||||
|
||||
feedback = FeedbackService(config)
|
||||
@@ -1,5 +1,4 @@
|
||||
import json
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import click
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import click
|
||||
from viu_cli.core.config import AppConfig
|
||||
from viu_media.core.config import AppConfig
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
|
||||
@@ -11,8 +11,8 @@ def notifications(config: AppConfig):
|
||||
Displays unread notifications from AniList.
|
||||
Running this command will also mark the notifications as read on the AniList website.
|
||||
"""
|
||||
from viu_cli.cli.service.feedback import FeedbackService
|
||||
from viu_cli.libs.media_api.api import create_api_client
|
||||
from viu_media.cli.service.feedback import FeedbackService
|
||||
from viu_media.libs.media_api.api import create_api_client
|
||||
|
||||
from ....service.auth import AuthService
|
||||
|
||||
@@ -251,18 +251,14 @@ def search(config: AppConfig, **options: "Unpack[SearchOptions]"):
|
||||
and start_date_lesser is not None
|
||||
and start_date_greater > start_date_lesser
|
||||
):
|
||||
raise ViuError(
|
||||
"Start date greater cannot be later than start date lesser"
|
||||
)
|
||||
raise ViuError("Start date greater cannot be later than start date lesser")
|
||||
|
||||
if (
|
||||
end_date_greater is not None
|
||||
and end_date_lesser is not None
|
||||
and end_date_greater > end_date_lesser
|
||||
):
|
||||
raise ViuError(
|
||||
"End date greater cannot be later than end date lesser"
|
||||
)
|
||||
raise ViuError("End date greater cannot be later than end date lesser")
|
||||
|
||||
# Build search parameters
|
||||
search_params = MediaSearchParams(
|
||||
@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
|
||||
import click
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from viu_cli.core.config import AppConfig
|
||||
from viu_media.core.config import AppConfig
|
||||
|
||||
|
||||
@click.command(help="Print out your anilist stats")
|
||||
@@ -11,7 +11,7 @@ if TYPE_CHECKING:
|
||||
from pathlib import Path
|
||||
from typing import TypedDict
|
||||
|
||||
from viu_cli.cli.service.feedback.service import FeedbackService
|
||||
from viu_media.cli.service.feedback.service import FeedbackService
|
||||
from typing_extensions import Unpack
|
||||
|
||||
from ...libs.provider.anime.base import BaseAnimeProvider
|
||||
@@ -103,7 +103,7 @@ if TYPE_CHECKING:
|
||||
)
|
||||
@click.pass_obj
|
||||
def download(config: AppConfig, **options: "Unpack[Options]"):
|
||||
from viu_cli.cli.service.feedback.service import FeedbackService
|
||||
from viu_media.cli.service.feedback.service import FeedbackService
|
||||
|
||||
from ...core.exceptions import ViuError
|
||||
from ...libs.provider.anime.params import (
|
||||
@@ -1,7 +1,7 @@
|
||||
import click
|
||||
from viu_cli.core.config import AppConfig
|
||||
from viu_cli.core.exceptions import ViuError
|
||||
from viu_cli.libs.media_api.types import (
|
||||
from viu_media.core.config import AppConfig
|
||||
from viu_media.core.exceptions import ViuError
|
||||
from viu_media.libs.media_api.types import (
|
||||
MediaFormat,
|
||||
MediaGenre,
|
||||
MediaItem,
|
||||
@@ -33,8 +33,12 @@ from viu_cli.libs.media_api.types import (
|
||||
@click.option(
|
||||
"--genres-not", multiple=True, type=click.Choice([g.value for g in MediaGenre])
|
||||
)
|
||||
@click.option("--tags", "-T", multiple=True, type=click.Choice([t.value for t in MediaTag]))
|
||||
@click.option("--tags-not", multiple=True, type=click.Choice([t.value for t in MediaTag]))
|
||||
@click.option(
|
||||
"--tags", "-T", multiple=True, type=click.Choice([t.value for t in MediaTag])
|
||||
)
|
||||
@click.option(
|
||||
"--tags-not", multiple=True, type=click.Choice([t.value for t in MediaTag])
|
||||
)
|
||||
@click.option(
|
||||
"--media-format",
|
||||
"-f",
|
||||
@@ -72,14 +76,14 @@ def queue(config: AppConfig, **options):
|
||||
and queue the specified episode range for background download.
|
||||
The background worker should be running to process the queue.
|
||||
"""
|
||||
from viu_cli.cli.service.download.service import DownloadService
|
||||
from viu_cli.cli.service.feedback import FeedbackService
|
||||
from viu_cli.cli.service.registry import MediaRegistryService
|
||||
from viu_cli.cli.utils.parser import parse_episode_range
|
||||
from viu_cli.libs.media_api.params import MediaSearchParams
|
||||
from viu_cli.libs.media_api.api import create_api_client
|
||||
from viu_cli.libs.provider.anime.provider import create_provider
|
||||
from viu_cli.libs.selectors import create_selector
|
||||
from viu_media.cli.service.download.service import DownloadService
|
||||
from viu_media.cli.service.feedback import FeedbackService
|
||||
from viu_media.cli.service.registry import MediaRegistryService
|
||||
from viu_media.cli.utils.parser import parse_episode_range
|
||||
from viu_media.libs.media_api.params import MediaSearchParams
|
||||
from viu_media.libs.media_api.api import create_api_client
|
||||
from viu_media.libs.provider.anime.provider import create_provider
|
||||
from viu_media.libs.selectors import create_selector
|
||||
from rich.progress import Progress
|
||||
|
||||
feedback = FeedbackService(config)
|
||||
@@ -13,7 +13,7 @@ commands = {
|
||||
@click.group(
|
||||
cls=LazyGroup,
|
||||
name="queue",
|
||||
root="viu_cli.cli.commands.queue.commands",
|
||||
root="viu_media.cli.commands.queue.commands",
|
||||
invoke_without_command=False,
|
||||
help="Manage the download queue (add, list, resume, clear).",
|
||||
short_help="Manage the download queue.",
|
||||
@@ -1,7 +1,7 @@
|
||||
import click
|
||||
from viu_cli.core.config import AppConfig
|
||||
from viu_cli.core.exceptions import ViuError
|
||||
from viu_cli.libs.media_api.types import (
|
||||
from viu_media.core.config import AppConfig
|
||||
from viu_media.core.exceptions import ViuError
|
||||
from viu_media.libs.media_api.types import (
|
||||
MediaFormat,
|
||||
MediaGenre,
|
||||
MediaItem,
|
||||
@@ -70,14 +70,14 @@ from viu_cli.libs.media_api.types import (
|
||||
)
|
||||
@click.pass_obj
|
||||
def add(config: AppConfig, **options):
|
||||
from viu_cli.cli.service.download import DownloadService
|
||||
from viu_cli.cli.service.feedback import FeedbackService
|
||||
from viu_cli.cli.service.registry import MediaRegistryService
|
||||
from viu_cli.cli.utils.parser import parse_episode_range
|
||||
from viu_cli.libs.media_api.api import create_api_client
|
||||
from viu_cli.libs.media_api.params import MediaSearchParams
|
||||
from viu_cli.libs.provider.anime.provider import create_provider
|
||||
from viu_cli.libs.selectors import create_selector
|
||||
from viu_media.cli.service.download import DownloadService
|
||||
from viu_media.cli.service.feedback import FeedbackService
|
||||
from viu_media.cli.service.registry import MediaRegistryService
|
||||
from viu_media.cli.utils.parser import parse_episode_range
|
||||
from viu_media.libs.media_api.api import create_api_client
|
||||
from viu_media.libs.media_api.params import MediaSearchParams
|
||||
from viu_media.libs.provider.anime.provider import create_provider
|
||||
from viu_media.libs.selectors import create_selector
|
||||
from rich.progress import Progress
|
||||
|
||||
feedback = FeedbackService(config)
|
||||
@@ -149,7 +149,7 @@ def add(config: AppConfig, **options):
|
||||
}
|
||||
preview_command = None
|
||||
if config.general.preview != "none":
|
||||
from viu_cli.cli.utils.preview import create_preview_context
|
||||
from viu_media.cli.utils.preview import create_preview_context
|
||||
|
||||
with create_preview_context() as preview_ctx:
|
||||
preview_command = preview_ctx.get_anime_preview(
|
||||
@@ -1,14 +1,17 @@
|
||||
import click
|
||||
from viu_cli.core.config import AppConfig
|
||||
from viu_media.core.config import AppConfig
|
||||
|
||||
|
||||
@click.command(name="clear", help="Clear queued items from the registry (QUEUED -> NOT_DOWNLOADED).")
|
||||
@click.command(
|
||||
name="clear",
|
||||
help="Clear queued items from the registry (QUEUED -> NOT_DOWNLOADED).",
|
||||
)
|
||||
@click.option("--force", is_flag=True, help="Do not prompt for confirmation.")
|
||||
@click.pass_obj
|
||||
def clear_cmd(config: AppConfig, force: bool):
|
||||
from viu_cli.cli.service.feedback import FeedbackService
|
||||
from viu_cli.cli.service.registry import MediaRegistryService
|
||||
from viu_cli.cli.service.registry.models import DownloadStatus
|
||||
from viu_media.cli.service.feedback import FeedbackService
|
||||
from viu_media.cli.service.registry import MediaRegistryService
|
||||
from viu_media.cli.service.registry.models import DownloadStatus
|
||||
|
||||
feedback = FeedbackService(config)
|
||||
registry = MediaRegistryService(config.general.media_api, config.media_registry)
|
||||
@@ -1,5 +1,5 @@
|
||||
import click
|
||||
from viu_cli.core.config import AppConfig
|
||||
from viu_media.core.config import AppConfig
|
||||
|
||||
|
||||
@click.command(name="list", help="List items in the download queue and their statuses.")
|
||||
@@ -10,9 +10,9 @@ from viu_cli.core.config import AppConfig
|
||||
@click.option("--detailed", is_flag=True)
|
||||
@click.pass_obj
|
||||
def list_cmd(config: AppConfig, status: str | None, detailed: bool | None):
|
||||
from viu_cli.cli.service.feedback import FeedbackService
|
||||
from viu_cli.cli.service.registry import MediaRegistryService
|
||||
from viu_cli.cli.service.registry.models import DownloadStatus
|
||||
from viu_media.cli.service.feedback import FeedbackService
|
||||
from viu_media.cli.service.registry import MediaRegistryService
|
||||
from viu_media.cli.service.registry.models import DownloadStatus
|
||||
|
||||
feedback = FeedbackService(config)
|
||||
registry = MediaRegistryService(config.general.media_api, config.media_registry)
|
||||
@@ -1,15 +1,17 @@
|
||||
import click
|
||||
from viu_cli.core.config import AppConfig
|
||||
from viu_media.core.config import AppConfig
|
||||
|
||||
|
||||
@click.command(name="resume", help="Submit any queued or in-progress downloads to the worker.")
|
||||
@click.command(
|
||||
name="resume", help="Submit any queued or in-progress downloads to the worker."
|
||||
)
|
||||
@click.pass_obj
|
||||
def resume(config: AppConfig):
|
||||
from viu_cli.cli.service.download.service import DownloadService
|
||||
from viu_cli.cli.service.feedback import FeedbackService
|
||||
from viu_cli.cli.service.registry import MediaRegistryService
|
||||
from viu_cli.libs.media_api.api import create_api_client
|
||||
from viu_cli.libs.provider.anime.provider import create_provider
|
||||
from viu_media.cli.service.download.service import DownloadService
|
||||
from viu_media.cli.service.feedback import FeedbackService
|
||||
from viu_media.cli.service.registry import MediaRegistryService
|
||||
from viu_media.libs.media_api.api import create_api_client
|
||||
from viu_media.libs.provider.anime.provider import create_provider
|
||||
|
||||
feedback = FeedbackService(config)
|
||||
media_api = create_api_client(config.general.media_api, config)
|
||||
@@ -19,7 +19,7 @@ commands = {
|
||||
@click.group(
|
||||
cls=LazyGroup,
|
||||
name="registry",
|
||||
root="viu_cli.cli.commands.registry.commands",
|
||||
root="viu_media.cli.commands.registry.commands",
|
||||
invoke_without_command=True,
|
||||
help="Manage your local media registry - sync, search, backup and maintain your anime database",
|
||||
short_help="Local media registry management",
|
||||
@@ -3,8 +3,8 @@ Registry sync command - synchronize local registry with remote media API
|
||||
"""
|
||||
|
||||
import click
|
||||
from viu_cli.cli.service.feedback.service import FeedbackService
|
||||
from viu_cli.cli.service.registry.service import MediaRegistryService
|
||||
from viu_media.cli.service.feedback.service import FeedbackService
|
||||
from viu_media.cli.service.registry.service import MediaRegistryService
|
||||
|
||||
from .....core.config import AppConfig
|
||||
|
||||
@@ -10,7 +10,7 @@ from . import examples
|
||||
if TYPE_CHECKING:
|
||||
from typing import TypedDict
|
||||
|
||||
from viu_cli.cli.service.feedback.service import FeedbackService
|
||||
from viu_media.cli.service.feedback.service import FeedbackService
|
||||
from typing_extensions import Unpack
|
||||
|
||||
from ...libs.provider.anime.base import BaseAnimeProvider
|
||||
@@ -42,7 +42,7 @@ if TYPE_CHECKING:
|
||||
)
|
||||
@click.pass_obj
|
||||
def search(config: AppConfig, **options: "Unpack[Options]"):
|
||||
from viu_cli.cli.service.feedback.service import FeedbackService
|
||||
from viu_media.cli.service.feedback.service import FeedbackService
|
||||
|
||||
from ...core.exceptions import ViuError
|
||||
from ...libs.provider.anime.params import (
|
||||
@@ -134,7 +134,7 @@ def stream_anime(
|
||||
episode: str,
|
||||
anime_title: str,
|
||||
):
|
||||
from viu_cli.cli.service.player.service import PlayerService
|
||||
from viu_media.cli.service.player.service import PlayerService
|
||||
|
||||
from ...libs.player.params import PlayerParams
|
||||
from ...libs.provider.anime.params import EpisodeStreamsParams
|
||||
@@ -1,5 +1,5 @@
|
||||
import click
|
||||
from viu_cli.core.config import AppConfig
|
||||
from viu_media.core.config import AppConfig
|
||||
|
||||
|
||||
@click.command(help="Run the background worker for notifications and downloads.")
|
||||
@@ -11,14 +11,14 @@ def worker(config: AppConfig):
|
||||
process any queued downloads. It's recommended to run this in the
|
||||
background (e.g., 'viu worker &') or as a system service.
|
||||
"""
|
||||
from viu_cli.cli.service.auth import AuthService
|
||||
from viu_cli.cli.service.download.service import DownloadService
|
||||
from viu_cli.cli.service.feedback import FeedbackService
|
||||
from viu_cli.cli.service.notification.service import NotificationService
|
||||
from viu_cli.cli.service.registry.service import MediaRegistryService
|
||||
from viu_cli.cli.service.worker.service import BackgroundWorkerService
|
||||
from viu_cli.libs.media_api.api import create_api_client
|
||||
from viu_cli.libs.provider.anime.provider import create_provider
|
||||
from viu_media.cli.service.auth import AuthService
|
||||
from viu_media.cli.service.download.service import DownloadService
|
||||
from viu_media.cli.service.feedback import FeedbackService
|
||||
from viu_media.cli.service.notification.service import NotificationService
|
||||
from viu_media.cli.service.registry.service import MediaRegistryService
|
||||
from viu_media.cli.service.worker.service import BackgroundWorkerService
|
||||
from viu_media.libs.media_api.api import create_api_client
|
||||
from viu_media.libs.provider.anime.provider import create_provider
|
||||
|
||||
feedback = FeedbackService(config)
|
||||
if not config.worker.enabled:
|
||||
@@ -19,9 +19,7 @@ class InteractiveConfigEditor:
|
||||
|
||||
def run(self) -> AppConfig:
|
||||
"""Starts the interactive configuration wizard."""
|
||||
print(
|
||||
"[bold cyan]Welcome to the Viu Interactive Configurator![/bold cyan]"
|
||||
)
|
||||
print("[bold cyan]Welcome to the Viu Interactive Configurator![/bold cyan]")
|
||||
print("Let's set up your experience. Press Ctrl+C at any time to exit.")
|
||||
print("Current values will be shown as defaults.")
|
||||
|
||||
@@ -6,7 +6,7 @@ from ...state import InternalDirective, State
|
||||
@session.menu
|
||||
def download_episodes(ctx: Context, state: State) -> State | InternalDirective:
|
||||
"""Menu to select and download episodes synchronously."""
|
||||
from .....core.utils.fuzzy import fuzz
|
||||
from viu_media.cli.utils.search import find_best_match_title
|
||||
from .....core.utils.normalizer import normalize_title
|
||||
from ....service.download.service import DownloadService
|
||||
|
||||
@@ -40,12 +40,8 @@ def download_episodes(ctx: Context, state: State) -> State | InternalDirective:
|
||||
return InternalDirective.BACK
|
||||
|
||||
provider_results_map = {res.title: res for res in provider_search_results.results}
|
||||
best_match_title = max(
|
||||
provider_results_map.keys(),
|
||||
key=lambda p_title: fuzz.ratio(
|
||||
normalize_title(p_title, config.general.provider.value).lower(),
|
||||
media_title.lower(),
|
||||
),
|
||||
best_match_title = find_best_match_title(
|
||||
provider_results_map, config.general.provider, media_item
|
||||
)
|
||||
selected_provider_anime_ref = provider_results_map[best_match_title]
|
||||
|
||||
@@ -72,6 +72,6 @@ def episodes(ctx: Context, state: State) -> State | InternalDirective:
|
||||
menu_name=MenuName.SERVERS,
|
||||
media_api=state.media_api,
|
||||
provider=state.provider.model_copy(
|
||||
update={"episode": chosen_episode, "start_time": start_time}
|
||||
update={"episode_": chosen_episode, "start_time_": start_time}
|
||||
),
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user