mirror of https://git.48k.eu/ogclient
ogclient-systray: add new systray program for ogclient
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.master v1.3.2-26
parent
e91f6c5e2c
commit
476d82e6a9
|
@ -0,0 +1,8 @@
|
|||
:: Create version_info.txt
|
||||
python utils\create_version_file.py
|
||||
|
||||
:: Build the service binary with clean
|
||||
pyinstaller --onefile --noconsole --version-file=ogclient-version-info.txt --clean ogclient
|
||||
|
||||
:: Build the systray binary with clean
|
||||
pyinstaller --onefile --noconsole --version-file=systray-version-info.txt --clean 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()
|
|
@ -30,12 +30,12 @@ VSVersionInfo(
|
|||
'040904B0',
|
||||
[
|
||||
StringStruct('CompanyName', 'Soleta Networks'),
|
||||
StringStruct('FileDescription', 'ogClient - OpenGnsys Client Application'),
|
||||
StringStruct('FileDescription', '{appname} - OpenGnsys Client Application'),
|
||||
StringStruct('FileVersion', '{version}'),
|
||||
StringStruct('InternalName', 'ogclient'),
|
||||
StringStruct('InternalName', '{appname}'),
|
||||
StringStruct('LegalCopyright', 'Copyright © {year} Soleta Networks'),
|
||||
StringStruct('OriginalFilename', 'ogclient.exe'),
|
||||
StringStruct('ProductName', 'ogClient'),
|
||||
StringStruct('OriginalFilename', '{appname}.exe'),
|
||||
StringStruct('ProductName', '{appname}'),
|
||||
StringStruct('ProductVersion', '{version}')
|
||||
]
|
||||
)
|
||||
|
@ -72,6 +72,13 @@ if __name__ == "__main__":
|
|||
version = get_git_version()
|
||||
major, minor, patch = version_to_tuple(version)
|
||||
current_year = datetime.now().year
|
||||
version_file = version_template.format(major=major, minor=minor, patch=patch, version=version, year=current_year)
|
||||
with open('version_info.txt', 'w', encoding='utf-8') as f:
|
||||
version_file = version_template.format(major=major, minor=minor,
|
||||
patch=patch, version=version,
|
||||
year=current_year, appname='ogclient')
|
||||
with open('ogclient-version-info.txt', 'w', encoding='utf-8') as f:
|
||||
f.write(version_file)
|
||||
version_file = version_template.format(major=major, minor=minor,
|
||||
patch=patch, version=version,
|
||||
year=current_year, appname='ogclient-systray')
|
||||
with open('systray-version-info.txt', 'w', encoding='utf-8') as f:
|
||||
f.write(version_file)
|
||||
|
|
Loading…
Reference in New Issue