Solaar/lib/solaar/ui/notify.py

147 lines
4.0 KiB
Python

# -*- python-mode -*-
# -*- coding: UTF-8 -*-
## Copyright (C) 2012-2013 Daniel Pavel
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License along
## with this program; if not, write to the Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# Optional desktop notifications.
from __future__ import absolute_import, division, print_function, unicode_literals
from solaar.i18n import _
#
#
#
try:
# this import is allowed to fail, in which case the entire feature is unavailable
from gi.repository import Notify
from logging import getLogger, INFO as _INFO
_log = getLogger(__name__)
del getLogger
from solaar import NAME
from . import icons as _icons
# assumed to be working since the import succeeded
available = True
# cache references to shown notifications here, so if another status comes
# while its notification is still visible we don't create another one
_notifications = {}
def init():
"""Init the notifications system."""
global available
if available:
if not Notify.is_initted():
if _log.isEnabledFor(_INFO):
_log.info("starting desktop notifications")
try:
return Notify.init(NAME)
except:
_log.exception("initializing desktop notifications")
available = False
return available and Notify.is_initted()
def uninit():
if available and Notify.is_initted():
if _log.isEnabledFor(_INFO):
_log.info("stopping desktop notifications")
_notifications.clear()
Notify.uninit()
# def toggle(action):
# if action.get_active():
# init()
# else:
# uninit()
# action.set_sensitive(available)
# return action.get_active()
def alert(reason, icon=None):
assert reason
if available and Notify.is_initted():
n = _notifications.get(NAME)
if n is None:
n = _notifications[NAME] = Notify.Notification()
# we need to use the filename here because the notifications daemon
# is an external application that does not know about our icon sets
icon_file = _icons.icon_file(NAME.lower()) if icon is None \
else _icons.icon_file(icon)
n.update(NAME, reason, icon_file)
n.set_urgency(Notify.Urgency.NORMAL)
try:
# if _log.isEnabledFor(_DEBUG):
# _log.debug("showing %s", n)
n.show()
except Exception:
_log.exception("showing %s", n)
def show(dev, reason=None, icon=None):
"""Show a notification with title and text."""
if available and Notify.is_initted():
summary = dev.name
# if a notification with same name is already visible, reuse it to avoid spamming
n = _notifications.get(summary)
if n is None:
n = _notifications[summary] = Notify.Notification()
if reason:
message = reason
elif dev.status is None:
message = _("unpaired")
elif bool(dev.status):
message = dev.status.to_string() or _("connected")
else:
message = _("offline")
# we need to use the filename here because the notifications daemon
# is an external application that does not know about our icon sets
icon_file = _icons.device_icon_file(dev.name, dev.kind) if icon is None \
else _icons.icon_file(icon)
n.update(summary, message, icon_file)
urgency = Notify.Urgency.LOW if dev.status else Notify.Urgency.NORMAL
n.set_urgency(urgency)
try:
# if _log.isEnabledFor(_DEBUG):
# _log.debug("showing %s", n)
n.show()
except Exception:
_log.exception("showing %s", n)
except ImportError:
available = False
init = lambda: False
uninit = lambda: None
# toggle = lambda action: False
alert = lambda reason: None
show = lambda dev, reason=None: None