openmedialibrary/oml/gtkstatus.py

165 lines
4.4 KiB
Python

#!/usr/bin/env python3
import os
from os.path import dirname, abspath
import json
import subprocess
import sys
import webbrowser
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
base = dirname(dirname(dirname(abspath(__file__))))
icon = os.path.join(base, 'openmedialibrary/static/svg/oml.svg')
title = "Open Media Library"
ctl = base + '/ctl'
def check_pid(pid):
if not os.path.exists(pid):
return False
try:
with open(pid, 'r') as fd:
pid = int(fd.read().strip())
os.kill(pid, 0)
except OSError:
return False
else:
return True
def preexec(): # Don't forward signals.
os.setpgrp()
class OMLStatus:
menu = None
icon = None
def __init__(self, autostart=False):
self.autostart = autostart
self.create_pid()
self.win = Gtk.Window()
self.win.set_icon_from_file(icon)
self.win.set_title(title)
#self.win.show_all()
self.win.iconify()
'''
self.icon = Gtk.StatusIcon()
self.icon.set_from_file(icon)
self.icon.set_title(title)
self.icon.connect("activate", self._click)
self.icon.connect("popup-menu", self._click)
'''
subprocess.Popen([ctl, 'start'], close_fds=True, preexec_fn=preexec)
if not self.autostart:
GLib.timeout_add_seconds(1, self._open, None)
GLib.timeout_add_seconds(60, self._check, None)
def _check(self, *args, **kwargs):
pid = os.path.join(base, 'data', 'openmedialibrary.pid')
if os.path.exists(pid):
GLib.timeout_add_seconds(60, self._check, None)
else:
self._quit(None)
def create_pid(self):
pid = self.get_pid()
if pid:
with open(pid, 'w') as fd:
fd.write('%s' % os.getpid())
@classmethod
def remove_pid(cls):
pid = cls.get_pid()
if pid and os.path.exists(pid):
os.unlink(pid)
@classmethod
def get_pid(cls):
run = '/run/user/%s' % os.getuid()
if os.path.exists(run):
oml = os.path.join(run, 'openmedialibrary')
if not os.path.exists(oml):
os.makedirs(oml)
pid = os.path.join(oml, 'pid')
else:
pid = None
return pid
@classmethod
def is_running(cls):
pid = cls.get_pid()
if pid and check_pid(pid):
return True
else:
return False
def get_menu(self):
menu = Gtk.Menu()
t = Gtk.MenuItem(label=title)
t.set_sensitive(False)
menu.append(t)
menu.append(Gtk.SeparatorMenuItem())
about = Gtk.MenuItem(label="Launch")
about.connect("activate", self._open)
menu.append(about)
quit = Gtk.MenuItem(label="Quit")
quit.connect("activate", self._quit)
menu.append(quit)
menu.show_all()
return menu
def _click(self, icon, button=None, time=None):
if self.menu:
self.menu.destroy()
self.menu = None
else:
self.menu = self.get_menu()
button = 1
time = Gtk.get_current_event_time()
self.menu.popup(None, None, self.icon.position_menu, icon, button, time)
def _quit(self, q):
Gtk.main_quit()
self.stop()
def stop(self, *args, **kwargs):
p = subprocess.Popen([ctl, 'stop'], close_fds=True)
self.menu = None
self.remove_pid()
def _open(self, *args):
self.load()
self.menu = None
@classmethod
def load(cls):
config = os.path.join(base, 'data', 'server.json')
default_port = port = 9842
if os.path.exists(config):
try:
with open(config) as fd:
config = json.load(fd)
port = config.get('port', port)
except:
pass
url = 'file://' + base + '/openmedialibrary/static/html/load.html'
if port != default_port:
url += '#%s' % port
webbrowser.open_new_tab(url)
if __name__ == '__main__':
import signal
autostart = len(sys.argv) > 1 and sys.argv[1] == '--autostart'
if OMLStatus.is_running():
OMLStatus.load()
else:
oml = OMLStatus(autostart)
main_loop = GLib.MainLoop()
try:
main_loop.run()
except KeyboardInterrupt:
oml.stop()