Source code for flexget.components.notify.notify

import itertools

from loguru import logger

from flexget import plugin
from flexget.config_schema import one_or_more
from flexget.event import event
from flexget.utils.template import get_template

logger = logger.bind(name='notify_entry')

ENTRY_CONTAINERS = ['entries', 'accepted', 'rejected', 'failed', 'undecided']

VIA_SCHEMA = {
    'type': 'array',
    'items': {
        'allOf': [
            {'$ref': '/schema/plugins?interface=notifiers'},
            {
                'maxProperties': 1,
                'error_maxProperties': 'Plugin options indented 2 more spaces than '
                'the first letter of the plugin name.',
                'minProperties': 1,
            },
        ]
    },
}


[docs] class Notify: schema = { 'type': 'object', 'properties': { 'entries': { 'type': 'object', 'properties': { 'title': {'type': 'string', 'default': '{{ title }}'}, 'message': { 'type': 'string', 'default': '{% if series_name is defined %}' '{{ tvdb_series_name|d(series_name) }} ' '{{series_id}} {{tvdb_ep_name|d(' ')}}' '{% elif imdb_name is defined %}' '{{imdb_name}} {{imdb_year}}' '{% elif title is defined %}' '{{ title }}' '{% endif %}', }, 'template': {'type': 'string'}, 'what': one_or_more({'type': 'string', 'enum': ENTRY_CONTAINERS}), 'via': VIA_SCHEMA, }, 'required': ['via'], 'additionalProperties': False, }, 'task': { 'type': 'object', 'properties': { 'title': { 'type': 'string', 'default': '{% if not task.failed and not task.accepted %} Task {{task.name}} did not' ' produce any entries.' '{% else %} [FlexGet] {{task.name}}:' '{% if task.failed %} {{task.failed|length}} failed entries.{% endif %}' '{% if task.accepted %} {{task.accepted|length}} new entries downloaded.{% endif %}' '{% endif %}', }, 'message': {'type': 'string'}, 'template': {'type': 'string', 'default': 'default.template'}, 'always_send': {'type': 'boolean', 'default': False}, 'via': VIA_SCHEMA, }, 'required': ['via'], 'additionalProperties': False, }, 'abort': { 'type': 'object', 'properties': { 'title': {'type': 'string', 'default': 'Task {{ task.name }} has aborted!'}, 'message': {'type': 'string', 'default': 'Reason: {{ task.abort_reason }}'}, 'via': VIA_SCHEMA, }, 'required': ['via'], }, }, 'additionalProperties': False, 'minProperties': 1, 'error_minProperties': 'You must specify at least one of `entries` or `task` in your notify config.', }
[docs] def prepare_config(self, config): if 'entries' in config: config['entries'].setdefault('what', ['accepted']) if not isinstance(config['entries']['what'], list): config['entries']['what'] = [config['entries']['what']] return config
[docs] def send_notification(self, task, *args, **kwargs): send_notification = plugin.get('notification_framework', 'notify').send_notification try: send_notification(*args, **kwargs) except plugin.PluginError as e: logger.error(e) if task.options.test: raise except plugin.PluginWarning as e: logger.warning(e) if task.options.test: raise except Exception: logger.exception('Found an error') if task.options.test: raise
[docs] @plugin.priority(0) def on_task_output(self, task, config): config = self.prepare_config(config) if 'entries' in config: entries = list( itertools.chain(*(getattr(task, what) for what in config['entries']['what'])) ) if not entries: logger.debug('No entries to notify about.') else: # If a file template is defined, it overrides message if config['entries'].get('template'): try: message = get_template(config['entries']['template'], scope='entry') except ValueError: raise plugin.PluginError( 'Cannot locate template on disk: {}'.format( config['entries']['template'] ) ) else: message = config['entries']['message'] for entry in entries: self.send_notification( task, config['entries']['title'], message, config['entries']['via'], template_renderer=entry.render, ) if 'task' in config: if not (task.accepted or task.failed) and not config['task']['always_send']: logger.verbose('No accepted or failed entries, not sending a notification.') return if config['task'].get('message'): template = config['task']['message'] else: try: template = get_template(config['task']['template'], scope='task') except ValueError: raise plugin.PluginError( 'Cannot locate template on disk: {}'.format(config['task']['template']) ) self.send_notification( task, config['task']['title'], template, config['task']['via'], template_renderer=task.render, )
[docs] def on_task_abort(self, task, config): if 'abort' in config: if task.silent_abort: return logger.debug('sending abort notification') self.send_notification( task, config['abort']['title'], config['abort']['message'], config['abort']['via'], template_renderer=task.render, )
[docs] @event('plugin.register') def register_plugin(): plugin.register(Notify, 'notify', api_ver=2)