Source code for flexget.components.notify.notifiers.toast

import os
import sys

from loguru import logger

from flexget import plugin
from flexget.event import event
from flexget.plugin import DependencyError, PluginWarning

plugin_name = 'toast'

logger = logger.bind(name=plugin_name)


[docs] class NotifyToast: """Send messages via local notification system. You must have a notification system like dbus for Linux. Preliminary support for Windows notifications. Not heavily tested yet. Examples:: notify: entries: via: - toast: yes notify: entries: via: - toast: timeout: 5 """ schema = { 'anyOf': [ {'type': 'boolean', 'enum': [True]}, { 'type': 'object', 'properties': {'timeout': {'type': 'integer'}, 'url': {'type': 'string'}}, 'additionalProperties': False, }, ] } def __init__(self): self.windows_classAtom = None
[docs] def prepare_config(self, config): if not isinstance(config, dict): config = {} config.setdefault('timeout', 4) config.setdefault('url', '') return config
[docs] def mac_notify(self, title, message, config): config = self.prepare_config(config) try: from pync import Notifier except ImportError as e: logger.debug('Error importing pync: {}', e) raise DependencyError(plugin_name, 'pync', f'pync module required. ImportError: {e}') icon_path = None try: import flexget.ui icon_path = os.path.join(flexget.ui.__path__[0], 'v1', 'app', 'favicon.ico') except Exception as e: logger.debug('Error trying to get flexget icon from webui folder: {}', e) notify_kwargs = { 'subtitle': title, 'title': 'FlexGet Notification', 'appIcon': icon_path, 'timeout': config['timeout'], } if config.get('url'): notify_kwargs['open'] = config.get('url') try: Notifier.notify(message, **notify_kwargs) except Exception as e: raise PluginWarning(f'Cannot send a notification: {e}')
[docs] def linux_notify(self, title, message, config): config = self.prepare_config(config) try: from gi.repository import Notify except ImportError as e: logger.debug('Error importing Notify: {}', e) raise DependencyError( plugin_name, 'gi.repository', f'Notify module required. ImportError: {e}' ) if not Notify.init('Flexget'): raise PluginWarning('Unable to init libnotify.') n = Notify.Notification.new(title, message, None) timeout = config['timeout'] * 1000 n.set_timeout(timeout) if not n.show(): raise PluginWarning(f'Unable to send notification for {title}')
[docs] def windows_notify(self, title, message, config): config = self.prepare_config(config) try: from win32api import GetModuleHandle from win32con import ( CW_USEDEFAULT, IDI_APPLICATION, IMAGE_ICON, LR_DEFAULTSIZE, LR_LOADFROMFILE, WM_USER, WS_OVERLAPPED, WS_SYSMENU, ) from win32gui import ( NIF_ICON, NIF_INFO, NIF_MESSAGE, NIF_TIP, NIM_ADD, WNDCLASS, CreateWindow, LoadIcon, LoadImage, RegisterClass, Shell_NotifyIcon, UpdateWindow, ) except ImportError: raise DependencyError( plugin_name, 'pypiwin32', 'pywin32 module is required for desktop notifications on ' 'windows. You can install it with `pip install pypiwin32`', ) # Register the window class. wc = WNDCLASS() hinst = wc.hInstance = GetModuleHandle(None) wc.lpszClassName = 'FlexGetTaskbar' if not self.windows_classAtom: self.windows_classAtom = RegisterClass(wc) style = WS_OVERLAPPED | WS_SYSMENU hwnd = CreateWindow( self.windows_classAtom, 'Taskbar', style, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hinst, None, ) UpdateWindow(hwnd) hicon = LoadIcon(0, IDI_APPLICATION) # Hackily grab the icon from the webui if possible icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE try: import flexget.ui icon_path = os.path.join(flexget.ui.__path__[0], 'v1', 'app', 'favicon.ico') hicon = LoadImage(hinst, icon_path, IMAGE_ICON, 0, 0, icon_flags) except Exception as e: logger.debug('Error trying to get flexget icon from webui folder: {}', e) # Taskbar icon flags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO nid = ( hwnd, 0, flags, WM_USER + 20, hicon, 'FlexGet Notification', message, config['timeout'] * 1000, title, ) Shell_NotifyIcon(NIM_ADD, nid)
if sys.platform.startswith('win'): notify = windows_notify elif sys.platform == 'darwin': notify = mac_notify else: notify = linux_notify
[docs] @event('plugin.register') def register_plugin(): plugin.register(NotifyToast, plugin_name, api_ver=2, interfaces=['notifiers'])