From 901c4422b58d581fe57d309a78d9797960bfc988 Mon Sep 17 00:00:00 2001 From: Benexl Date: Tue, 18 Nov 2025 15:01:07 +0300 Subject: [PATCH 1/7] feat: add welcome screen config option --- viu_media/core/config/defaults.py | 1 + viu_media/core/config/descriptions.py | 1 + viu_media/core/config/model.py | 3 +++ 3 files changed, 5 insertions(+) diff --git a/viu_media/core/config/defaults.py b/viu_media/core/config/defaults.py index 01ff26c..bc08a6c 100644 --- a/viu_media/core/config/defaults.py +++ b/viu_media/core/config/defaults.py @@ -2,6 +2,7 @@ from ..constants import APP_DATA_DIR, DEFAULTS_DIR, PLATFORM, USER_VIDEOS_DIR from ..utils import detect # GeneralConfig +GENERAL_WELCOME_SCREEN = True GENERAL_PYGMENT_STYLE = "github-dark" GENERAL_PREFERRED_SPINNER = "smiley" GENERAL_API_CLIENT = "anilist" diff --git a/viu_media/core/config/descriptions.py b/viu_media/core/config/descriptions.py index 9801f0e..64bc844 100644 --- a/viu_media/core/config/descriptions.py +++ b/viu_media/core/config/descriptions.py @@ -1,5 +1,6 @@ # GeneralConfig +GENERAL_WELCOME_SCREEN = "Whether to enable the welcome screen, that runs once per day" GENERAL_PYGMENT_STYLE = "The pygment style to use" GENERAL_PREFERRED_SPINNER = "The spinner to use" GENERAL_API_CLIENT = "The media database API to use (e.g., 'anilist', 'jikan')." diff --git a/viu_media/core/config/model.py b/viu_media/core/config/model.py index f125b7a..234a9bf 100644 --- a/viu_media/core/config/model.py +++ b/viu_media/core/config/model.py @@ -156,6 +156,9 @@ class GeneralConfig(BaseModel): default=defaults.GENERAL_API_CLIENT, description=desc.GENERAL_API_CLIENT, ) + welcome_screen: bool = Field( + default=defaults.GENERAL_WELCOME_SCREEN, description=desc.GENERAL_WELCOME_SCREEN + ) provider: ProviderName = Field( default=ProviderName.ALLANIME, description=desc.GENERAL_PROVIDER, From f647b7419a2ba90998da308d16891f657f89a295 Mon Sep 17 00:00:00 2001 From: Benexl Date: Tue, 18 Nov 2025 15:56:28 +0300 Subject: [PATCH 2/7] feat: add welcome screen message --- viu_media/cli/cli.py | 38 +++++++++++++++++++++++++++++++- viu_media/cli/config/generate.py | 11 ++++++++- viu_media/core/constants.py | 4 +++- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/viu_media/cli/cli.py b/viu_media/cli/cli.py index 7a6c36a..7a39791 100644 --- a/viu_media/cli/cli.py +++ b/viu_media/cli/cli.py @@ -109,12 +109,48 @@ def cli(ctx: click.Context, **options: "Unpack[Options]"): ) ctx.obj = config + if config.general.welcome_screen: + import time + + from ..core.constants import APP_CACHE_DIR, USER_NAME, SUPPORT_PROJECT_URL + + last_welcomed_at_file = APP_CACHE_DIR / ".last_welcome" + should_welcome = False + if last_welcomed_at_file.exists(): + try: + last_welcomed_at = float( + last_welcomed_at_file.read_text(encoding="utf-8") + ) + # runs once a day + if (time.time() - last_welcomed_at) > 24 * 3600: + should_welcome = True + + except Exception as e: + logger.warning(f"Failed to check for update: {e}") + + else: + should_welcome = True + if should_welcome: + last_welcomed_at_file.write_text(str(time.time()), encoding="utf-8") + + from rich.prompt import Confirm + + if Confirm.ask(f"""\ +[green]How are you {USER_NAME} 🙂? +If you like the project and are able to support it please consider buying me a coffee at {SUPPORT_PROJECT_URL}. +If you would like to proceed to {SUPPORT_PROJECT_URL} select yes, otherwise enjoy your browser anime experience 😁.[/] +This messages can be disabled by switching off the welcome_screen option in the config and is only shown once every 24hrs. +"""): + from webbrowser import open + + open(SUPPORT_PROJECT_URL) + if config.general.check_for_updates: import time from ..core.constants import APP_CACHE_DIR - last_updated_at_file = APP_CACHE_DIR / "last_update" + last_updated_at_file = APP_CACHE_DIR / ".last_update" should_check_for_update = False if last_updated_at_file.exists(): try: diff --git a/viu_media/cli/config/generate.py b/viu_media/cli/config/generate.py index d0a3546..7ea5061 100644 --- a/viu_media/cli/config/generate.py +++ b/viu_media/cli/config/generate.py @@ -10,7 +10,13 @@ from pydantic.fields import ComputedFieldInfo, FieldInfo from pydantic_core import PydanticUndefined from ...core.config import AppConfig -from ...core.constants import APP_ASCII_ART, CLI_NAME, DISCORD_INVITE, REPO_HOME +from ...core.constants import ( + APP_ASCII_ART, + CLI_NAME, + DISCORD_INVITE, + REPO_HOME, + SUPPORT_PROJECT_URL, +) # The header for the config file. config_asci = "\n".join( @@ -38,6 +44,9 @@ CONFIG_FOOTER = f""" # Also join the discord server # where the anime tech community lives :) # {DISCORD_INVITE} +# If you like the project and are able to support it please consider buying me a coffee at {SUPPORT_PROJECT_URL}. +# If you would like to connect with me join the discord server from there you can dm for hackathons, or even to tell me a joke 😂 +# Otherwise enjoy your terminal anime browser experience 😁 # # ============================================================================== """.lstrip() diff --git a/viu_media/core/constants.py b/viu_media/core/constants.py index 9714f4c..e339c74 100644 --- a/viu_media/core/constants.py +++ b/viu_media/core/constants.py @@ -9,7 +9,8 @@ CLI_NAME_LOWER = "viu" PROJECT_NAME = "viu-media" APP_NAME = os.environ.get(f"{CLI_NAME}_APP_NAME", CLI_NAME_LOWER) -USER_NAME = os.environ.get("USERNAME", "User") +USER_NAME = os.environ.get("USERNAME", os.environ.get("USER", "User")) + __version__ = metadata.version("viu_media") @@ -85,3 +86,4 @@ USER_VIDEOS_DIR.mkdir(parents=True, exist_ok=True) USER_CONFIG = APP_DATA_DIR / "config.toml" LOG_FILE = LOG_FOLDER / "app.log" +SUPPORT_PROJECT_URL = "https://buymeacoffee.com/benexl" From bee73b3f9aff15eb740b28e3cc79ed2125353c2a Mon Sep 17 00:00:00 2001 From: Benexl Date: Tue, 18 Nov 2025 16:03:22 +0300 Subject: [PATCH 3/7] feat(config): add show release option --- viu_media/core/config/defaults.py | 1 + viu_media/core/config/descriptions.py | 3 +++ viu_media/core/config/model.py | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/viu_media/core/config/defaults.py b/viu_media/core/config/defaults.py index bc08a6c..4cc0aa8 100644 --- a/viu_media/core/config/defaults.py +++ b/viu_media/core/config/defaults.py @@ -33,6 +33,7 @@ def GENERAL_IMAGE_RENDERER(): GENERAL_MANGA_VIEWER = "feh" GENERAL_CHECK_FOR_UPDATES = True +GENERAL_SHOW_NEW_RELEASE = True GENERAL_UPDATE_CHECK_INTERVAL = 12 GENERAL_CACHE_REQUESTS = True GENERAL_MAX_CACHE_LIFETIME = "03:00:00" diff --git a/viu_media/core/config/descriptions.py b/viu_media/core/config/descriptions.py index 64bc844..c1dd871 100644 --- a/viu_media/core/config/descriptions.py +++ b/viu_media/core/config/descriptions.py @@ -25,6 +25,9 @@ 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_SHOW_NEW_RELEASE = ( + "Whether to show release notes after every update when running the new version" +) 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." diff --git a/viu_media/core/config/model.py b/viu_media/core/config/model.py index 234a9bf..13fb141 100644 --- a/viu_media/core/config/model.py +++ b/viu_media/core/config/model.py @@ -193,6 +193,10 @@ class GeneralConfig(BaseModel): default=defaults.GENERAL_CHECK_FOR_UPDATES, description=desc.GENERAL_CHECK_FOR_UPDATES, ) + show_new_release: bool = Field( + default=defaults.GENERAL_SHOW_NEW_RELEASE, + description=desc.GENERAL_SHOW_NEW_RELEASE, + ) update_check_interval: float = Field( default=defaults.GENERAL_UPDATE_CHECK_INTERVAL, description=desc.GENERAL_UPDATE_CHECK_INTERVAL, From 313f8369d71f4c0fb6e582c8007e5d030502156f Mon Sep 17 00:00:00 2001 From: Benexl Date: Tue, 18 Nov 2025 16:32:30 +0300 Subject: [PATCH 4/7] feat: show release notes after upgrade --- viu_media/cli/cli.py | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/viu_media/cli/cli.py b/viu_media/cli/cli.py index 7a39791..228a893 100644 --- a/viu_media/cli/cli.py +++ b/viu_media/cli/cli.py @@ -145,6 +145,59 @@ This messages can be disabled by switching off the welcome_screen option in the open(SUPPORT_PROJECT_URL) + if config.general.show_new_release: + import time + + from ..core.constants import APP_CACHE_DIR + + last_release_file = APP_CACHE_DIR / ".last_release" + should_print_release_notes = False + if last_release_file.exists(): + last_release = last_release_file.read_text(encoding="utf-8") + current_version = list(map(int, __version__.replace("v", "").split("."))) + last_saved_version = list( + map(int, last_release.replace("v", "").split(".")) + ) + if ( + (current_version[0] > last_saved_version[0]) + or ( + current_version[1] > last_saved_version[1] + and current_version[0] == last_saved_version[0] + ) + or ( + current_version[2] > last_saved_version[2] + and current_version[0] == last_saved_version[0] + and current_version[1] == last_saved_version[1] + ) + ): + should_print_release_notes = True + + else: + should_print_release_notes = True + if should_print_release_notes: + last_release_file.write_text(__version__, encoding="utf-8") + from .service.feedback import FeedbackService + from .utils.update import check_for_updates, print_release_json, update_app + from rich.prompt import Confirm + + feedback = FeedbackService(config) + feedback.info("Getting release notes...") + is_latest, release_json = check_for_updates() + if Confirm.ask( + "Would you also like to update your config with the latest options and config notes" + ): + import subprocess + + cmd = ["viu", "config", "--update"] + print(f"running '{' '.join(cmd)}'...") + subprocess.run(cmd) + + if is_latest: + print_release_json(release_json) + else: + print_release_json(release_json) + print("It seems theres another update waiting for you as well 😁") + if config.general.check_for_updates: import time From a4950efa02fde812b8ad1667ed129468e34826ce Mon Sep 17 00:00:00 2001 From: Benexl Date: Tue, 2 Dec 2025 18:00:44 +0300 Subject: [PATCH 5/7] feat: wait for feedback --- viu_media/cli/cli.py | 1 + 1 file changed, 1 insertion(+) diff --git a/viu_media/cli/cli.py b/viu_media/cli/cli.py index 228a893..af18171 100644 --- a/viu_media/cli/cli.py +++ b/viu_media/cli/cli.py @@ -197,6 +197,7 @@ This messages can be disabled by switching off the welcome_screen option in the else: print_release_json(release_json) print("It seems theres another update waiting for you as well 😁") + click.pause("Press Any Key To Proceed...") if config.general.check_for_updates: import time From 29ba77f795650b72c8a54619b37221b1afb4fe4d Mon Sep 17 00:00:00 2001 From: Benedict Xavier <81157281+Benexl@users.noreply.github.com> Date: Tue, 2 Dec 2025 18:01:56 +0300 Subject: [PATCH 6/7] Update viu_media/cli/cli.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- viu_media/cli/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viu_media/cli/cli.py b/viu_media/cli/cli.py index af18171..e5e4626 100644 --- a/viu_media/cli/cli.py +++ b/viu_media/cli/cli.py @@ -126,7 +126,7 @@ def cli(ctx: click.Context, **options: "Unpack[Options]"): should_welcome = True except Exception as e: - logger.warning(f"Failed to check for update: {e}") + logger.warning(f"Failed to read welcome screen timestamp: {e}") else: should_welcome = True From 69d3d2e032fea689b2c5abb18565554d6a64e7a9 Mon Sep 17 00:00:00 2001 From: Benedict Xavier <81157281+Benexl@users.noreply.github.com> Date: Tue, 2 Dec 2025 18:02:11 +0300 Subject: [PATCH 7/7] Update viu_media/cli/cli.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- viu_media/cli/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viu_media/cli/cli.py b/viu_media/cli/cli.py index e5e4626..3b015b7 100644 --- a/viu_media/cli/cli.py +++ b/viu_media/cli/cli.py @@ -139,7 +139,7 @@ def cli(ctx: click.Context, **options: "Unpack[Options]"): [green]How are you {USER_NAME} 🙂? If you like the project and are able to support it please consider buying me a coffee at {SUPPORT_PROJECT_URL}. If you would like to proceed to {SUPPORT_PROJECT_URL} select yes, otherwise enjoy your browser anime experience 😁.[/] -This messages can be disabled by switching off the welcome_screen option in the config and is only shown once every 24hrs. +This message can be disabled by switching off the welcome_screen option in the config and is only shown once every 24hrs. """): from webbrowser import open