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
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()
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()))
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
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
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)
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)
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
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"])
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()
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')
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')))
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
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)
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)
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)
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.