From 172d3afd8dd9183d6a17d5476d3b70737ada89cc Mon Sep 17 00:00:00 2001 From: frarol96 Date: Sun, 1 Oct 2023 13:10:23 +0000 Subject: [PATCH] Added self-update functionality and changelog viewer --- Video2Crops.py | 178 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 173 insertions(+), 5 deletions(-) diff --git a/Video2Crops.py b/Video2Crops.py index b77b4f5..7e19df0 100644 --- a/Video2Crops.py +++ b/Video2Crops.py @@ -2,17 +2,24 @@ import cv2 import os import numpy as np import tkinter as tk -import tkdnd from tkinterdnd2 import DND_FILES, TkinterDnD -from tkinter import filedialog, simpledialog, messagebox +from tkinter import filedialog, simpledialog, messagebox, scrolledtext from datetime import datetime import sys import webbrowser import screeninfo +import feedparser +import subprocess +import platform +import urllib.request +import re +from bs4 import BeautifulSoup + +print(f"New start\n") # Constants v2cversion1 = 1 -v2cversion2 = 0 +v2cversion2 = 1 v2cversion3 = 0 v2cversion = f"{v2cversion1}.{v2cversion2}.{v2cversion3}" frame_step = 100 @@ -21,9 +28,168 @@ SAVE = True SHOW = True processing = False +# Define the RSS feed URL +rss_feed_url = "https://git.rolfsvaag.no/frarol96/Video2Crops/releases.rss" + # Create the root window root = TkinterDnD.Tk() root.title("Video2Crops") +root.geometry("300x450") + +def open_changelog_window(): + changelog_window = tk.Toplevel(root) + changelog_window.title("Video2Crops Changelog") + + try: + # Parse the RSS feed + feed = feedparser.parse(rss_feed_url) + + if not feed.entries: + scrolled_text = scrolledtext.ScrolledText(changelog_window, wrap=tk.WORD) + scrolled_text.pack(fill=tk.BOTH, expand=True) + scrolled_text.insert(tk.END, "No updates available.") + return + + # Create a single scrolled text widget to display all changelog entries + scrolled_text = scrolledtext.ScrolledText(changelog_window, wrap=tk.WORD) + scrolled_text.pack(fill=tk.BOTH, expand=True) + + entry_num = 0 + for entry in feed.entries: + entry_num += 1 + version_str = extract_version(entry.link) + changelog_md = extract_changelog(entry.content[0].value) + + if version_str is not None and changelog_md is not None: + version_info = f"# v{version_str}" + print(version_str) + if str(version_str) == str(v2cversion) and entry_num == 1: + version_info += "(up to date)" + elif str(version_str) == str(v2cversion): + version_info += "(current)" + elif entry_num == 1: + version_info += "(latest)" + version_info += "\n" + + date_pattern = r'(\w{3}, \d{2} \w{3} \d{4})' + pub_date = re.search(date_pattern, entry.published) + if pub_date: + rel_date = pub_date.group(1) + + version_info += f"\n{rel_date}\n\n" + + # Append the version information and changelog entry to the scrolled text widget + changelog_text = version_info + changelog_md + f"\n--------------------\n" + scrolled_text.insert(tk.END, changelog_text) + + except Exception as e: + scrolled_text = scrolledtext.ScrolledText(changelog_window, wrap=tk.WORD) + scrolled_text.pack(fill=tk.BOTH, expand=True) + scrolled_text.insert(tk.END, f"An error occurred: {str(e)}") + +def extract_version(title): + # Use regular expressions to extract the version number from the title + match = re.search(r'(\d+\.\d+\.\d+)', title) + if match: + return match.group(1) + return None + +def extract_changelog(description): + # Parse the HTML content using BeautifulSoup + soup = BeautifulSoup(description, 'html.parser') + + # Find all changelog sections + changelog_sections = soup.find_all('h3', id='user-content-changelog') + + changelogs = [] + + for changelog_section in changelog_sections: + # Extract the changelog text as plain text + changelog_text = changelog_section.find_next('ul').get_text() + changelogs.append(changelog_text.strip()) + + # Join the changelogs into a single string + changelog_str = '\n'.join(changelogs) + + return changelog_str if changelog_str else None + +# Function for updating Video2Crops +def check_for_updates(): + try: + # Parse the RSS feed + feed = feedparser.parse(rss_feed_url) + + if not feed.entries: + response = tk.messagebox.showinfo( + "No updates found", + f"Latest version: ({v2cversion})\n" + f"Current version: ({v2cversion})\n" + ) + return + + # Get the latest release + latest_release = feed.entries[0] + latest_version_str = extract_version(latest_release.link) + + if latest_version_str is None: + tk.messagebox.showinfo( + "No update Available", + f"Latest version: ({v2cversion})\n" + f"Current version: ({v2cversion})\n" + ) + return + + print(f"RSS Version: {latest_version_str}") + + # Extract version numbers from the latest release title + latest_version = tuple(map(int, latest_version_str.split('.'))) + + # Compare the versions + if latest_version > (v2cversion1, v2cversion2, v2cversion3): + # Prompt the user for an update + response = tk.messagebox.askyesno( + "Update Available", + f"A newer version ({latest_version_str}) is available.\n" + f"Current version: ({v2cversion})\n" + "Do you want to update?" + ) + + if response: + # Determine the platform + current_platform = platform.system().lower() + if current_platform == "windows": + # On Windows, download and run the installer + installer_url = "https://git.rolfsvaag.no/frarol96/Video2Crops/releases/download/v{}/Video2Crops-windows-installer.exe".format(latest_version_str) + try: + urllib.request.urlretrieve(installer_url, "Video2Crops-windows-installer.exe") + subprocess.Popen("Video2Crops-windows-installer.exe", shell=True) + root.quit() + except: + tk.messagebox.showinfo( + "Installer not found", + f"The installer file was not found.\nPlease check your antivirus and network connectivity" + ) + elif current_platform == "linux": + # On Linux, download and run the executable + executable_url = "https://git.rolfsvaag.no/frarol96/Video2Crops/releases/download/v{}/Video2Crops-linux".format(latest_version_str) + try: + urllib.request.urlretrieve(executable_url, "Video2Crops-linux") + os.chmod("Video2Crops-linux", 0o755) + subprocess.Popen("./Video2Crops-linux", shell=True) + root.quit() + except: + tk.messagebox.showinfo( + "Executable not found", + f"The executable file was not found.\nPlease check your antivirus and network connectivity" + ) + else: + tk.messagebox.showinfo( + "No update Available", + f"Latest version: ({v2cversion})\n" + f"Current version: ({v2cversion})\n" + ) + except Exception as e: + tk.messagebox.showerror("Error", f"An error occurred: {str(e)}") # Function to create the output directory and return its path def create_output_directory(video_filename): @@ -352,8 +518,10 @@ info_menu = tk.Menu(menu, tearoff=0) menu.add_cascade(label="Info", menu=info_menu) info_menu.add_command(label="Project Folder", command=lambda: webbrowser.open(os.getcwd())) info_menu.add_separator() -info_menu.add_command(label="About", command=lambda: webbrowser.open("about.md")) +info_menu.add_command(label="About", command=lambda: webbrowser.open("https://git.rolfsvaag.no/frarol96/Video2Crops/wiki")) info_menu.add_command(label=f"Version: {str(v2cversion)}") +info_menu.add_command(label=f"Check for updates", command=check_for_updates) +info_menu.add_command(label=f"View Changelog", command=open_changelog_window) # Create a label for selected files label = tk.Label(root, text="Selected Files:") @@ -375,4 +543,4 @@ remove_file_button.pack(padx=20, pady=10) process_files_button = tk.Button(root, text="Process Files", command=process_files) process_files_button.pack(padx=20, pady=10) -root.mainloop() \ No newline at end of file +root.mainloop()