cleanups
This commit is contained in:
parent
cb3a42c04e
commit
ecf3539ba2
|
@ -29,15 +29,15 @@ def _status_updated(watcher, icon, window):
|
|||
# pass
|
||||
|
||||
|
||||
def run():
|
||||
def run(config):
|
||||
GObject.threads_init()
|
||||
|
||||
ui.notify.start(APP_TITLE)
|
||||
ui.notify.init(APP_TITLE, config.notifications)
|
||||
|
||||
watcher = WatcherThread(ui.notify.show)
|
||||
watcher.start()
|
||||
|
||||
window = ui.window.create(APP_TITLE, watcher.devices[0])
|
||||
window = ui.window.create(APP_TITLE, watcher.devices[0], not config.start_hidden, config.close_to_tray)
|
||||
|
||||
menu_actions = [('Scan all devices', watcher.full_scan),
|
||||
# ('Pair new device', _pair_new_device, watcher),
|
||||
|
@ -53,4 +53,4 @@ def run():
|
|||
Gtk.main()
|
||||
|
||||
watcher.stop()
|
||||
ui.notify.stop()
|
||||
ui.notify.set_active(False)
|
||||
|
|
|
@ -2,35 +2,62 @@
|
|||
# Optional desktop notifications.
|
||||
#
|
||||
|
||||
import logging
|
||||
|
||||
|
||||
try:
|
||||
import notify2 as _notify
|
||||
|
||||
|
||||
available = True
|
||||
available = True # assumed to be working since the import succeeded
|
||||
_active = False # not yet active
|
||||
_app_title = None
|
||||
_notifications = {}
|
||||
|
||||
|
||||
def start(app_title):
|
||||
def init(app_title, active=True):
|
||||
"""Init the notifications system."""
|
||||
_notify.init(app_title)
|
||||
return True
|
||||
global _app_title, _active
|
||||
_app_title = app_title
|
||||
return set_active(active)
|
||||
|
||||
|
||||
def stop():
|
||||
"""Stop the notifications system."""
|
||||
def set_active(active=True):
|
||||
global available, _active
|
||||
if available:
|
||||
if active:
|
||||
if not _active:
|
||||
try:
|
||||
_notify.init(_app_title)
|
||||
_active = True
|
||||
except:
|
||||
logging.exception("initializing desktop notifications")
|
||||
available = False
|
||||
else:
|
||||
if _active:
|
||||
for n in list(_notifications.values()):
|
||||
try:
|
||||
n.close()
|
||||
except Exception:
|
||||
logging.exception("closing open notification %s", n)
|
||||
# DBUS
|
||||
pass
|
||||
_notifications.clear()
|
||||
try:
|
||||
_notify.uninit()
|
||||
except:
|
||||
logging.exception("stopping desktop notifications")
|
||||
available = False
|
||||
_active = False
|
||||
return _active
|
||||
|
||||
|
||||
def show(status_code, title, text, icon=None):
|
||||
def active():
|
||||
return _active
|
||||
|
||||
|
||||
def show(status_code, title, text='', icon=None):
|
||||
"""Show a notification with title and text."""
|
||||
if not available:
|
||||
if not available or not _active:
|
||||
return
|
||||
|
||||
if title in _notifications:
|
||||
|
@ -45,17 +72,20 @@ try:
|
|||
icon = icon or title
|
||||
notification.update(title, text, title)
|
||||
try:
|
||||
if text:
|
||||
notification.show()
|
||||
else:
|
||||
notification.close()
|
||||
except Exception:
|
||||
# DBUS
|
||||
pass
|
||||
logging.exception("showing notification %s", notification)
|
||||
|
||||
|
||||
except ImportError:
|
||||
import logging
|
||||
logging.exception("ouch")
|
||||
logging.warn("python-notify2 not found, desktop notifications are disabled")
|
||||
available = False
|
||||
def start(app_title): pass
|
||||
def stop(): pass
|
||||
active = False
|
||||
def init(app_title, active=True): return False
|
||||
def active(): return False
|
||||
def set_active(active=True): return False
|
||||
def show(status_code, title, text, icon=None): pass
|
||||
|
|
|
@ -21,7 +21,10 @@ def update(window, devices):
|
|||
first = controls[0].get_child()
|
||||
icon, label = first.get_children()
|
||||
rstatus = devices[0]
|
||||
if rstatus.text:
|
||||
label.set_markup('<big><b>%s</b></big>\n%s' % (rstatus.name, rstatus.text))
|
||||
else:
|
||||
label.set_markup('<big><b>%s</b></big>' % rstatus.name)
|
||||
|
||||
for index in range(1, 1 + _MAX_DEVICES):
|
||||
devstatus = devices.get(index)
|
||||
|
@ -120,7 +123,7 @@ def _device_box(title):
|
|||
return frame
|
||||
|
||||
|
||||
def create(title, rstatus):
|
||||
def create(title, rstatus, show=True, close_to_tray=False):
|
||||
vbox = Gtk.VBox(homogeneous=False, spacing=4)
|
||||
vbox.set_border_width(4)
|
||||
|
||||
|
@ -130,6 +133,8 @@ def create(title, rstatus):
|
|||
vbox.set_visible(True)
|
||||
|
||||
window = Gtk.Window()
|
||||
window.add(vbox)
|
||||
|
||||
window.set_title(title)
|
||||
window.set_icon_name(title)
|
||||
window.set_keep_above(True)
|
||||
|
@ -137,15 +142,20 @@ def create(title, rstatus):
|
|||
# window.set_skip_pager_hint(True)
|
||||
window.set_deletable(False)
|
||||
window.set_resizable(False)
|
||||
|
||||
window.set_position(Gtk.WindowPosition.MOUSE)
|
||||
window.set_type_hint(Gdk.WindowTypeHint.UTILITY)
|
||||
|
||||
window.set_wmclass(title, 'status-window')
|
||||
window.set_role('status-window')
|
||||
|
||||
if close_to_tray:
|
||||
window.connect('window-state-event', _state_event)
|
||||
window.connect('delete-event', lambda w, e: toggle(None, window) or True)
|
||||
else:
|
||||
window.connect('delete-event', Gtk.main_quit)
|
||||
|
||||
window.add(vbox)
|
||||
if show:
|
||||
window.present()
|
||||
return window
|
||||
|
||||
|
|
|
@ -17,15 +17,15 @@ _THREAD_SLEEP = 5 # seconds
|
|||
|
||||
_UNIFYING_RECEIVER = 'Unifying Receiver'
|
||||
_NO_DEVICES = 'No devices attached.'
|
||||
_SCANNING = 'Initializing...'
|
||||
_INITIALIZING = 'Initializing...'
|
||||
_SCANNING = 'Scanning...'
|
||||
_NO_RECEIVER = 'not found'
|
||||
_FOUND_RECEIVER = 'found'
|
||||
|
||||
|
||||
class _DevStatus(api.AttachedDeviceInfo):
|
||||
timestamp = time.time()
|
||||
code = devices.STATUS.UNKNOWN
|
||||
text = ''
|
||||
text = _INITIALIZING
|
||||
refresh = None
|
||||
|
||||
|
||||
|
@ -48,20 +48,23 @@ class WatcherThread(threading.Thread):
|
|||
|
||||
def run(self):
|
||||
self.active = True
|
||||
self._notify(0, _UNIFYING_RECEIVER, _SCANNING)
|
||||
|
||||
while self.active:
|
||||
if self.listener is None:
|
||||
self._device_status_changed(self.rstatus, (devices.STATUS.UNKNOWN, _INITIALIZING))
|
||||
self._update_status_text()
|
||||
|
||||
receiver = api.open()
|
||||
if receiver:
|
||||
self._device_status_changed(self.rstatus, (devices.STATUS.CONNECTED, _FOUND_RECEIVER))
|
||||
self._device_status_changed(self.rstatus, (devices.STATUS.CONNECTED, _SCANNING))
|
||||
self._update_status_text()
|
||||
|
||||
for devinfo in api.list_devices(receiver):
|
||||
self._new_device(devinfo)
|
||||
|
||||
if len(self.devices) == 1:
|
||||
if len(self.devices) > 1:
|
||||
self._device_status_changed(self.rstatus, (devices.STATUS.CONNECTED, ''))
|
||||
else:
|
||||
self._device_status_changed(self.rstatus, (devices.STATUS.CONNECTED, _NO_DEVICES))
|
||||
|
||||
self._update_status_text()
|
||||
|
||||
self.listener = EventsListener(receiver, self._events_callback)
|
||||
|
@ -163,20 +166,30 @@ class WatcherThread(threading.Thread):
|
|||
devstatus.timestamp = time.time()
|
||||
|
||||
if type(status) == int:
|
||||
devstatus.code = status
|
||||
if devstatus.code in devices.STATUS_NAME:
|
||||
devstatus.text = devices.STATUS_NAME[devstatus.code]
|
||||
status_code = status
|
||||
if status_code in devices.STATUS_NAME:
|
||||
status_text = devices.STATUS_NAME[status_code]
|
||||
else:
|
||||
devstatus.code = status[0]
|
||||
status_code = status[0]
|
||||
if isinstance(status[1], str):
|
||||
devstatus.text = status[1]
|
||||
status_text = status[1]
|
||||
elif isinstance(status[1], dict):
|
||||
status_text = ''
|
||||
for key, value in status[1].items():
|
||||
if key == 'text':
|
||||
status_text = value
|
||||
else:
|
||||
setattr(devstatus, key, value)
|
||||
else:
|
||||
status_code = devices.STATUS.UNKNOWN
|
||||
status_text = ''
|
||||
|
||||
if old_status_code != devstatus.code:
|
||||
logging.debug("%s: device '%s' status changed %s => %s: %s", time.asctime(), devstatus.name, old_status_code, devstatus.code, devstatus.text)
|
||||
if devstatus.code // 256 != old_status_code // 256:
|
||||
if not (status_code == 0 and old_status_code > 0):
|
||||
devstatus.code = status_code
|
||||
devstatus.text = status_text
|
||||
logging.debug("%s: device '%s' status update %s => %s: %s", time.asctime(), devstatus.name, old_status_code, status_code, status_text)
|
||||
|
||||
if status_code == 0 or old_status_code != status_code:
|
||||
self._notify(devstatus.code, devstatus.name, devstatus.text)
|
||||
|
||||
return True
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
"""Generic Human Interface Device API.
|
||||
"""
|
||||
"""Generic Human Interface Device API."""
|
||||
|
||||
__author__ = "Daniel Pavel"
|
||||
__license__ = "GPL"
|
||||
__version__ = "0.3"
|
||||
|
||||
#
|
||||
# In case a future pure-Python implementation is feasible.
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
# pass
|
||||
#
|
||||
|
||||
__author__ = "Daniel Pavel"
|
||||
__license__ = "GPL"
|
||||
__version__ = "0.4"
|
||||
|
|
15
solaar.py
15
solaar.py
|
@ -6,18 +6,23 @@ __version__ = '0.4'
|
|||
#
|
||||
#
|
||||
|
||||
import logging
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
arg_parser = argparse.ArgumentParser()
|
||||
arg_parser = argparse.ArgumentParser(prog='Solaar')
|
||||
arg_parser.add_argument('-v', '--verbose', action='count', default=0,
|
||||
help='increase the logger verbosity')
|
||||
arg_parser.add_argument('-N', '--disable-notifications', action='store_false', dest='notifications',
|
||||
help='disable desktop notifications')
|
||||
arg_parser.add_argument('-H', '--start-hidden', action='store_true', dest='start_hidden',
|
||||
help='hide the application window on start')
|
||||
arg_parser.add_argument('-t', '--close-to-tray', action='store_true',
|
||||
help='closing the application window hides it')
|
||||
arg_parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__)
|
||||
args = arg_parser.parse_args()
|
||||
|
||||
import logging
|
||||
log_level = logging.root.level - 10 * args.verbose
|
||||
logging.basicConfig(level=log_level if log_level > 0 else 1)
|
||||
|
||||
import app
|
||||
app.run()
|
||||
app.run(args)
|
||||
|
|
Loading…
Reference in New Issue