diff options
author | Alejandro Sirgo Rica <asirgo@soleta.eu> | 2024-12-13 13:54:15 +0100 |
---|---|---|
committer | Alejandro Sirgo Rica <asirgo@soleta.eu> | 2024-12-16 16:01:06 +0100 |
commit | 476d82e6a9fa19e8d4be141b3575738c6859ae82 (patch) | |
tree | 872aba0400f97f92a5e259f2f1ed8fd2da46ed5c /systray/ogclient-systray | |
parent | e91f6c5e2cee39bb49d3a3ddeddc66fc0268b51e (diff) |
Add make.bat for an easier building process in Windows. This
script generates ogclient.exe and ogclient-systray binaries in
a ./dist directory.
Add ogclient-systray program. This python program polls the
existence of the ogclient process and shows a systray if the
ogclient service is active.
Update utils/create_version_file.py to generate information for
the systray binary.
Diffstat (limited to 'systray/ogclient-systray')
-rw-r--r-- | systray/ogclient-systray | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/systray/ogclient-systray b/systray/ogclient-systray new file mode 100644 index 0000000..aa517bd --- /dev/null +++ b/systray/ogclient-systray @@ -0,0 +1,99 @@ +#!/usr/bin/python3 + +# +# Copyright (C) 2020-2024 Soleta Networks <info@soleta.eu> +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +import time +import multiprocessing as mp +import psutil + +from PIL import Image, ImageDraw +from pystray import Icon, Menu, MenuItem + +SERVICE_POLL_INTERVAL = 5 + + +def _create_default_image(): + """ + Creates a default image for the tray icon. Use in case + no favicon.ico is found. The image will be a blue circle. + """ + width = height = 250 + circle_color = (45, 158, 251) + + # Create a new image with a transparent background + image = Image.new('RGBA', (width, height), (0, 0, 0, 0)) + dc = ImageDraw.Draw(image) + + # Draw circle + circle_radius = min(width, height) // 2 - 10 + circle_center = (width // 2, height // 2) + dc.ellipse( + (circle_center[0] - circle_radius, circle_center[1] - circle_radius, + circle_center[0] + circle_radius, circle_center[1] + circle_radius), + fill=circle_color + ) + return image + + +def create_icon_image(): + try: + image = Image.open(r'./favicon.ico') + image = Image.composite(image, Image.new('RGB', image.size, 'white'), image) + except FileNotFoundError: + image = _create_default_image() + return image + + +def create_systray(): + menu = Menu(MenuItem('ogclient service running', + lambda icon, item: None)) + icon = Icon('ogClient', create_icon_image(), menu=menu) + icon.run() + + +def is_ogclient_service_active(): + service_name = 'ogclient' + try: + service = psutil.win_service_get(service_name) + service = service.as_dict() + return service.get('status') == 'running' + except Exception: + return False + + +def _session_check_loop(): + systray_process = None + try: + while True: + session_status = is_ogclient_service_active() + is_systray_active = systray_process and systray_process.is_alive() + + if session_status and not is_systray_active: + systray_process = mp.Process(target=create_systray, daemon=True) + systray_process.start() + elif not session_status and is_systray_active: + systray_process.terminate() + systray_process.join() + systray_process = None + + time.sleep(SERVICE_POLL_INTERVAL) + except KeyboardInterrupt: + if systray_process and systray_process.is_alive(): + systray_process.terminate() + systray_process.join() + + +def main(): + mp.freeze_support() + mp.set_start_method('spawn') + _session_check_loop() + + +if __name__ == "__main__": + main() |