Ejemplo n.º 1
0
def get_text():
    pb = Pushbullet('PUSHBULLET API KEY')
    while True:
        pushes = pb.get_pushes()
        latest = pushes[0]['body']
        check = open('2fa.txt', 'r').read()
        if latest == check:
            time.sleep(10)
        else:
            open('2fa.txt', 'w').close()
            with open("2fa.txt", "w") as text_file:
                text_file.write(latest)
            break
    pb.delete_push(pushes[0].get("iden"))
    code = latest.replace(' is your Amazon security code.', '')
    return code
Ejemplo n.º 2
0
class PushBulletRoute(Route):
    """SmartHome using pushbullet."""

    def __init__(self, cfg):
        super(PushBulletRoute).__init__(cfg)
        
        self.lastFetch = time.time()
        self.apiKey = self.cfg.get('global', 'api_key')
        self.pb = Pushbullet(self.apiKey)

    def run(self):
        try:
            deviceIden = self.cfg.get('global', 'device_iden')
        except NoOptionError:
            deviceIden = self.pb.new_device('SmartHome').device_iden
            self.cfg.set('global', 'device_iden', deviceIden)
            with open(CONFIG_FILE, 'w') as f:
                self.cfg.write(f)

        def on_push(msg):
            journal.send('Got message: ' + json.dumps(msg))
            try:
                pushes = self.pb.get_pushes(self.lastFetch)
                journal.send('Got pushes: ' + json.dumps(pushes))
                self.lastFetch = time.time()
                if type(pushes) is types.TupleType and len(pushes)>1 \
                        and type(pushes[1]) is types.ListType:
                    for push in pushes[1]:
                        journal.send('Check push: ' + json.dumps(push))
                        if push.has_key('target_device_iden') and push['target_device_iden'] == deviceIden:
                            cmd = json.loads(push['body'])
                            self.home.followCommand(cmd)
                            fromIden = push['source_device_iden']
                            fromDevice = self.getDevice(fromIden)
                            if fromDevice is None:
                                journal.send('get_status: Cannot find device with iden "' + fromIden + '"', PRIORITY=journal.LOG_ERR)
                                return
                            self.pb.push_note('status', self.home.getStatus(), fromDevice)
            except (PushbulletError, IOError, ValueError, KeyError), e:
                journal.send(str(e), PRIORITY=journal.LOG_ERR)

        lsr = Listener(Account(self.apiKey), on_push)
        lsr.run()
Ejemplo n.º 3
0
    print('configuration directory is %s' % config.config_dir())

pb = Pushbullet(valid.credentials.pushbullet)

phone = pb.devices[1]

r = requests.post(
    'https://www.tarsnap.com/manage.cgi?action=verboseactivity&format=csv',
    data={
        "address": valid.credentials.tarsnap_address,
        "password": valid.credentials.tarsnap_password
    })

# We don't care about the pushes, but we want to use the API every time this script runs so the account does not
# get deactivated :/
pushes = pb.get_pushes()

balances = OrderedDict()
last_balance = 0.0
usage_log = OrderedDict()
if r.status_code == 200:
    if "Password is incorrect" in r.text:
        print("Password is incorrect.")
        sys.exit()
    raw_csv = StringIO(r.text)
    for row in csv.DictReader(raw_csv):
        if row["RECTYPE"] == 'Balance':
            balances[row["DATE"]] = float(row["BALANCE"])
        else:
            usage_log[row["DATE"]] = row
    last_balance = next(reversed(balances.values()))
Ejemplo n.º 4
0
class ServicePushbullet(ServicesMgr):
    """
        Service Pushbullet
    """
    def __init__(self, token=None, **kwargs):
        super(ServicePushbullet, self).__init__(token, **kwargs)
        self.AUTH_URL = 'https://pushbullet.com/authorize'
        self.ACC_TOKEN = 'https://pushbullet.com/access_token'
        self.REQ_TOKEN = 'https://api.pushbullet.com/oauth2/token'
        self.consumer_key = settings.TH_PUSHBULLET_KEY['client_id']
        self.consumer_secret = settings.TH_PUSHBULLET_KEY['client_secret']
        self.scope = 'everything'
        self.service = 'ServicePushbullet'
        self.oauth = 'oauth2'
        if token:
            self.token = token
            self.pushb = Pushb(token)

    def read_data(self, **kwargs):
        """
            get the data from the service
            as the pushbullet service does not have any date
            in its API linked to the note,
            add the triggered date to the dict data
            thus the service will be triggered when data will be found

            :param kwargs: contain keyword args : trigger_id at least
            :type kwargs: dict

            :rtype: list
        """
        trigger_id = kwargs.get('trigger_id')
        trigger = Pushbullet.objects.get(trigger_id=trigger_id)
        date_triggered = kwargs.get('date_triggered')
        data = list()
        pushes = self.pushb.get_pushes()
        for p in pushes:
            title = 'From Pushbullet'
            created = arrow.get(p.get('created'))
            if created > date_triggered and p.get('type') == trigger.type and\
               (p.get('sender_email') == p.get('receiver_email') or p.get('sender_email') is None):
                title = title + ' Channel' if p.get('channel_iden') and p.get('title') is None else title
                # if sender_email and receiver_email are the same ;
                # that means that "I" made a note or something
                # if sender_email is None, then "an API" does the post

                body = p.get('body')
                data.append({'title': title, 'content': body})
                # digester
                self.send_digest_event(trigger_id, title, '')

        cache.set('th_pushbullet_' + str(trigger_id), data)
        return data

    def save_data(self, trigger_id, **data):
        """
            let's save the data
            :param trigger_id: trigger ID from which to save data
            :param data: the data to check to be used and save
            :type trigger_id: int
            :type data:  dict
            :return: the status of the save statement
            :rtype: boolean
        """
        title, content = super(ServicePushbullet, self).save_data(trigger_id, **data)
        if self.token:
            trigger = Pushbullet.objects.get(trigger_id=trigger_id)
            if trigger.type == 'note':
                status = self.pushb.push_note(title=title, body=content)
            elif trigger.type == 'link':
                status = self.pushb.push_link(title=title, body=content, url=data.get('link'))
                sentence = str('pushbullet {} created').format(title)
                logger.debug(sentence)
            else:
                # no valid type of pushbullet specified
                msg = "no valid type of pushbullet specified"
                logger.critical(msg)
                update_result(trigger_id, msg=msg, status=False)
                status = False
        else:
            msg = "no token or link provided for trigger ID {} ".format(trigger_id)
            logger.critical(msg)
            update_result(trigger_id, msg=msg, status=False)
            status = False
        return status
Ejemplo n.º 5
0
class ServicePushbullet(ServicesMgr):
    """
        Service Pushbullet
    """
    def __init__(self, token=None, **kwargs):
        super(ServicePushbullet, self).__init__(token, **kwargs)
        self.AUTH_URL = 'https://pushbullet.com/authorize'
        self.ACC_TOKEN = 'https://pushbullet.com/access_token'
        self.REQ_TOKEN = 'https://api.pushbullet.com/oauth2/token'
        self.consumer_key = settings.TH_PUSHBULLET['client_id']
        self.consumer_secret = settings.TH_PUSHBULLET['client_secret']
        self.scope = 'everything'
        self.service = 'ServicePushbullet'
        self.oauth = 'oauth2'
        if token:
            self.token = token
            self.pushb = Pushb(token)

    def read_data(self, **kwargs):
        """
            get the data from the service
            as the pushbullet service does not have any date
            in its API linked to the note,
            add the triggered date to the dict data
            thus the service will be triggered when data will be found

            :param kwargs: contain keyword args : trigger_id at least
            :type kwargs: dict

            :rtype: list
        """
        trigger_id = kwargs.get('trigger_id')
        trigger = Pushbullet.objects.get(trigger_id=trigger_id)
        date_triggered = kwargs.get('date_triggered')
        data = list()
        pushes = self.pushb.get_pushes()
        for p in pushes:
            title = 'From Pushbullet'
            created = arrow.get(p.get('created'))
            if created > date_triggered and p.get('type') == trigger.type and\
                (p.get('sender_email') == p.get('receiver_email') or
                 p.get('sender_email') is None):
                title = title + ' Channel' if p.get('channel_iden') and \
                                              p.get('title') is None else title
                # if sender_email and receiver_email are the same ;
                # that means that "I" made a note or something
                # if sender_email is None, then "an API" does the post

                body = p.get('body')
                data.append({'title': title, 'content': body})

        cache.set('th_pushbullet_' + str(trigger_id), data)
        return data

    def save_data(self, trigger_id, **data):
        """
            let's save the data
            :param trigger_id: trigger ID from which to save data
            :param data: the data to check to be used and save
            :type trigger_id: int
            :type data:  dict
            :return: the status of the save statement
            :rtype: boolean
        """
        title, content = super(ServicePushbullet, self).save_data(trigger_id,
                                                                  **data)

        if self.token:
            trigger = Pushbullet.objects.get(trigger_id=trigger_id)
            if trigger.type == 'note':
                status = self.pushb.push_note(title=title, body=content)
            elif trigger.type == 'link':
                status = self.pushb.push_link(title=title, body=content,
                                              url=data.get('link'))
                sentence = str('pushbullet {} created').format(title)
                logger.debug(sentence)
            else:
                # no valid type of pushbullet specified
                msg = "no valid type of pushbullet specified"
                logger.critical(msg)
                update_result(trigger_id, msg=msg)
                status = False
        else:
            msg = "no token or link provided for trigger " \
                  "ID {} ".format(trigger_id)
            logger.critical(msg)
            update_result(trigger_id, msg=msg)
            status = False
        return status
Ejemplo n.º 6
0
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, GPIO.LOW)


def notification(pitch, duration):
    period = 1.0 / pitch
    delay = period / 2
    cycles = int(duration * pitch)
    for i in range(cycles):
        GPIO.output(pin, True)
        time.sleep(delay)
        GPIO.output(pin, False)
        time.sleep(delay)


while True:
    count = len(pb.get_pushes())
    pushes = pb.get_pushes()
    if count >= 1:
        if not pushes[0]['sender_email'] == me:
            notification(10, 0.5)
            time.sleep(0.25)
            notification(20, 0.5)
            time.sleep(0.25)
    else:
        GPIO.output(pin, GPIO.LOW)
    print 'Check In Progress'
    time.sleep(SLEEP)
Ejemplo n.º 7
0
class PushBulletWSClient(WebSocketBaseClient):
    name = "pushbullet"

    def __init__(self, interface, url):
        """ Initializes the PB WS Client"""
        super().__init__(url)

        self.pb = Pushbullet(cfg.PUSHBULLET_KEY)
        self.manager = WebSocketManager()
        self.interface = interface

        self.device = None
        for i, device in enumerate(self.pb.devices):
            if device.nickname == 'pai':
                logger.debug("Device found")
                self.device = device
                break
        else:
            logger.exception("Device not found. Creating 'pai' device")
            self.device = self.pb.new_device(nickname='pai', icon='system')

    def stop(self):
        self.terminate()
        self.manager.stop()

    def handshake_ok(self):
        """ Callback trigger when connection succeeded"""
        logger.info("Handshake OK")
        self.manager.add(self)
        self.manager.start()
        for chat in self.pb.chats:
            logger.debug("Associated contacts: {}".format(chat))

        # Receiving pending messages
        self.received_message(json.dumps({
            "type": "tickle",
            "subtype": "push"
        }))

        self.send_message("Active")

    def received_message(self, message):
        """ Handle Pushbullet message. It should be a command """
        logger.debug("Received Message {}".format(message))

        try:
            message = json.loads(str(message))
        except:
            logger.exception("Unable to parse message")
            return

        if message['type'] == 'tickle' and message['subtype'] == 'push':
            now = time.time()
            pushes = self.pb.get_pushes(modified_after=int(now) - 20,
                                        limit=1,
                                        filter_inactive=True)
            for p in pushes:

                # Ignore messages send by us
                if p.get('direction') == 'self' and p.get('title') == 'pai':
                    #logger.debug('Ignoring message sent')
                    continue

                if p.get('direction') == 'outgoing' or p.get('dismissed'):
                    #logger.debug('Ignoring outgoing dismissed')
                    continue

                if p.get('sender_email_normalized'
                         ) in cfg.PUSHBULLET_CONTACTS or p.get(
                             'direction') == 'self':
                    ret = self.interface.handle_command(p.get('body'))

                    m = "PB {}: {}".format(p.get('sender_email_normalized'),
                                           ret)
                    logger.info(m)
                else:
                    m = "PB {} (UNK): {}".format(
                        p.get('sender_email_normalized'), p.get('body'))
                    logger.warning(m)

                self.send_message(m)
                ps.sendNotification(
                    Notification(sender=self.name,
                                 message=m,
                                 level=EventLevel.INFO))

    def unhandled_error(self, error):
        logger.error("{}".format(error))

        try:
            self.terminate()
        except Exception:
            logger.exception("Closing Pushbullet WS")

        self.close()

    def send_message(self, msg, dstchat=None):
        if dstchat is None:
            dstchat = self.pb.chats

        if not isinstance(dstchat, list):
            dstchat = [dstchat]
        # Push to self
        self.device.push_note("pai", msg)

        for chat in dstchat:
            if chat.email in cfg.PUSHBULLET_CONTACTS:
                try:
                    self.pb.push_note("pai", msg, chat=chat)
                except Exception:
                    logger.exception("Sending message")
                    time.sleep(5)
Ejemplo n.º 8
0
class PushBulletWSClient(WebSocketBaseClient):
    def init(self):
        """ Initializes the PB WS Client"""

        self.pb = Pushbullet(cfg.PUSHBULLET_KEY, cfg.PUSHBULLET_SECRET)
        self.manager = WebSocketManager()
        self.alarm = None

    def set_alarm(self, alarm):
        """ Sets the paradox alarm object """
        self.alarm = alarm

    def handshake_ok(self):
        """ Callback trigger when connection succeeded"""
        logger.info("Handshake OK")
        self.manager.add(self)
        for chat in self.pb.chats:
            logger.debug("Associated contacts: {}".format(chat))

        # Receiving pending messages
        self.received_message(json.dumps({
            "type": "tickle",
            "subtype": "push"
        }))

        self.send_message("Active")

    def handle_message(self, message):
        """ Handle Pushbullet message. It should be a command """

        logger.debug("Received Message {}".format(message))
        try:
            message = json.loads(str(message))
        except:
            logger.exception("Unable to parse message")
            return

        if self.alarm == None:
            return

        if message['type'] == 'tickle' and msg['subtype'] == 'push':
            now = time.time()
            pushes = self.pb.get_pushes(modified_after=int(now) - 10,
                                        limit=1,
                                        filter_inactive=True)

            for p in pushes:
                self.pb.dismiss_push(p.get("iden"))
                self.pb.delete_push(p.get("iden"))

                if p.get('direction') == 'outgoing' or p.get('dismissed'):
                    continue

                if p.get('sender_email_normalized') in PUSHBULLET_CONTACTS:
                    ret = self.send_command(p.get('body'))

                    if ret:
                        logger.info("From {} ACCEPTED: {}".format(
                            p.get('sender_email_normalized'), p.get('body')))
                    else:
                        logger.warning("From {} UNKNOWN: {}".format(
                            p.get('sender_email_normalized'), p.get('body')))
                else:
                    logger.warning("Command from INVALID SENDER {}: {}".format(
                        p.get('sender_email_normalized'), p.get('body')))

    def unhandled_error(self, error):
        logger.error("{}".format(error))

        try:
            self.terminate()
        except:
            logger.exception("Closing Pushbullet WS")

        self.close()

    def send_message(self, msg, dstchat=None):
        for chat in self.pb.chats:
            if chat.email in PUSHBULLET_CONTACTS:
                try:
                    self.pb.push_note("paradox", msg, chat=chat)
                except:
                    logger.exception("Sending message")
                    time.sleep(5)

    def send_command(self, message):
        """Handle message received from the MQTT broker"""
        """Format TYPE LABEL COMMAND """
        tokens = message.split(" ")

        if len(tokens) != 3:
            logger.warning("Message format is invalid")
            return

        if self.alarm == None:
            logger.error("No alarm registered")
            return

        element_type = tokens[0].lower()
        element = tokens[1]
        command = self.normalize_payload(tokens[2])

        # Process a Zone Command
        if element_type == 'zone':
            if command not in ['bypass', 'clear_bypass']:
                logger.error("Invalid command for Zone {}".format(command))
                return

            if not self.alarm.control_zone(element, command):
                logger.warning("Zone command refused: {}={}".format(
                    element, command))

        # Process a Partition Command
        elif element_type == 'partition':
            if command not in ['arm', 'disarm', 'arm_stay', 'arm_sleep']:
                logger.error(
                    "Invalid command for Partition {}".format(command))
                return

            if not self.alarm.control_partition(element, command):
                logger.warning("Partition command refused: {}={}".format(
                    element, command))

        # Process an Output Command
        elif element_type == 'output':
            if command not in ['on', 'off', 'pulse']:
                logger.error("Invalid command for Output {}".format(command))
                return

            if not self.alarm.control_output(element, command):
                logger.warning("Output command refused: {}={}".format(
                    element, command))
        else:
            logger.error("Invalid control property {}".format(element))

    def normalize_payload(self, message):
        message = message.strip().lower()

        if message in ['true', 'on', '1', 'enable']:
            return 'on'
        elif message in ['false', 'off', '0', 'disable']:
            return 'off'
        elif message in [
                'pulse', 'arm', 'disarm', 'arm_stay', 'arm_sleep', 'bypass',
                'clear_bypass'
        ]:
            return message

        return None

    def notify(self, source, message, level):
        if level < logging.INFO:
            return

        try:
            self.send_message("{}".format(message))
        except:
            logging.exception("Pushbullet notify")

    def event(self, raw):
        """Handle Live Event"""
        return

    def change(self, element, label, property, value):
        """Handle Property Change"""
        #logger.debug("Property Change: element={}, label={}, property={}, value={}".format(
        #    element,
        #    label,
        #    property,
        #    value))
        return
Ejemplo n.º 9
0
class PushbulletManager():
    """Manager interface to and from PushBullet.

    Note:
       Requires that the environment variable PUSHBULLET_API_TOKEN is set.
    """
    REMINDER_KEYWORD = r"remi(nder)?\s+"
    last_mod_time = 0.0

    def __init__(self):
        """Create PushBullet listener."""
        self.logger = logging.getLogger(__name__)
        self.logger.info("Starting PushbulletManager...")
        self.pb = Pushbullet(os.environ.get("PUSHBULLET_API_TOKEN"))
        push_list = self.pb.get_pushes(limit=1)
        if push_list:
            self.last_mod_time = push_list[0]["modified"]
        self.pb_listener = Listener(account=self.pb,
                                    on_push=self.pb_on_push,
                                    on_error=self.pb_on_error,
                                    http_proxy_host=HTTP_PROXY_HOST,
                                    http_proxy_port=HTTP_PROXY_PORT)
        self.rmc = ReminderMessageConsumer()
        self.rmc.start()

    def run(self):
        """Listen for messages on PushBullet websocket."""
        try:
            self.logger.info('Waiting for messages. To exit press CTRL+C')
            self.pb_listener.run_forever()
        except KeyboardInterrupt:
            self.rmc.stop()
            self.rmc.join()
            raise
        finally:
            self.pb_listener.close()

    def pb_on_error(self, websocket, exception):
        """Error handler for the PushBullet listener.

        Re-raise any exception that occurs, as otherwise it will be swallowed
        up by the PushBullet Listener.
        """
        # If a KeyboardInterrupt is raised during
        # self.pb_listener.run_forever(), this method is invoked, which is the
        # only way we'll know about it.
        raise exception

    def pb_on_push(self, data):
        """Push handler for the PushBullet listener"""
        try:
            self.logger.debug("Received tickle: %s", str(data))
            push_list = self.pb.get_pushes(limit=1,
                                           modified_after=self.last_mod_time)
            if not push_list:
                self.logger.debug("Ignoring tickle")
                return
            latest = push_list[0]
            self.last_mod_time = latest["modified"]
            self.logger.info("Latest Push: %s", str(latest))
            self.process_push(latest)
        except Exception:
            self.logger.exception("Error processing push message")

    def process_push(self, push):
        """Process PushBullet JSON message.

        Passes the message to the ReminderManager if appropriate
        """
        # Pushbullet can also send Links and Images, which don't have a "body"
        if "body" not in push:
            self.logger.info("Ignoring non-note push: id=%s type=%s",
                             push["iden"], push["type"])
            return
        if push["dismissed"]:
            self.logger.debug("Ignoring dismissed push: id=%s, body=%s",
                              push["iden"], push["body"])
            return
        # We require the reminder keyword at beginning of message, to avoid
        # an infinite loop of pushbullets.
        if not bool(re.match(self.REMINDER_KEYWORD, push["body"], re.I)):
            self.logger.info("Ignoring non-reminder push: id=%s, body=%s",
                             push["iden"], push["body"])
            return
        self.logger.info('Received push: id=%s, body=%s', push["iden"],
                         push["body"])
        # Strip off reminder keyword first
        body = re.sub(r'^\S+\s+', '', push["body"])
        request = {"body": body, "source": "pushbullet"}
        self.logger.info("Sending request to reminder RPC service")
        try:
            reminder_rpc = ReminderRpcClient()
            response = reminder_rpc.call(request)
            self.logger.info("Reminder RPC response: %s", str(response))
        except ResponseTimeout as rto:
            self.logger.exception(str(rto))
            response = {
                "error": {
                    "code": 0,
                    "text": "Unable to connect to server"
                }
            }
        if "error" in response:
            self.logger.error("Reminder RPC returned error code '%d' (%s)",
                              response["error"]["code"],
                              response["error"]["text"])
            self.pb.push_note("Error Setting Reminder",
                              response["error"]["text"])
        else:
            self.logger.info("Received response: %s", str(response))
            self.logger.info("Dismissing push: id=%s", push["iden"])
            self.pb.dismiss_push(push["iden"])
            self.logger.info("Sending response: %s", response["data"]["text"])
            self.pb.push_note("Got it!", response["data"]["text"])
Ejemplo n.º 10
0
class PushbulletBackend(Backend):
    """
    This backend will listen for events on a Pushbullet (https://pushbullet.com)
    channel and propagate them to the bus. This backend is quite useful if you
    want to synchronize events and actions with your mobile phone (through the
    Pushbullet app and/or through Tasker), synchronize clipboards, send pictures
    and files to other devices etc. You can also wrap Platypush messages as JSON
    into a push body to execute them.

    Triggers:

        * :class:`platypush.message.event.pushbullet.PushbulletEvent` if a new push is received

    Requires:

        * **requests** (``pip install requests``)
        * **pushbullet.py** (``pip install git+https://github.com/rbrcsk/pushbullet.py``)
    """

    def __init__(self, token, device='Platypush', proxy_host=None,
                 proxy_port=None, **kwargs):
        """
        :param token: Your Pushbullet API token, see
            https://docs.pushbullet.com/#authentication
        :type token: str

        :param device: Name of the virtual device for Platypush (default: Platypush)
        :type device: str

        :param proxy_host: HTTP proxy host (default: None)
        :type proxy_host: str

        :param proxy_port: HTTP proxy port (default: None)
        :type proxy_port: int
        """

        super().__init__(**kwargs)

        self.token = token
        self.device_name = device
        self.proxy_host = proxy_host
        self.proxy_port = proxy_port
        self.pb = Pushbullet(token)
        self.listener = None

        try:
            self.device = self.pb.get_device(self.device_name)
        except:
            self.device = self.pb.new_device(self.device_name)

        self.pb_device_id = self.get_device_id()

    def _get_latest_push(self):
        t = int(time.time()) - 5
        pushes = self.pb.get_pushes(modified_after=str(t), limit=1)
        if pushes:
            return pushes[0]

    def on_push(self):
        def callback(data):
            try:
                # Parse the push
                try:
                    data = json.loads(data) if isinstance(data, str) else data
                except Exception as e:
                    self.logger.exception(e)
                    return

                # If it's a push, get it
                if data['type'] == 'tickle' and data['subtype'] == 'push':
                    push = self._get_latest_push()
                elif data['type'] == 'push':
                    push = data['push']
                else: return  # Not a push notification

                if not push:
                    return

                # Post an event, useful to react on mobile notifications if
                # you enabled notification mirroring on your PushBullet app
                event = PushbulletEvent(**push)
                self.on_message(event)

                if 'body' not in push: return
                self.logger.debug('Received push: {}'.format(push))

                body = push['body']
                try:
                    body = json.loads(body)
                    self.on_message(body)
                except Exception as e:
                    self.logger.debug(('Unexpected message received on the ' +
                                        'Pushbullet backend: {}. Message: {}')
                                        .format(str(e), body))

            except Exception as e:
                self.logger.exception(e)
                return

        return callback

    def get_device_id(self):
        try:
            return self.pb.get_device(self.device_name).device_iden
        except Exception as e:
            device = self.pb.new_device(self.device_name, model='Platypush virtual device',
                                        manufacturer='platypush', icon='system')

            self.logger.info('Created Pushbullet device {}'.format(
                self.device_name))

            return device.device_iden

    def send_message(self, msg):
        if isinstance(msg, dict):
            msg = json.dumps(msg)
        self.device.push_note(title=None, body=str(msg))

    def close(self):
        if self.listener:
            self.listener.close()

    def on_stop(self):
        return self.close()

    def run(self):
        super().run()

        self.logger.info('Initialized Pushbullet backend - device_id: {}'
                     .format(self.device_name))

        self.listener = Listener(account=self.pb, on_push=self.on_push(),
                                 http_proxy_host=self.proxy_host,
                                 http_proxy_port=self.proxy_port)

        self.listener.run_forever()
Ejemplo n.º 11
0
class PushbulletBackend(Backend):
    """
    This backend will listen for events on a Pushbullet (https://pushbullet.com)
    channel and propagate them to the bus. This backend is quite useful if you
    want to synchronize events and actions with your mobile phone (through the
    Pushbullet app and/or through Tasker), synchronize clipboards, send pictures
    and files to other devices etc. You can also wrap Platypush messages as JSON
    into a push body to execute them.

    Triggers:

        * :class:`platypush.message.event.pushbullet.PushbulletEvent` if a new push is received

    Requires:

        * **pushbullet.py** (``pip install git+https://github.com/pushbullet.py/pushbullet.py``)

    """
    def __init__(self,
                 token: str,
                 device: str = 'Platypush',
                 proxy_host: Optional[str] = None,
                 proxy_port: Optional[int] = None,
                 **kwargs):
        """
        :param token: Your Pushbullet API token, see https://docs.pushbullet.com/#authentication
        :param device: Name of the virtual device for Platypush (default: Platypush)
        :param proxy_host: HTTP proxy host (default: None)
        :param proxy_port: HTTP proxy port (default: None)
        """
        super().__init__(**kwargs)

        self.token = token
        self.device_name = device
        self.proxy_host = proxy_host
        self.proxy_port = proxy_port
        self.device = None
        self.pb_device_id = None
        self.pb = None
        self.listener = None

    def _initialize(self):
        # noinspection PyPackageRequirements
        from pushbullet import Pushbullet
        self.pb = Pushbullet(self.token)

        try:
            self.device = self.pb.get_device(self.device_name)
        except Exception as e:
            self.logger.info(
                f'Device {self.device_name} does not exist: {e}. Creating it')
            self.device = self.pb.new_device(self.device_name)

        self.pb_device_id = self.get_device_id()

    def _get_latest_push(self):
        t = int(time.time()) - 5
        pushes = self.pb.get_pushes(modified_after=str(t), limit=1)
        if pushes:
            return pushes[0]

    def on_push(self):
        def callback(data):
            try:
                # Parse the push
                try:
                    data = json.loads(data) if isinstance(data, str) else data
                except Exception as e:
                    self.logger.exception(e)
                    return

                # If it's a push, get it
                if data['type'] == 'tickle' and data['subtype'] == 'push':
                    push = self._get_latest_push()
                elif data['type'] == 'push':
                    push = data['push']
                else:
                    return  # Not a push notification

                if not push:
                    return

                # Post an event, useful to react on mobile notifications if
                # you enabled notification mirroring on your PushBullet app
                event = PushbulletEvent(**push)
                self.on_message(event)

                if 'body' not in push:
                    return
                self.logger.debug(f'Received push: {push}')

                body = push['body']
                try:
                    body = json.loads(body)
                    self.on_message(body)
                except Exception as e:
                    self.logger.debug(
                        'Unexpected message received on the ' +
                        f'Pushbullet backend: {e}. Message: {body}')
            except Exception as e:
                self.logger.exception(e)
                return

        return callback

    def get_device_id(self):
        # noinspection PyBroadException
        try:
            return self.pb.get_device(self.device_name).device_iden
        except Exception:
            device = self.pb.new_device(self.device_name,
                                        model='Platypush virtual device',
                                        manufacturer='platypush',
                                        icon='system')

            self.logger.info(f'Created Pushbullet device {self.device_name}')
            return device.device_iden

    def close(self):
        if self.listener:
            self.listener.close()
            self.listener = None

    def on_stop(self):
        self.logger.info('Received STOP event on the Pushbullet backend')
        super().on_stop()
        self.close()
        self.logger.info('Pushbullet backend terminated')

    def on_close(self, err=None):
        def callback(*_):
            self.listener = None
            raise RuntimeError(err or 'Connection closed')

        return callback

    def on_error(self, *_):
        def callback(*args):
            self.logger.error(f'Pushbullet error: {args}')
            try:
                if self.listener:
                    self.listener.close()
            except Exception as e:
                self.logger.error(
                    'Error on Pushbullet connection close upon error')
                self.logger.exception(e)
            finally:
                self.listener = None

        return callback

    def on_open(self):
        def callback(*_):
            self.logger.info('Pushbullet service connected')

        return callback

    def run_listener(self):
        from .listener import Listener

        self.logger.info(
            f'Initializing Pushbullet backend - device_id: {self.device_name}')
        self.listener = Listener(account=self.pb,
                                 on_push=self.on_push(),
                                 on_open=self.on_open(),
                                 on_close=self.on_close(),
                                 on_error=self.on_error(),
                                 http_proxy_host=self.proxy_host,
                                 http_proxy_port=self.proxy_port)

        self.listener.run_forever()

    def run(self):
        super().run()
        initialized = False

        while not initialized:
            try:
                self._initialize()
                initialized = True
            except Exception as e:
                self.logger.exception(e)
                self.logger.error(f'Pushbullet initialization error: {e}')
                time.sleep(10)

        while not self.should_stop():
            try:
                self.run_listener()
            except Exception as e:
                self.logger.exception(e)
                time.sleep(10)
                self.logger.info('Retrying connection')
Ejemplo n.º 12
0
def watch_tgtg():
    if tgtg_email is not None and tgtg_password is not None:
        tgtg_client = TgtgClient(email=tgtg_email, password=tgtg_password)
    elif tgtg_user_id is not None and tgtg_access_token is not None:
        tgtg_client = TgtgClient(user_id=tgtg_user_id,
                                 access_token=tgtg_access_token)
    else:
        print(
            "Neither email and password nor user id and access token for TGTG were specified. Aborting..."
        )

    pb_client = None
    if pb_api_key is not None:
        pb_client = Pushbullet(pb_api_key)

    pb_notification_channel = pb_client.get_channel(
        pb_notification_channel_tag
    ) if pb_notification_channel_tag is not None else None

    if bool(environ.get('PB_CLEAR_CHANNEL',
                        False)) and pb_notification_channel is not None:
        for push in pb_client.get_pushes():
            if 'channel_iden' in push and push[
                    'channel_iden'] == pb_notification_channel.iden:
                pb_client.delete_push(push['iden'])

    available_items = {}
    while True:
        for available_item in available_items.values():
            available_item['still_available'] = False

        items = tgtg_client.get_items(favorites_only=True,
                                      latitude=tgtg_search_lat,
                                      longitude=tgtg_search_lon,
                                      radius=tgtg_search_range)

        print(
            f"Found {len(items)} favourited stores of which {len([_ for _ in items if _['items_available'] > 0])} have available items..."
        )
        for item in items:
            if item['items_available'] > 0:
                if item['item']['item_id'] in available_items:
                    available_items[item['item']
                                    ['item_id']]['still_available'] = True
                else:
                    print(
                        f"Found newly available product: {item['display_name']} since {datetime.now().strftime('%H:%M:%S (%d.%m.%Y)')}"
                    )
                    if pb_client is not None:
                        push_guid = uuid4().hex
                        pb_client.push_link(
                            f"New TGTG product available",
                            f"https://share.toogoodtogo.com/item/{item['item']['item_id']}",
                            f"{item['display_name']} since {datetime.now().strftime('%H:%M:%S (%d.%m.%Y)')}",
                            channel=pb_notification_channel,
                            guid=push_guid)
                    available_items[item['item']['item_id']] = {
                        'item': item,
                        'still_available': True,
                        'push_guid': push_guid
                    }

        keys_to_delete = []
        for available_item_id, available_item in available_items.items():
            if not available_item['still_available']:
                print(
                    f"Product is no longer available: {available_item['item']['display_name']} since {datetime.now().strftime('%H:%M:%S (%d.%m.%Y)')}"
                )
                if pb_client is not None:
                    push_to_delete = next(
                        (push
                         for push in pb_client.get_pushes() if 'guid' in push
                         and push['guid'] == available_item['push_guid']),
                        None)
                    if push_to_delete is not None:
                        pb_client.delete_push(push_to_delete['iden'])

                keys_to_delete.append(available_item_id)

        for key_to_delete in keys_to_delete:
            del available_items[key_to_delete]

        print(
            f"All favourited stores were processed. Sleeping {environ.get('SLEEP_INTERVAL', '60')} seconds..."
        )
        time.sleep(int(environ.get('SLEEP_INTERVAL', '60')))
Ejemplo n.º 13
0
def lambda_handler(*args):
    timetable = {
        '1': '08:40',
        '2': '09:40',
        '3': '10:40',
        '4': '11:40',
        '5': '12:40',
        '6': '13:30',
        '7': '14:30',
        '8': '15:30',
        '9': '16:30',
        '10': '17:40',
        '11': '18:40',
        '12': '19:40',
        '13': '20:40'
    }

    school_ip = {
        'futakotamagawa': '125.206.202.147',
        'seijo': '153.150.125.233',
        'shakujii': '221.186.136.107',
        'akitsu': '125.206.199.163',
        'tsunashima': '125.206.214.67'
    }

    IP = school_ip[os.environ['KOYAMA_LOC']]
    LOGIN_URL = 'http://{}/scripts/mtr0010.asp'.format(IP)
    CALENDAR_URL = 'http://{}/scripts/mtr1010.asp'.format(IP)

    browser = mechanize.Browser()
    browser.open(LOGIN_URL)
    browser.form = list(browser.forms())[0]

    un_control = browser.form.find_control('mt0010uid')
    un_control.value = os.environ['KOYAMA_ID']
    password_control = browser.form.find_control('mt0010pwd')
    password_control.value = os.environ['KOYAMA_PW']

    browser.submit()
    browser.open(CALENDAR_URL)

    all_available = {}
    all_reserved = {}
    for i in xrange(0, int(os.environ['MAX_WEEKS'])):
        soup = BeautifulSoup(
            browser.response().read(),
            'html.parser',
            from_encoding='shift-jis')  # doesn't work with lxml/xml
        available = soup.find_all('input', src='/images/ko2_kusya.gif')
        print('week {}: {} available'.format(str(i), str(len(available))))
        for date in available:
            period = date.attrs['name'][1:]
            date_string = date.parent.parent.contents[1].text
            try:
                all_available[date_string].append(timetable[period])
            except KeyError:
                all_available[date_string] = [timetable[period]]
        try:
            browser.form = browser.forms()[0]
            browser.submit('next')
        except:
            break

    print(sorted(all_available))
    message_text = u'\n'.join([
        u'{}: {}'.format(date, ', '.join(times))
        for (date, times) in sorted(all_available.iteritems())
    ])

    if os.environ['KOYAMA_PUSH_MODE'] in ('line', 'both'):
        if all_available:
            message_text += u'\n\n' + CALENDAR_URL
            url = 'https://api.line.me/v2/bot/message/push'
            headers = {
                'Content-Type':
                'application/json',
                'Authorization':
                'Bearer {{{}}}'.format(
                    os.environ['LINE_CHANNEL_TOKEN'])  # {{ → '{'
            }
            payload = {
                'to': os.environ['LINE_MY_ID'],
                'messages': [{
                    'type': 'text',
                    'text': message_text
                }]
            }
            r = requests.post(url, headers=headers, data=json.dumps(payload))
            print(r)
        else:
            print('None available.')

    if os.environ['KOYAMA_PUSH_MODE'] in ('pushbullet', 'both'):
        pb = Pushbullet(os.environ['PUSHBULLET_TOKEN'])
        if all_available:
            pushes = pb.get_pushes()
            try:
                most_recent = [
                    push for push in pushes
                    if push['sender_name'] == 'Koyama Alert'
                ][0]
                if most_recent['body'] != message_text:
                    pb.dismiss_push(most_recent['iden'])
                    push = push_to_pushbullet(pb, message_text)
            except IndexError:
                push = push_to_pushbullet(pb, message_text)
            print(push)
        else:
            undismissed = [
                push['iden'] for push in pb.get_pushes() if
                push['sender_name'] == 'Koyama Alert' and not push['dismissed']
            ]
            for iden in undismissed:
                pb.dismiss_push(iden)
            print('None available. Dismissed pushes.')

    return None
Ejemplo n.º 14
0
class Pushlistener(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self, name="PbThread")
        self.api_key=api_key
        self.pb = Pushbullet(self.api_key)
        self.ws = websocket.WebSocket()
        self.ws.connect("wss://stream.pushbullet.com/websocket/{0}".format(self.api_key))
        self.last_time=0
        self.data=''
        self.setDaemon(True)
        self.interpreters=[]
        self.devices=[x.nickname.encode('UTF-8') for x in self.pb.devices]
        if DEVICE_NAME not in self.devices:
            self.pb.new_device('DEVICE_NAME')

    def run(self):
        while(1):
            self.result=json.loads(self.ws.recv())
            self.res_type=self.result.get("type")
            if self.res_type!='nop':
                self.context_matcher()

		

    def context_matcher(self):
        if self.result.get("type")=='tickle':
            if self.result.get('subtype')=='push':
                pushes = self.pb.get_pushes()
                latest=pushes[1][0]
                if latest.get('target_device_iden')==PUSHBULLET_ID:
                    self.body=latest['body']
                    os.system('mpg321 {0} 2>/dev/null'.format(MESSAGE_FILE))
                    self.notify({'text':self.body})
                    ny.show(self.body)

    def register(self, interpreter):
        """
        Register interpreters to be notified of new input
        """
        if not interpreter in self.interpreters:
            self.interpreters.append(interpreter)

    def unregister(self, interpreter):
        """
        Unregisters an interpreter
        """
        if interpreter in self.interpreters:
            self.interpreters.remove(interpreter)

    def notify(self, event):
        """
        Notify all interpreters of a received input
        """
        for interpreter in self.interpreters:
            interpreter.on_event(event, self)

    def send(self,device,msg):
        for dev in self.pb.devices:
            print dev.nickname
            if dev.nickname==device:
                dev.push_note(msg,None)
Ejemplo n.º 15
0
import settings
from pushbullet import Pushbullet
pb = Pushbullet(settings.pushBulletApiKey)
print(pb.devices)

address = " 25 E 85th St, 10028 New York, NY"
# push = pb.push_address("home", address)

to_buy = ["milk", "bread", "cider"]
# push = pb.push_list("Shopping list", to_buy)

push = pb.push_link("Cool site", "https://github.com")

pushes = pb.get_pushes()

for p in pushes:
    print(p)
Ejemplo n.º 16
0
class NotificationHandler:
    def __init__(self, pushBulletAPIKey, didReceiveCommand):
        # Setup pushBullet manager
        self.pushBulletAPIKey = pushBulletAPIKey
        self.didReceiveCommand = didReceiveCommand
        self.pushBulletManager = Pushbullet(self.pushBulletAPIKey)
        thread = Thread(target=self.__createListener)
        thread.start()
        # Setup Notification Queue
        self.__setupNotificationQueue()

    def __createListener(self):
        self.listener = Listener(account=self.pushBulletManager,
                                 on_push=self.on_push,
                                 http_proxy_host=HTTP_PROXY_HOST,
                                 http_proxy_port=HTTP_PROXY_PORT)
        self.listener.run_forever()

    def __setupNotificationQueue(self):
        print("setupNotificationQueue")
        self.notificationQueue = Queue(maxsize=QUEUE_MAX_SIZE)
        for i in range(NUM_THREAD):
            worker = Thread(target=self.__motionNotify, args=())
            worker.setDaemon(True)
            worker.start()

    def pushNotificationToMobile(self, filePath):
        self.notificationQueue.put(filePath)

    def pushToMobile(self, dataDictionary):
        print("pushToMobile: ", dataDictionary)
        self.notificationQueue.put(dataDictionary)

    def __motionNotify(self):
        print("__motionNotify called")
        while True:
            dataDictionary = self.notificationQueue.get()
            print("upload and notify: ", dataDictionary)
            if dataDictionary['type'] == "TEXT_MESSAGE":
                push = self.pushBulletManager.push_note(
                    dataDictionary['text'], '')
                print("push result: ", push)
            elif dataDictionary['type'] == "IMAGE_MESSAGE":
                filePath = dataDictionary['filePath']
                print("upload and push file: ", filePath)
                with open(filePath, "rb") as pic:
                    fileData = self.pushBulletManager.upload_file(
                        pic, dataDictionary['fileName'])
                    push = self.pushBulletManager.push_file(**fileData)
                    print("push result: ", push)
                    if "iden" in push:
                        os.remove(filePath)
            elif dataDictionary['type'] == "VIDEO_MESSAGE":
                push = self.pushBulletManager.push_note(
                    "The motion is out. Video uploading...", '')
                filePath = dataDictionary['filePath']
                print("upload and push file: ", filePath)
                with open(filePath, "rb") as pic:
                    fileData = self.pushBulletManager.upload_file(
                        pic, dataDictionary['fileName'])
                    push = self.pushBulletManager.push_file(**fileData)
                    print("push result: ", push)
                    if "iden" in push:
                        os.remove(filePath)
            else:
                print("Not support type: ", dataDictionary['Type'])
            self.notificationQueue.task_done()

    def __delete(self):
        self.listener.close()  # to stop the run_forever()

    def on_push(self, jsonMessage):
        if jsonMessage["type"] == "tickle" and jsonMessage["subtype"] == "push":
            allPushes = self.pushBulletManager.get_pushes()
            latest = allPushes[0]
            if 'body' in latest:
                body = latest['body']
                print(body)
                if body.startswith("@"):
                    self.didReceiveCommand(body)
        #		else:
        #			print("latest pushes: ", latest)
        #	else:
        #		print("latest pushes: ", latest)

    def notifyWithImage(self, filePath):
        with open(filePath, "rb") as pic:
            file_data = self.pushBulletManager.upload_file(pic, "picture.jpg")
            push = self.pushBulletManager.push_file(**file_data)

    def notifyWithVideo(self, filePath):
        with open(filePath, "rb") as pic:
            file_data = self.pushBulletManager.upload_file(pic, "video.h264")
            push = self.pushBulletManager.push_file(**file_data)
Ejemplo n.º 17
0
class PushBulletWSClient(WebSocketBaseClient):

    def init(self, interface):
        """ Initializes the PB WS Client"""

        self.logger = logging.getLogger('PAI').getChild(__name__)
        self.pb = Pushbullet(cfg.PUSHBULLET_KEY, cfg.PUSHBULLET_SECRET)
        self.manager = WebSocketManager()
        self.alarm = None
        self.interface = interface

    def stop(self):
        self.terminate()
        self.manager.stop()

    def set_alarm(self, alarm):
        """ Sets the paradox alarm object """
        self.alarm = alarm

    def handshake_ok(self):
        """ Callback trigger when connection succeeded"""
        self.logger.info("Handshake OK")
        self.manager.add(self)
        self.manager.start()
        for chat in self.pb.chats:
            self.logger.debug("Associated contacts: {}".format(chat))

        # Receiving pending messages
        self.received_message(json.dumps({"type": "tickle", "subtype": "push"}))

        self.send_message("Active")

    def received_message(self, message):
        """ Handle Pushbullet message. It should be a command """
        self.logger.debug("Received Message {}".format(message))

        try:
            message = json.loads(str(message))
        except:
            self.logger.exception("Unable to parse message")
            return

        if self.alarm is None:
            return
        if message['type'] == 'tickle' and message['subtype'] == 'push':
            now = time.time()
            pushes = self.pb.get_pushes(modified_after=int(now) - 20, limit=1, filter_inactive=True)
            self.logger.debug("got pushes {}".format(pushes))
            for p in pushes:
                self.pb.dismiss_push(p.get("iden"))
                self.pb.delete_push(p.get("iden"))

                if p.get('direction') == 'outgoing' or p.get('dismissed'):
                    continue

                if p.get('sender_email_normalized') in cfg.PUSHBULLET_CONTACTS:
                    ret = self.interface.send_command(p.get('body'))

                    if ret:
                        self.logger.info("From {} ACCEPTED: {}".format(p.get('sender_email_normalized'), p.get('body')))
                    else:
                        self.logger.warning("From {} UNKNOWN: {}".format(p.get('sender_email_normalized'), p.get('body')))
                else:
                    self.logger.warning("Command from INVALID SENDER {}: {}".format(p.get('sender_email_normalized'), p.get('body')))

    def unhandled_error(self, error):
        self.logger.error("{}".format(error))

        try:
            self.terminate()
        except Exception:
            self.logger.exception("Closing Pushbullet WS")

        self.close()

    def send_message(self, msg, dstchat=None):
        if dstchat is None:
            dstchat = self.pb.chats

        if not isinstance(dstchat, list):
            dstchat = [dstchat]

        for chat in dstchat:
            if chat.email in cfg.PUSHBULLET_CONTACTS:
                try:
                    self.pb.push_note("paradox", msg, chat=chat)
                except Exception:
                    self.logger.exception("Sending message")
                    time.sleep(5)

    def notify(self, source, message, level):
        try:
            if level.value >= EventLevel.WARN.value:
                self.send_message("{}".format(message))
        except Exception:
            logging.exception("Pushbullet notify")

def computeMean(dates):
    data = pd.read_csv('../data.csv', index_col=0)
    mean = np.mean(data[dates[0]:dates[1]])[0]
    return mean


# Enter PushBullet credentials.

apiKey = 'REPLACE_WITH_YOUR_API_KEY'
pb = Pushbullet(apiKey)

# Pull the latest push.

latestPush = pb.get_pushes()[0]

# Get Unix time.

unixTime = time.time()

# Get time since latest message sent.

timeSinceLatest = unixTime - latestPush['created']

# Define regular expression.

pattern = re.compile('\d{4}-\d{1,2}-\d{1,2}')

# Check if dates have been pushed within the last 10 minutes.