#!/usr/bin/env python # Get needed modules import sys import yaml import webbrowser import subprocess from os import path from functools import partial from PyQt5.QtCore import QTimer from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QAction, QApplication, QSystemTrayIcon, QMenu # Use config.yml file to allow for compatibility with # most terminal emulators possible, custom timer duration and icons if path.exists(path.expanduser("~/.config/systrayupdater/config.yml")): config = path.expanduser("~/.config/systrayupdater/config.yml") else: config = '/etc/systrayupdater/config.yml' try: f = open(config) except FileNotFoundError: print("Error: No config file found\n") sys.exit(1) conf = yaml.load(f,yaml.FullLoader) term = str(conf['terminal']) opt = str(conf['option']) wait = int(conf['timer']) * 60000 icn = str(conf['icon']) f.close() iconDir = '/usr/share/icons/systrayupdater/' match icn: case "white": icon = QIcon(path.join(iconDir,'arch-white-symbolic-24.svg')) case "blue": icon = QIcon(path.join(iconDir,'arch-blue-symbolic-24.svg')) case "red": icon = QIcon(path.join(iconDir,'arch-red-symbolic-24.svg')) case "green": icon = QIcon(path.join(iconDir,'arch-green-symbolic-24.svg')) case "purple": icon = QIcon(path.join(iconDir,'arch-purple-symbolic-24.svg')) case "yellow": icon = QIcon(path.join(iconDir,'arch-yellow-symbolic-24.svg')) case "black": icon = QIcon(path.join(iconDir,'arch-black-symbolic-24.svg')) case "gray": icon = QIcon(path.join(iconDir,'arch-gray-symbolic-24.svg')) case _: icon = QIcon(path.join(path.expanduser("~/.config/systrayupdater/"),icn)) # Run checkupdates command # Populates the available updates and count # Sets the menu options, list and count in proper spots def count(): cmd = ['checkupdates'] try: p1 = subprocess.Popen(cmd,stdout=subprocess.PIPE) outputList = ((p1.communicate()[0]).decode()).rstrip('\n') outputCount = len(outputList.splitlines()) if outputCount == 0: tray.setVisible(False) else: menu.clear() menu.addAction(readNews) menu.addAction(runUpdate) menu.addAction(quit) for i in outputList.splitlines(): menu.addAction(i, partial(infos, i)) avail = str(outputCount)+" Updates" tray.setToolTip(avail) tray.setVisible(True) except subprocess.CalledProcessError: tray.setVisible(False) wait = 1800000 updateTimer.killTimer updateTimer.start(wait) print("Error: \'checkupdates\' command unable to retrieve updates\nSetting timer to 30mins\n") # Read the News def news(): url = 'https://archlinux.org/news/' webbrowser.open_new_tab(url) # Get pkg info def infos(pkgString): pkg = pkgString.split(' ') url = 'https://archlinux.org/packages/?q='+ pkg[0] webbrowser.open_new_tab(url) # Run system update def update(): cmd = [ term, opt, 'sudo', 'pacman', '-Syu' ] subprocess.Popen(cmd) updateTimer.singleShot(1,count) # Create an app surface app = QApplication([]) app.setQuitOnLastWindowClosed(False) # Set up timer updateTimer = QTimer() updateTimer.timeout.connect(count) updateTimer.singleShot(1,count) # Initially populate available updates updateTimer.start(wait) # Creating the menu/options menu = QMenu() runUpdate = QAction("Run Update") readNews = QAction("Read the News") quit = QAction("Quit") runUpdate.triggered.connect(update) readNews.triggered.connect(news) quit.triggered.connect(app.quit) # Create applet and place menu in it tray = QSystemTrayIcon() tray.setIcon(icon) tray.setVisible(True) tray.setContextMenu(menu) app.exec_()