platypush/notifier.py

154 lines
3.5 KiB
Python

#!/usr/bin/env python
import importlib
import os
import logging
import json
import socket
import subprocess
import sys
import time
import websocket
import yaml
from threading import Thread
from getopt import getopt
__author__ = 'Fabio Manganiello <info@fabiomanganiello.com>'
#-----------#
curdir = os.path.dirname(os.path.realpath(__file__))
lib_dir = curdir + os.sep + 'lib'
sys.path.insert(0, lib_dir)
config_file = curdir + os.sep + 'config.yaml'
config = {}
with open(config_file,'r') as f:
config = yaml.load(f)
API_KEY = config['pushbullet_token']
DEVICE_ID = config['device_id'] \
if 'device_id' in config else socket.gethostname()
DEBUG = config['debug'] if 'debug' in config else False
def on_open(ws):
logging.info('Connection opened')
def on_close(ws):
logging.info('Connection closed')
def on_error(ws, error):
logging.error(error)
def _exec_func(body):
module = None
try:
module = importlib.import_module('plugins.{}'.format(body['plugin']))
except ModuleNotFoundError as e:
logging.warn('No such plugin: {}'.format(body['plugin']))
return
logging.info('Received push addressed to me: {}'.format(body))
args = body['args'] if 'args' in body else {}
cls = getattr(module, body['plugin'].title() + 'Plugin')
instance = cls()
out, err = instance.run(args)
logging.info('Command output: {}'.format(out))
if err:
logging.warn('Command error: {}'.format(err))
def _on_push(ws, data):
data = json.loads(data)
if data['type'] == 'tickle' and data['subtype'] == 'push':
logging.debug('Received push tickle')
return
if data['type'] != 'push':
return # Not a push notification
push = data['push']
logging.debug('Received push: {}'.format(push))
if 'body' not in push:
return
body = push['body']
try:
body = json.loads(body)
except ValueError as e:
return
if 'target' not in body or body['target'] != DEVICE_ID:
return # Not for me
if 'plugin' not in body:
return # No plugin specified
thread = Thread(target=_exec_func, args=(body,))
thread.start()
def on_push(ws, data):
try:
_on_push(ws, data)
except Exception as e:
on_error(ws, e)
def main():
DEBUG = False
config_file = curdir + os.sep + 'config.yaml'
optlist, args = getopt(sys.argv[1:], 'vh')
for opt, arg in optlist:
if opt == '-c':
config_file = arg
if opt == '-v':
DEBUG = True
elif opt == '-h':
print('''
Usage: {} [-v] [-h] [-c <config_file>]
-v Enable debug mode
-h Show this help
-c Path to the configuration file (default: ./config.yaml)
'''.format(sys.argv[0]))
return
config = {}
with open(config_file,'r') as f:
config = yaml.load(f)
API_KEY = config['pushbullet_token']
DEVICE_ID = config['device_id'] \
if 'device_id' in config else socket.gethostname()
if 'debug' in config:
DEBUG = config['debug']
if DEBUG:
logging.basicConfig(level=logging.DEBUG)
websocket.enableTrace(True)
else:
logging.basicConfig(level=logging.INFO)
ws = websocket.WebSocketApp('wss://stream.pushbullet.com/websocket/' +
API_KEY,
on_message = on_push,
on_error = on_error,
on_close = on_close)
ws.on_open = on_open
ws.run_forever()
if __name__ == '__main__':
main()