mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-27 13:13:25 -08:00
feat(cli): auto check for updates
This commit is contained in:
@@ -108,6 +108,49 @@ def cli(ctx: click.Context, **options: "Unpack[Options]"):
|
||||
else loader.load(cli_overrides)
|
||||
)
|
||||
ctx.obj = config
|
||||
|
||||
if config.general.check_for_updates:
|
||||
import time
|
||||
|
||||
from ..core.constants import APP_CACHE_DIR
|
||||
|
||||
last_updated_at_file = APP_CACHE_DIR / "last_update"
|
||||
should_check_for_update = False
|
||||
if last_updated_at_file.exists():
|
||||
try:
|
||||
last_updated_at_time = float(
|
||||
last_updated_at_file.read_text(encoding="utf-8")
|
||||
)
|
||||
if (
|
||||
time.time() - last_updated_at_time
|
||||
) > config.general.update_check_interval * 3600:
|
||||
should_check_for_update = True
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to check for update: {e}")
|
||||
|
||||
else:
|
||||
should_check_for_update = True
|
||||
if should_check_for_update:
|
||||
last_updated_at_file.write_text(str(time.time()), encoding="utf-8")
|
||||
from .service.feedback import FeedbackService
|
||||
from .utils.update import check_for_updates, print_release_json, update_app
|
||||
|
||||
feedback = FeedbackService(config)
|
||||
feedback.info("Checking for updates...")
|
||||
is_latest, release_json = check_for_updates()
|
||||
if not is_latest:
|
||||
from ..libs.selectors.selector import create_selector
|
||||
|
||||
selector = create_selector(config)
|
||||
if release_json and selector.confirm(
|
||||
"Theres an update available would you like to see the release notes before deciding to update?"
|
||||
):
|
||||
print_release_json(release_json)
|
||||
selector.ask("Enter to continue...")
|
||||
if selector.confirm("Would you like to update?"):
|
||||
update_app()
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
from .commands.anilist import cmd
|
||||
|
||||
|
||||
@@ -5,10 +5,8 @@ from typing import TYPE_CHECKING
|
||||
|
||||
import click
|
||||
from rich import print
|
||||
from rich.console import Console
|
||||
from rich.markdown import Markdown
|
||||
|
||||
from ..utils.update import check_for_updates, update_app
|
||||
from ..utils.update import check_for_updates, print_release_json, update_app
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ...core.config import AppConfig
|
||||
@@ -74,87 +72,46 @@ def update(
|
||||
check_only: Whether to only check for updates without updating
|
||||
release_notes: Whether to show release notes for the latest version
|
||||
"""
|
||||
try:
|
||||
if release_notes:
|
||||
print("[cyan]Fetching latest release notes...[/]")
|
||||
is_latest, release_json = check_for_updates()
|
||||
if release_notes:
|
||||
print("[cyan]Fetching latest release notes...[/]")
|
||||
is_latest, release_json = check_for_updates()
|
||||
|
||||
if not release_json:
|
||||
print(
|
||||
"[yellow]Could not fetch release information. Please check your internet connection.[/]"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
version = release_json.get("tag_name", "unknown")
|
||||
release_name = release_json.get("name", version)
|
||||
release_body = release_json.get("body", "No release notes available.")
|
||||
published_at = release_json.get("published_at", "unknown")
|
||||
|
||||
console = Console()
|
||||
|
||||
print(f"[bold cyan]Release: {release_name}[/]")
|
||||
print(f"[dim]Version: {version}[/]")
|
||||
print(f"[dim]Published: {published_at}[/]")
|
||||
print()
|
||||
|
||||
# Display release notes as markdown if available
|
||||
if release_body.strip():
|
||||
markdown = Markdown(release_body)
|
||||
console.print(markdown)
|
||||
else:
|
||||
print("[dim]No release notes available for this version.[/]")
|
||||
|
||||
return
|
||||
|
||||
elif check_only:
|
||||
print("[cyan]Checking for updates...[/]")
|
||||
is_latest, release_json = check_for_updates()
|
||||
|
||||
if not release_json:
|
||||
print(
|
||||
"[yellow]Could not check for updates. Please check your internet connection.[/]"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
if is_latest:
|
||||
print("[green]Viu is up to date![/]")
|
||||
print(
|
||||
f"[dim]Current version: {release_json.get('tag_name', 'unknown')}[/]"
|
||||
)
|
||||
else:
|
||||
latest_version = release_json.get("tag_name", "unknown")
|
||||
print(f"[yellow]Update available: {latest_version}[/]")
|
||||
print("[dim]Run 'viu update' to update[/]")
|
||||
sys.exit(1)
|
||||
if not release_json:
|
||||
print(
|
||||
"[yellow]Could not fetch release information. Please check your internet connection.[/]"
|
||||
)
|
||||
else:
|
||||
print("[cyan]Checking for updates and updating if necessary...[/]")
|
||||
success, release_json = update_app(force=force)
|
||||
print_release_json(release_json)
|
||||
|
||||
if not release_json:
|
||||
print(
|
||||
"[red]Could not check for updates. Please check your internet connection.[/]"
|
||||
)
|
||||
sys.exit(1)
|
||||
return
|
||||
|
||||
if success:
|
||||
latest_version = release_json.get("tag_name", "unknown")
|
||||
print(f"[green]Successfully updated to version {latest_version}![/]")
|
||||
else:
|
||||
if force:
|
||||
print(
|
||||
"[red]Update failed. Please check the error messages above.[/]"
|
||||
)
|
||||
sys.exit(1)
|
||||
# If not forced and update failed, it might be because already up to date
|
||||
# The update_app function already prints appropriate messages
|
||||
elif check_only:
|
||||
print("[cyan]Checking for updates...[/]")
|
||||
is_latest, release_json = check_for_updates()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n[yellow]Update cancelled by user.[/]")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"[red]An error occurred during update: {e}[/]")
|
||||
# Get trace option from parent context
|
||||
trace = ctx.parent.params.get("trace", False) if ctx.parent else False
|
||||
if trace:
|
||||
raise
|
||||
sys.exit(1)
|
||||
if not release_json:
|
||||
print(
|
||||
"[yellow]Could not check for updates. Please check your internet connection.[/]"
|
||||
)
|
||||
|
||||
if is_latest:
|
||||
print("[green]Viu is up to date![/]")
|
||||
print(f"[dim]Current version: {release_json.get('tag_name', 'unknown')}[/]")
|
||||
else:
|
||||
latest_version = release_json.get("tag_name", "unknown")
|
||||
print(f"[yellow]Update available: {latest_version}[/]")
|
||||
print("[dim]Run 'viu update' to update[/]")
|
||||
else:
|
||||
print("[cyan]Checking for updates and updating if necessary...[/]")
|
||||
success, release_json = update_app(force=force)
|
||||
|
||||
if not release_json:
|
||||
print(
|
||||
"[red]Could not check for updates. Please check your internet connection.[/]"
|
||||
)
|
||||
if success:
|
||||
latest_version = release_json.get("tag_name", "unknown")
|
||||
print(f"[green]Successfully updated to version {latest_version}![/]")
|
||||
else:
|
||||
if force:
|
||||
print("[red]Update failed. Please check the error messages above.[/]")
|
||||
|
||||
@@ -8,6 +8,8 @@ import sys
|
||||
|
||||
from httpx import get
|
||||
from rich import print
|
||||
from rich.console import Console
|
||||
from rich.markdown import Markdown
|
||||
|
||||
from ...core.constants import (
|
||||
AUTHOR,
|
||||
@@ -20,6 +22,25 @@ from ...core.constants import (
|
||||
API_URL = f"https://api.{GIT_REPO}/repos/{AUTHOR}/{CLI_NAME_LOWER}/releases/latest"
|
||||
|
||||
|
||||
def print_release_json(release_json):
|
||||
version = release_json.get("tag_name", "unknown")
|
||||
release_name = release_json.get("name", version)
|
||||
release_body = release_json.get("body", "No release notes available.")
|
||||
published_at = release_json.get("published_at", "unknown")
|
||||
|
||||
console = Console()
|
||||
|
||||
print(f"[bold cyan]Release: {release_name}[/]")
|
||||
print(f"[dim]Version: {version}[/]")
|
||||
print(f"[dim]Published: {published_at}[/]")
|
||||
print()
|
||||
|
||||
# Display release notes as markdown if available
|
||||
if release_body and release_body.strip():
|
||||
markdown = Markdown(release_body)
|
||||
console.print(markdown)
|
||||
|
||||
|
||||
def check_for_updates():
|
||||
USER_AGENT = f"{CLI_NAME_LOWER} user"
|
||||
try:
|
||||
|
||||
@@ -32,6 +32,7 @@ def GENERAL_IMAGE_RENDERER():
|
||||
|
||||
GENERAL_MANGA_VIEWER = "feh"
|
||||
GENERAL_CHECK_FOR_UPDATES = True
|
||||
GENERAL_UPDATE_CHECK_INTERVAL = 12
|
||||
GENERAL_CACHE_REQUESTS = True
|
||||
GENERAL_MAX_CACHE_LIFETIME = "03:00:00"
|
||||
GENERAL_NORMALIZE_TITLES = True
|
||||
|
||||
@@ -24,6 +24,7 @@ GENERAL_IMAGE_RENDERER = (
|
||||
)
|
||||
GENERAL_MANGA_VIEWER = "The external application to use for viewing manga pages."
|
||||
GENERAL_CHECK_FOR_UPDATES = "Automatically check for new versions of Viu on startup."
|
||||
GENERAL_UPDATE_CHECK_INTERVAL = "The interval in hours to check for updates"
|
||||
GENERAL_CACHE_REQUESTS = (
|
||||
"Enable caching of network requests to speed up subsequent operations."
|
||||
)
|
||||
|
||||
@@ -190,6 +190,10 @@ class GeneralConfig(BaseModel):
|
||||
default=defaults.GENERAL_CHECK_FOR_UPDATES,
|
||||
description=desc.GENERAL_CHECK_FOR_UPDATES,
|
||||
)
|
||||
update_check_interval: float = Field(
|
||||
default=defaults.GENERAL_UPDATE_CHECK_INTERVAL,
|
||||
description=desc.GENERAL_UPDATE_CHECK_INTERVAL,
|
||||
)
|
||||
cache_requests: bool = Field(
|
||||
default=defaults.GENERAL_CACHE_REQUESTS,
|
||||
description=desc.GENERAL_CACHE_REQUESTS,
|
||||
|
||||
Reference in New Issue
Block a user