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

import base64
import datetime

from loguru import logger
from requests.exceptions import RequestException

from flexget import plugin
from flexget.config_schema import one_or_more
from flexget.event import event
from flexget.plugin import PluginWarning
from flexget.utils.requests import Session as RequestSession
from flexget.utils.requests import TimedLimiter

plugin_name = 'pushbullet'
logger = logger.bind(name=plugin_name)

PUSHBULLET_URL = 'https://api.pushbullet.com/v2/pushes'

requests = RequestSession(max_retries=3)
requests.add_domain_limiter(TimedLimiter('pushbullet.com', '5 seconds'))


[docs] class PushbulletNotifier: """Send a Pushbullet notification. Example:: notify: entries: via: pushbullet: apikey: <API_KEY> [device: <DEVICE_IDEN> (can also be a list of device ids, or don't specify any ids to send to all devices)] [email: <EMAIL_ADDRESS> (can also be a list of user email addresses)] [channel: <CHANNEL_TAG> (you can only specify device / email or channel tag, cannot use both)] Configuration parameters are also supported from entries (eg. through set). """ schema = { 'type': 'object', 'properties': { 'api_key': one_or_more({'type': 'string'}), 'device': one_or_more({'type': 'string'}), 'email': one_or_more({'type': 'string', 'format': 'email'}), 'url': {'type': 'string'}, 'channel': {'type': 'string'}, 'file_template': {'type': 'string'}, }, 'required': ['api_key'], 'oneOf': [ {'required': ['device']}, {'required': ['channel']}, {'required': ['email']}, { 'not': { 'anyOf': [ {'required': ['device']}, {'required': ['channel']}, {'required': ['email']}, ] } }, ], 'error_oneOf': 'One (and only one) of `email`, `device` or `channel` are allowed.', 'additionalProperties': False, }
[docs] def notify(self, title, message, config): """Send a Pushbullet notification.""" if config.get('device') and not isinstance(config['device'], list): config['device'] = [config['device']] if config.get('email') and not isinstance(config['email'], list): config['email'] = [config['email']] if not isinstance(config['api_key'], list): config['api_key'] = [config['api_key']] for key in config['api_key']: if config.get('channel'): self.send_push( key, title, message, config.get('url'), config.get('channel'), 'channel_tag' ) elif config.get('device'): for d in config['device']: self.send_push(key, title, message, config.get('url'), d, 'device_iden') elif config.get('email'): for e in config['email']: self.send_push(key, title, message, config.get('url'), e, 'email') else: self.send_push(key, title, message, config.get('url'))
[docs] @staticmethod def send_push(api_key, title, body, url=None, destination=None, destination_type=None): push_type = 'link' if url else 'note' notification = {'type': push_type, 'title': title, 'body': body} if url: notification['url'] = url if destination: notification[destination_type] = destination # Make the request headers = { 'Authorization': b'Basic ' + base64.b64encode(api_key.encode('ascii')), 'Content-Type': 'application/json', 'Accept': 'application/json', 'User-Agent': 'Flexget', } try: response = requests.post(PUSHBULLET_URL, headers=headers, json=notification) except RequestException as e: if e.response is not None: if e.response.status_code == 429: reset_time = e.response.headers.get('X-Ratelimit-Reset') if reset_time: reset_time = datetime.datetime.fromtimestamp(int(reset_time)).strftime( '%Y-%m-%d %H:%M:%S' ) message = f'Monthly Pushbullet database operations limit reached. Next reset: {reset_time}' else: message = e.response.json()['error']['message'] else: message = str(e) raise PluginWarning(message) reset_time = response.headers.get('X-Ratelimit-Reset') remaining = response.headers.get('X-Ratelimit-Remaining') if reset_time and remaining: reset_time = datetime.datetime.fromtimestamp(int(reset_time)) logger.debug( 'Pushbullet notification sent. Database operations remaining until next reset: {}. ' 'Next reset at: {}', remaining, reset_time, )
[docs] @event('plugin.register') def register_plugin(): plugin.register(PushbulletNotifier, plugin_name, api_ver=2, interfaces=['notifiers'])