#!python import argparse import json import os import re import sys import yaml from pushbullet import Pushbullet from runbullet import parse_config_file from runbullet.backend.kafka import KafkaBackend from runbullet.backend.local import LocalBackend def print_usage(): print ('''Usage: {} [-h|--help] <-t|--target > <-a|--action > payload -h, --help:\t\tShow this help and exit -b, --backend:\tBackend to deliver the message [pushbullet|kafka] (default: whatever specified in your config with pusher=True) -t, --target:\tName of the target device/host -a, --action\tAction to run, it includes both the package name and the method (e.g. shell.exec or music.mpd.play) payload:\t\tArguments to the action '''.format(sys.argv[0])) def get_pb_device_by_name(pb, name): devices = [ _ for _ in pb.devices if _.nickname == name ] return devices[0] if devices else None def send_pb_message(pb, device_name, msg): device = get_pb_device_by_name(pb, name=device_name) if not device: print('Device {} not found - please create a virtual device on ' + 'your PushBullet account'.format(config['backend.pushbullet']['device'])) return pb.push_note('', json.dumps(msg), device) def send_kafka_message(backend, msg): backend.send_msg(msg) def send_local_message(backend, msg): backend.send_msg(msg) def get_backend(config): # TODO Refactor this as something better and reuse the same # backend classes from the runbullet consumer module if 'backend.local' in config \ and 'pusher' in config['backend.local'] \ and config['backend.local']['pusher']: c = config['backend.local'] return LocalBackend({'fifo': c['fifo']}) elif 'backend.pushbullet' in config \ and 'pusher' in config['backend.pushbullet'] \ and config['backend.pushbullet']['pusher']: API_KEY = config['backend.pushbullet']['token'] return Pushbullet(API_KEY) elif 'backend.kafka' in config \ and 'pusher' in config['backend.kafka'] \ and config['backend.kafka']['pusher']: c = config['backend.kafka'] return KafkaBackend({'server':c['server'], 'topic':c['topic']}) def main(): config = parse_config_file() parser = argparse.ArgumentParser() parser.add_argument('--target', '-t', dest='target', required=True, help="Destination of the command") parser.add_argument('--action', '-a', dest='action', required=True, help="Action to execute, as package.method") parser.add_argument('--backend', '-b', dest='backend', required=False, help="Backend to deliver the message " + "[pushbullet|kafka|local] (default: whatever " + "specified in your config with pusher=True)") opts, args = parser.parse_known_args(sys.argv[1:]) payload = {} if len(args) % 2 != 0: raise RuntimeError('Odd number of key-value options passed: {}'. format(args)) if opts.target == 'localhost' and 'backend.local' in config: cfg = config['backend.local'] cfg['pusher'] = True config = { 'backend.local': cfg } if opts.backend: backend_cfg_name = 'backend.' + opts.backend if backend_cfg_name not in config: raise RuntimeError('{} backend specified, but no configuration ' + 'for it available'.format(backend_cfg_name)) cfg = config[backend_cfg_name] cfg['pusher'] = True config = { backend_cfg_name: cfg } backend = get_backend(config) for i in range(0, len(args), 2): payload[re.sub('^-+', '', args[i])] = args[i+1] msg = { 'target': opts.target, 'action': opts.action, **payload, } print('msg: {}'.format(msg)) if isinstance(backend, Pushbullet): send_pb_message(backend, config['backend.pushbullet']['device'], msg) elif isinstance(backend, KafkaBackend): send_kafka_message(backend, msg) elif isinstance(backend, LocalBackend): send_local_message(backend, msg) if __name__ == '__main__': main() # vim:sw=4:ts=4:et: