Add periodic version check
All checks were successful
Gitea/kapitanbooru-uploader/pipeline/head This commit looks good
All checks were successful
Gitea/kapitanbooru-uploader/pipeline/head This commit looks good
This commit is contained in:
@@ -7,11 +7,14 @@ import threading
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog, messagebox, ttk
|
||||
from typing import Dict, Tuple, Optional
|
||||
from packaging.version import parse as parse_version
|
||||
import itertools
|
||||
|
||||
import networkx as nx
|
||||
import requests
|
||||
from PIL import Image, ImageTk, PngImagePlugin
|
||||
import wdtagger as wdt
|
||||
import tomli
|
||||
|
||||
from .I18N import _
|
||||
from .ProgressFile import ProgressFile
|
||||
@@ -139,7 +142,8 @@ class ImageBrowser(tk.Tk):
|
||||
super().__init__()
|
||||
self.title("Kapitanbooru Uploader")
|
||||
self.geometry("900x600")
|
||||
self.version = "0.4.4"
|
||||
self.version = "0.5.0"
|
||||
self.acknowledged_version = parse_version(self.version)
|
||||
|
||||
self.settings = Settings()
|
||||
self.tags_repo = TagsRepo(self.settings)
|
||||
@@ -204,6 +208,66 @@ class ImageBrowser(tk.Tk):
|
||||
self.create_widgets()
|
||||
self.bind_events()
|
||||
|
||||
# Schedule first update check
|
||||
self.after(1000, self._schedule_update_check)
|
||||
|
||||
def _schedule_update_check(self):
|
||||
"""Schedule periodic update checks"""
|
||||
self._check_for_update()
|
||||
# Check every 5 minutes (300,000 ms)
|
||||
self.after(300000, self._schedule_update_check)
|
||||
|
||||
def _check_for_update(self):
|
||||
"""Check for updates in a background thread"""
|
||||
|
||||
def check_thread():
|
||||
try:
|
||||
# Fetch pyproject.toml using requests
|
||||
response = requests.get(
|
||||
"https://git.mlesniak.pl/kapitan/kapitanbooru-uploader/raw/branch/main/pyproject.toml",
|
||||
timeout=10, # Add reasonable timeout
|
||||
)
|
||||
response.raise_for_status() # Raise exception for HTTP errors
|
||||
|
||||
remote_toml = tomli.loads(response.text)
|
||||
remote_version_str = remote_toml["project"]["version"]
|
||||
remote_version = parse_version(remote_version_str)
|
||||
current_version = parse_version(self.version)
|
||||
|
||||
if (
|
||||
remote_version > current_version
|
||||
and remote_version > self.acknowledged_version
|
||||
):
|
||||
self.after(0, lambda: self._notify_user(remote_version_str))
|
||||
self.acknowledged_version = remote_version
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(_("Update check failed: {error}").format(error=e))
|
||||
except KeyError as e:
|
||||
print(_("Malformed pyproject.toml: {error}").format(error=e))
|
||||
except Exception as e:
|
||||
print(
|
||||
_("Unexpected error during update check: {error}").format(error=e)
|
||||
)
|
||||
|
||||
threading.Thread(target=check_thread, daemon=True).start()
|
||||
|
||||
def _notify_user(self, new_version):
|
||||
"""Show update notification with translated messages"""
|
||||
title = _("Update Available")
|
||||
message_template = _(
|
||||
"A new version {new_version} is available!\n"
|
||||
"You have version {current_version}.\n\n"
|
||||
"Update using: {update_command}"
|
||||
)
|
||||
|
||||
formatted_message = message_template.format(
|
||||
new_version=new_version,
|
||||
current_version=self.version,
|
||||
update_command="pip install --upgrade kapitanbooru-uploader",
|
||||
)
|
||||
|
||||
messagebox.showinfo(title, formatted_message)
|
||||
|
||||
def reload_ui(self):
|
||||
"""Reload UI components with new language"""
|
||||
# Destroy current widgets
|
||||
@@ -417,31 +481,43 @@ class ImageBrowser(tk.Tk):
|
||||
frame = ttk.Frame(about, padding=10)
|
||||
frame.pack(fill="both", expand=True)
|
||||
|
||||
row_counter = itertools.count(0)
|
||||
|
||||
ttk.Label(
|
||||
frame, text="Kapitanbooru Uploader", font=("TkDefaultFont", 16, "bold")
|
||||
).grid(row=0, column=0, sticky=tk.W)
|
||||
).grid(row=next(row_counter), column=0, sticky=tk.W)
|
||||
|
||||
current_version = parse_version(self.version)
|
||||
if current_version < self.acknowledged_version:
|
||||
ttk.Label(
|
||||
frame,
|
||||
text=_("A new version {new_version} is available!").format(
|
||||
new_version=self.acknowledged_version
|
||||
),
|
||||
foreground="red",
|
||||
).grid(row=next(row_counter), column=0, sticky=tk.W)
|
||||
|
||||
content = [
|
||||
(f"Version {self.version}", 1),
|
||||
("", 2),
|
||||
(_("A GUI application for uploading images to KapitanBooru."), 3),
|
||||
(_("Features include image upload, tag management, automatic"), 4),
|
||||
(_("tagging with wdtagger, and cache management."), 5),
|
||||
("", 6),
|
||||
(_("Authors:"), 7),
|
||||
("Michał Leśniak", 8),
|
||||
("", 9),
|
||||
(_("License: MIT License"), 10),
|
||||
(f"Copyright © 2025 Michał Leśniak", 11),
|
||||
("", 12),
|
||||
_("Current version: {version}").format(version=self.version),
|
||||
"",
|
||||
_("A GUI application for uploading images to KapitanBooru."),
|
||||
_("Features include image upload, tag management, automatic"),
|
||||
_("tagging with wdtagger, and cache management."),
|
||||
"",
|
||||
_("Authors:"),
|
||||
"Michał Leśniak",
|
||||
"",
|
||||
_("License: MIT License"),
|
||||
f"Copyright © 2025 Michał Leśniak",
|
||||
"",
|
||||
]
|
||||
|
||||
for text, row in content:
|
||||
ttk.Label(frame, text=text).grid(row=row, column=0, sticky=tk.W)
|
||||
for text in content:
|
||||
ttk.Label(frame, text=text).grid(row=next(row_counter), column=0, sticky=tk.W)
|
||||
|
||||
# Repository link
|
||||
repo_frame = ttk.Frame(frame)
|
||||
repo_frame.grid(row=13, sticky=tk.W)
|
||||
repo_frame.grid(row=next(row_counter), sticky=tk.W)
|
||||
ttk.Label(repo_frame, text=_("Repository:")).pack(side=tk.LEFT)
|
||||
repo_url = "https://git.mlesniak.pl/kapitan/kapitanbooru-uploader"
|
||||
repo = ttk.Label(repo_frame, text=repo_url, cursor="hand2", foreground="blue")
|
||||
@@ -450,7 +526,7 @@ class ImageBrowser(tk.Tk):
|
||||
|
||||
# Website link
|
||||
website_frame = ttk.Frame(frame)
|
||||
website_frame.grid(row=14, sticky=tk.W)
|
||||
website_frame.grid(row=next(row_counter), sticky=tk.W)
|
||||
ttk.Label(website_frame, text=_("Website:")).pack(side=tk.LEFT)
|
||||
website_url = "https://booru.mlesniak.pl"
|
||||
website = ttk.Label(
|
||||
|
Reference in New Issue
Block a user