2019-01-13 01:51:35 +00:00
|
|
|
import logging
|
2022-03-24 06:27:07 +00:00
|
|
|
import sys
|
2023-04-17 10:17:01 +00:00
|
|
|
from PyQt6 import QtCore, QtDBus
|
2021-11-17 09:14:11 +00:00
|
|
|
from vorta.store.models import SettingsModel
|
2018-11-06 05:13:49 +00:00
|
|
|
|
2019-01-13 01:51:35 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2018-11-06 05:13:49 +00:00
|
|
|
|
|
|
|
class VortaNotifications:
|
|
|
|
"""
|
|
|
|
Usage:
|
|
|
|
|
|
|
|
notifier = Notifications.pick()()
|
|
|
|
notifier.deliver('blah', 'blah blah')
|
|
|
|
"""
|
2022-08-15 05:21:14 +00:00
|
|
|
|
2018-11-06 05:13:49 +00:00
|
|
|
@classmethod
|
|
|
|
def pick(cls):
|
|
|
|
if sys.platform == 'darwin':
|
2019-01-13 01:51:35 +00:00
|
|
|
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'):
|
2022-03-24 06:27:07 +00:00
|
|
|
"""Dummy notifier if we're not on macOS or Linux notifier is not available."""
|
2019-01-13 01:51:35 +00:00
|
|
|
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
|
2018-11-06 05:13:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
class DarwinNotifications(VortaNotifications):
|
2019-01-13 01:51:35 +00:00
|
|
|
"""
|
|
|
|
Notify via notification center and pyobjc bridge.
|
|
|
|
"""
|
2018-12-08 10:08:23 +00:00
|
|
|
|
2019-01-13 01:51:35 +00:00
|
|
|
def deliver(self, title, text, level='info'):
|
|
|
|
if self.notifications_suppressed(level):
|
|
|
|
return
|
2018-11-06 05:13:49 +00:00
|
|
|
|
2019-01-13 01:51:35 +00:00
|
|
|
from Foundation import NSUserNotification, NSUserNotificationCenter
|
2022-08-15 05:21:14 +00:00
|
|
|
|
2019-01-13 01:51:35 +00:00
|
|
|
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)
|
2018-11-06 05:13:49 +00:00
|
|
|
|
2019-01-13 01:51:35 +00:00
|
|
|
|
|
|
|
class DBusNotifications(VortaNotifications):
|
2018-11-06 05:13:49 +00:00
|
|
|
"""
|
2019-01-13 01:51:35 +00:00
|
|
|
Use qt-dbus to send notifications.
|
2018-11-06 05:13:49 +00:00
|
|
|
|
2019-01-13 01:51:35 +00:00
|
|
|
Adapted from http://codito.in/notifications-in-qt-over-dbus/
|
2018-11-06 05:13:49 +00:00
|
|
|
"""
|
2019-01-13 01:51:35 +00:00
|
|
|
|
|
|
|
URGENCY = {'info': 1, 'error': 2}
|
|
|
|
|
|
|
|
def __init__(self):
|
2018-11-06 05:13:49 +00:00
|
|
|
pass
|
2019-01-13 01:51:35 +00:00
|
|
|
|
|
|
|
def _dbus_notify(self, header, msg, level='info'):
|
|
|
|
item = "org.freedesktop.Notifications"
|
|
|
|
path = "/org/freedesktop/Notifications"
|
|
|
|
interface = "org.freedesktop.Notifications"
|
|
|
|
app_name = "vorta"
|
2023-04-17 10:17:01 +00:00
|
|
|
id_replace = QtCore.QVariant(12321)
|
|
|
|
id_replace.convert(QtCore.QMetaType(QtCore.QMetaType.Type.UInt.value))
|
2020-08-11 03:51:14 +00:00
|
|
|
icon = "com.borgbase.Vorta-symbolic"
|
2019-01-13 01:51:35 +00:00
|
|
|
title = header
|
|
|
|
text = msg
|
2023-04-17 10:17:01 +00:00
|
|
|
actions_list = QtDBus.QDBusArgument([], QtCore.QMetaType.Type.QStringList.value)
|
2019-01-13 01:51:35 +00:00
|
|
|
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(
|
2023-04-17 10:17:01 +00:00
|
|
|
# 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,
|
2019-01-13 01:51:35 +00:00
|
|
|
"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)
|