def generate_qr_code(self): Logger.info(LOCATION, 'Generating QR Code for alternative pairing...') device_information = self.configuration.get_device_information() image = qrcode.make(json.dumps(device_information), image_factory=PymagingImage) Store.save_qrcode(image) Logger.success(LOCATION, 'QR Code successfully generated')
def get_actions(self): Logger.info(LOCATION, 'Retrieving actions...') try: actions = self.bot_service.get(ACTIONS_ENDPOINT) Logger.success(LOCATION, 'Successfully retrieved ' + str(len(actions)) + ' action(s) from server') Store.set_actions(actions) return actions except falcon.HTTPServiceUnavailable: Logger.warning(LOCATION, 'Unable to retrieve actions from server. Loading locally stored action(s)...') actions = self.store.get_actions() Logger.success(LOCATION, 'Successfully loaded ' + str(len(actions)) + ' cached action(s)') return actions
def _decode(token): try: data = jwt.decode(token, Store.get_bot_public_key(), algorithms=['RS256']) except: Logger.error(LOCATION, 'Could not decode message from BoT.') raise falcon.HTTPInternalServerError return data
class ConfigurationStore: def __init__(self): self.store = Store() def get(self): configuration = Configuration() if not self.store.has_configuration(): return configuration dictionary = self.store.get_configuration() return self._to_configuration(dictionary) # Generating the JSON file def save(self, configuration): dictionary = self._to_dictionary(configuration) self.store.set_configuration(dictionary) @staticmethod def _to_dictionary(configuration): return { MAKER_ID: configuration.get_maker_id(), DEVICE_ID: configuration.get_device_id(), DEVICE_STATUS: configuration.get_device_status(), PUBLIC_KEY: configuration.get_public_key(), PRIVATE_KEY: configuration.get_private_key(), #Added alternative id as a field in json fine ALTERNATIVE_ID: configuration.get_alternative_id() } @staticmethod def _to_configuration(dictionary): configuration = Configuration() configuration.initialize( dictionary[MAKER_ID], dictionary[DEVICE_ID], DeviceStatus[dictionary[DEVICE_STATUS]], # passing the dictionary of alternative value for initialization dictionary[ALTERNATIVE_ID], dictionary[PUBLIC_KEY], dictionary[PRIVATE_KEY]) return configuration
class ConfigurationStore: def __init__(self): self.store = Store() def get(self): configuration = Configuration() if not self.store.has_configuration(): return configuration dictionary = self.store.get_configuration() return self._to_configuration(dictionary) # Generating the JSON file def save(self, configuration): dictionary = self._to_dictionary(configuration) self.store.set_configuration(dictionary) @staticmethod def _to_dictionary(configuration): return { MAKER_ID: configuration.get_maker_id(), DEVICE_ID: configuration.get_device_id(), DEVICE_STATUS: configuration.get_device_status(), PUBLIC_KEY: configuration.get_public_key(), PRIVATE_KEY: configuration.get_private_key(), ALTERNATIVE_ID: configuration.get_alternative_id(), BLUETOOTH_ENABLED: configuration.is_bluetooth_enabled() } @staticmethod def _to_configuration(dictionary): configuration = Configuration() configuration.initialize(dictionary[MAKER_ID], dictionary[DEVICE_ID], DeviceStatus[dictionary[DEVICE_STATUS]], dictionary[BLUETOOTH_ENABLED], dictionary[ALTERNATIVE_ID], dictionary[PUBLIC_KEY], dictionary[PRIVATE_KEY]) return configuration
class ConfigurationStore: def __init__(self): self.store = Store() def get(self): configuration = Configuration() if not self.store.has_configuration(): return configuration dictionary = self.store.get_configuration() return self._to_configuration(dictionary) def save(self, configuration): dictionary = self._to_dictionary(configuration) self.store.set_configuration(dictionary) @staticmethod def _to_dictionary(configuration): return { MAKER_ID: configuration.get_maker_id(), DEVICE_ID: configuration.get_device_id(), DEVICE_STATUS: configuration.get_device_status(), PUBLIC_KEY: configuration.get_public_key(), PRIVATE_KEY: configuration.get_private_key() } @staticmethod def _to_configuration(dictionary): configuration = Configuration() configuration.initialize( dictionary[MAKER_ID], dictionary[DEVICE_ID], DeviceStatus[dictionary[DEVICE_STATUS]], dictionary[PUBLIC_KEY], dictionary[PRIVATE_KEY], ) return configuration
import os import subprocess import sys import re from bot_python_sdk.configuration_service import ConfigurationService from bot_python_sdk.store import Store from bot_python_sdk.logger import Logger configuration_service = ConfigurationService() store = Store() LOCATION = 'Server' # Function to validate the given IP Address def is_valid(ip): regex = '''^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.( 25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.( 25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.( 25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)''' return re.search(regex, ip) if not store.has_configuration(): if len(sys.argv) <= 1: exit('Please add your makerID to configure the SDK: "make server makerID=YOUR_MAKER_ID"') maker_id = sys.argv[1] # 1 -> First argument after server.py configuration_service.initialize_configuration(maker_id) # If OS is windows based, it doesn't support gunicorn so we run waitress
def __init__(self): self.store = Store()
def __init__(self): self.configuration = ConfigurationStore().get() self.bot_service = BoTService() self.key_generator = KeyGenerator() self.store = Store()
class ActionService: def __init__(self): self.configuration = ConfigurationStore().get() self.bot_service = BoTService() self.key_generator = KeyGenerator() self.store = Store() def get_actions(self): Logger.info(LOCATION, 'Retrieving actions...') try: actions = self.bot_service.get(ACTIONS_ENDPOINT) Logger.success( LOCATION, 'Successfully retrieved ' + str(len(actions)) + ' action(s) from server') Store.set_actions(actions) return actions except falcon.HTTPServiceUnavailable: Logger.warning( LOCATION, 'Unable to retrieve actions from server. Loading locally stored action(s)...' ) actions = self.store.get_actions() Logger.success( LOCATION, 'Successfully loaded ' + str(len(actions)) + ' cached action(s)') return actions def trigger(self, action_id, value=None, alternative_id=None): Logger.info(LOCATION, 'Triggering action: ' + action_id) action = self._get_action(action_id) self._validate_frequency(action) Logger.success(LOCATION, 'Action valid') data = self._create_trigger_body(action_id, value, alternative_id) try: self.bot_service.post(ACTIONS_ENDPOINT, data) Logger.success(LOCATION, 'Successfully triggered action: ' + action_id) self.store.set_last_triggered(action_id, time.time()) return True # TODO : Make exception more specific except: Logger.error(LOCATION, 'Unable to trigger action: ' + action_id) return False def _validate_frequency(self, action): last_triggered = self.store.get_last_triggered(action[ACTION_ID]) if last_triggered is None: return # It was never triggered, so it is valid, unless we ever introduce Frequency: 'never' frequency = action[FREQUENCY] if frequency not in FrequenciesInSeconds.keys(): self._handle_unsupported_frequency(frequency) if FrequenciesInSeconds[frequency] > time.time() - last_triggered: self._handle_maximum_frequency(frequency) def _get_action(self, action_id): actions = self.get_actions() for action in actions: if action[ACTION_ID] == action_id: Logger.success(LOCATION, 'Action found') return action Logger.error(LOCATION, 'Action not found') raise falcon.HTTPNotFound(description='Action not found') def _create_trigger_body(self, action_id, value, alternative_id): data = { ACTION_ID: action_id, DEVICE_ID: self.configuration.get_device_id(), QUEUE_ID: self.key_generator.generate_uuid() } if alternative_id is not None: data[ALTERNATIVE_ID] = str(alternative_id) if value is not None: data[VALUE] = str(value) return data @staticmethod def _handle_unsupported_frequency(frequency): error = 'Frequency not supported: ' + frequency Logger.error(LOCATION, error) raise falcon.HTTPBadRequest(description=error) @staticmethod def _handle_maximum_frequency(frequency): error = 'Maximum ' + frequency + ' triggers reached' Logger.error(LOCATION, error) raise falcon.HTTPBadRequest(description=error)