Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add update checker and installer for non-snap Linux versions. #3730

Open
tegridyfarmer opened this issue Dec 5, 2024 · 0 comments
Open

Add update checker and installer for non-snap Linux versions. #3730

tegridyfarmer opened this issue Dec 5, 2024 · 0 comments

Comments

@tegridyfarmer
Copy link

Problem Statement

When I installed the .rpm file I had to follow the GitHub to keep up with version updates.
Because then I would know when to update the program, since you do not get notified about it.

❔ Possible Solution

In SuperProductivity it would notify users of a new version being available.
This could be done in the form of a banner or a notification for example.
Then you could choose to install the update and restart the program.

⤴️ Describe alternatives you've considered

Currently I use a (bad) Python script which checks the current version of the program and the newest version from GitHub.
When it recognizes there is an out-of-date version in use, the Python script will show a red system tray icon.
When right-clicking on it you have to option to install the update or exit the tray icon.
I have created a new SuperProductivity desktop file, which launches this script at launch.

➕ Additional context

My Python script, maybe it can be useful.
Be warned I am a amateur Python programmer :).

import requests
import xml.etree.ElementTree as ET
import subprocess
import os
import re
from PIL import Image, ImageDraw
import sys
import pystray
from pystray import MenuItem, Icon
from datetime import datetime

def get_latest_version_from_atom_feed(atom_url):
    response = requests.get(atom_url)
    response.raise_for_status()
    root = ET.fromstring(response.content)
    
    entries = root.findall('{http://www.w3.org/2005/Atom}entry')
    latest_version = None
    
    for entry in entries:
        title = entry.find('{http://www.w3.org/2005/Atom}title').text
        if title:
            version_match = re.search(r'(\d+\.\d+\.\d+)(?:-.*)?', title)
            if version_match:
                version = version_match.group(1)  
                if '-rc' not in title and '-beta' not in title and '-alpha' not in title:
                    latest_version = version 
                    break  

    return latest_version

def get_current_version():
    version_string = subprocess.check_output(['rpm', '-q', 'superProductivity']).decode().strip()
    version_match = re.search(r'(\d+\.\d+\.\d+)', version_string)
    return version_match.group(1) if version_match else None 

def create_color_block_icon(color):
    width, height = 64, 64
    image = Image.new('RGB', (width, height), (255, 255, 255))
    draw = ImageDraw.Draw(image)
    draw.rectangle([0, 0, width, height], fill=color)
    return image

def on_quit(icon, item):
    icon.stop()

def log_update_status(message):
    log_file_path = os.path.expanduser('~/Software/SuperProductivity/Update/update_log.txt')
    os.makedirs(os.path.dirname(log_file_path), exist_ok=True)
    with open(log_file_path, 'a') as log_file:
        log_file.write(f"{datetime.now()}: {message}\n")

def download_and_update(icon):
    icon.title = "Downloading Update..."
    
    download_dir = os.path.expanduser('~/Software/SuperProductivity/Update')
    rpm_file = os.path.join(download_dir, 'superProductivity-x86_64.rpm')
    latest_release_url = 'https://github.com/johannesjo/super-productivity/releases/latest/download/superProductivity-x86_64.rpm'
    os.makedirs(download_dir, exist_ok=True)

    print("Downloading latest update...")
    log_update_status("Starting download of the latest update.")
    
    try:
        subprocess.run(['wget', '-O', rpm_file, latest_release_url], check=True)
        print("Download complete.")
        log_update_status("Download complete.")
    except subprocess.CalledProcessError as e:
        print("Failed to download the update.")
        log_update_status(f"Failed to download the update: {e}")
        return

    install_command = f"sudo rpm --upgrade {rpm_file}"
    print("Installing update...")
    log_update_status("Installing update...")
    
    try:
        os.system(install_command)
        print(f"Update installed successfully. SuperProductivity has been updated from {current_version} to {latest_version}.")
        log_update_status(f"Update installed successfully. SuperProductivity has been updated from {current_version} to {latest_version}.")
        os.remove(rpm_file)
        print(f"Deleted the RPM file: {rpm_file}")
        log_update_status(f"Deleted the RPM file: {rpm_file}")
        sys.exit(0) 
    except Exception as e:
        print(f"Error during installation: {e}")
        log_update_status(f"Error during installation: {e}")
        exit_choice = input("An error occurred during installation. Do you want to exit? (y/n): ").strip().lower()
        if exit_choice == 'y':
            print("Exiting the program.")
            sys.exit(1)

atom_feed_url = 'https://github.com/johannesjo/super-productivity/releases.atom'
latest_version = get_latest_version_from_atom_feed(atom_feed_url)
current_version = get_current_version()
print(f"Current Version: {current_version}")
print(f"Latest Version: {latest_version}")

if latest_version and current_version < latest_version:
    print(f"\033[91mYour SuperProductivity of version {current_version} is not up to date. The latest version is {latest_version}.\033[0m")
    log_update_status(f"Your SuperProductivity of version {current_version} is not up to date. The latest version is {latest_version}.")
    
    icon = Icon("version_check", create_color_block_icon((255, 0, 0)), "Update Available", 
                menu=pystray.Menu(
                    MenuItem("Download and Update", lambda icon: download_and_update(icon)),
                    MenuItem("Quit", on_quit)
                ))
    icon.run()
elif latest_version and current_version == latest_version:
    print(f"\033[92mYour SuperProductivity of version {current_version} is up to date since the latest version is {latest_version}.\033[0m")
    log_update_status(f"Your SuperProductivity of version {current_version} is up to date since the latest version is {latest_version}.")
else:
    print(f"\033[93mWe could not determine version information!\033[0m")
    log_update_status("We could not determine version information!")
@tegridyfarmer tegridyfarmer changed the title Add update checker to for non-snap Linux versions. Add update checker and installer for non-snap Linux versions. Dec 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant