mirror of https://github.com/borgbase/vorta
122 lines
3.8 KiB
Python
122 lines
3.8 KiB
Python
import logging
|
|
import sys
|
|
|
|
from PyQt6 import QtCore, QtDBus
|
|
|
|
from vorta.store.models import SettingsModel
|
|
|
|
try:
|
|
from Foundation import NSUserNotification, NSUserNotificationCenter
|
|
except ImportError:
|
|
pass
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class VortaNotifications:
|
|
"""
|
|
Usage:
|
|
|
|
notifier = Notifications.pick()()
|
|
notifier.deliver('blah', 'blah blah')
|
|
"""
|
|
|
|
@classmethod
|
|
def pick(cls):
|
|
if sys.platform == 'darwin':
|
|
return DarwinNotifications()
|
|
elif QtDBus.QDBusConnection.sessionBus().isConnected():
|
|
return DBusNotifications()
|
|
else:
|
|
logger.warning('could not pick valid notification class')
|
|
return cls()
|
|
|
|
def deliver(self, title, text, level='info'):
|
|
"""Dummy notifier if we're not on macOS or Linux notifier is not available."""
|
|
pass
|
|
|
|
def notifications_suppressed(self, level):
|
|
"""Decide if notification is sent or not based on settings and level."""
|
|
if not SettingsModel.get(key='enable_notifications').value:
|
|
logger.debug('notifications suppressed')
|
|
return True
|
|
if level == 'info' and not SettingsModel.get(key='enable_notifications_success').value:
|
|
logger.debug('success notifications suppressed')
|
|
return True
|
|
|
|
logger.debug('notification not suppressed')
|
|
return False
|
|
|
|
|
|
class DarwinNotifications(VortaNotifications):
|
|
"""
|
|
Notify via notification center and pyobjc bridge.
|
|
"""
|
|
|
|
def deliver(self, title, text, level='info'):
|
|
if self.notifications_suppressed(level):
|
|
return
|
|
|
|
notification = NSUserNotification.alloc().init()
|
|
notification.setTitle_(title)
|
|
notification.setInformativeText_(text)
|
|
center = NSUserNotificationCenter.defaultUserNotificationCenter()
|
|
if center is not None: # Only works when run from app bundle.
|
|
return center.deliverNotification_(notification)
|
|
|
|
|
|
class DBusNotifications(VortaNotifications):
|
|
"""
|
|
Use qt-dbus to send notifications.
|
|
|
|
Adapted from http://codito.in/notifications-in-qt-over-dbus/
|
|
"""
|
|
|
|
URGENCY = {'info': 1, 'error': 2}
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def _dbus_notify(self, header, msg, level='info'):
|
|
item = "org.freedesktop.Notifications"
|
|
path = "/org/freedesktop/Notifications"
|
|
interface = "org.freedesktop.Notifications"
|
|
app_name = "vorta"
|
|
id_replace = QtCore.QVariant(12321)
|
|
id_replace.convert(QtCore.QMetaType(QtCore.QMetaType.Type.UInt.value))
|
|
icon = "com.borgbase.Vorta-symbolic"
|
|
title = header
|
|
text = msg
|
|
actions_list = QtDBus.QDBusArgument([], QtCore.QMetaType.Type.QStringList.value)
|
|
hint = {'urgency': self.URGENCY[level]}
|
|
time = 5000 # milliseconds for display timeout
|
|
|
|
bus = QtDBus.QDBusConnection.sessionBus()
|
|
notify = QtDBus.QDBusInterface(item, path, interface, bus)
|
|
if notify.isValid():
|
|
x = notify.call(
|
|
# Call arguments for Notify interface need to match exactly:
|
|
# https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html#command-notify
|
|
QtDBus.QDBus.CallMode.AutoDetect,
|
|
"Notify",
|
|
app_name,
|
|
id_replace,
|
|
icon,
|
|
title,
|
|
text,
|
|
actions_list,
|
|
hint,
|
|
time,
|
|
)
|
|
if x.errorName():
|
|
logger.warning("Failed to send notification!")
|
|
logger.warning(x.errorMessage())
|
|
else:
|
|
logger.warning("Invalid dbus interface")
|
|
|
|
def deliver(self, title, text, level='info'):
|
|
if self.notifications_suppressed(level):
|
|
return
|
|
|
|
self._dbus_notify(title, text)
|