def doCommandLine(complexType=True, debug=False, **kw): from util import Storage if debug: SetDebugCallback(None,None,None,None) if complexType: SetPyclassMetaclass(None,None,None,None, **{'module':'ZSI.generate.pyclass', 'metaclass':'pyclass_type'} ) options = Storage( file=None, url=None, schema=False, simple_naming=False, clientClassSuffix=None, aname=None, pyclassMapModule=None, address=False, extended=False, types=None, output_directory='.', ) options.update(kw) return options, ()
def info(self): "Returns a Storage containing the attributes edited by this dialog." info = Storage(name=self.name.Value, protocol=self.protocol_name) info.protocol, info.name = strip_acct_id(info.protocol, info.name) if hasattr(self, "password"): info.password_len = len(self.password.Value) try: info.password = profile.crypt_pw(self.password.Value) except UnicodeEncodeError: # the database has corrupted the password. log.warning("corrupted password") info.password = "" self.password.Value = "" import hub hub.get_instance().on_error( "This account's password has been corrupted somehow. Please report it immediately." ) if hasattr(self, "host"): info.server = (self.host.Value, int(self.port.Value) if self.port.Value else "") if hasattr(self, "remote_alias"): info.remote_alias = self.remote_alias.Value if hasattr(self, "autologin"): info.autologin = bool(self.autologin.Value) if hasattr(self, "resource"): info.update( resource=self.resource.Value, priority=try_this(lambda: int(self.priority.Value), DEFAULT_JABBER_PRIORITY), ) # , # confserver = self.confserver.Value if hasattr(self, "dataproxy"): info.update(dataproxy=self.dataproxy.Value) for d in getattr(self.protocolinfo, "more_details", []): attr = d["store"] ctrl = getattr(self, attr) info[attr] = ctrl.Value getattr(self, "info_" + self.formtype, lambda *a: {})(info) for info_cb in self.info_callbacks: info_cb(info) defaults = self.protocolinfo.get("defaults", {}) for k in defaults: if k not in info: info[k] = getattr(self.account, k, defaults.get(k)) return info
def info(self): 'Returns a Storage containing the attributes edited by this dialog.' info = Storage(name = self.name.Value, protocol = self.protocol_name) info.protocol, info.name = strip_acct_id(info.protocol, info.name) if hasattr(self, 'password'): info.password_len = len(self.password.Value) try: info.password = profile.crypt_pw(self.password.Value) except UnicodeEncodeError: # the database has corrupted the password. log.warning('corrupted password') info.password = '' self.password.Value = '' import hub hub.get_instance().on_error('This account\'s password has been corrupted somehow. Please report it immediately.') if hasattr(self, 'host'): info.server = (self.host.Value, int(self.port.Value) if self.port.Value else '') if hasattr(self, 'remote_alias'): info.remote_alias = self.remote_alias.Value if hasattr(self, 'autologin'): info.autologin = bool(self.autologin.Value) if hasattr(self, 'resource'): info.update(resource = self.resource.Value, priority = try_this(lambda: int(self.priority.Value), DEFAULT_JABBER_PRIORITY)) # , # confserver = self.confserver.Value if hasattr(self, 'dataproxy'): info.update(dataproxy = self.dataproxy.Value) for d in getattr(self.protocolinfo, 'more_details', []): attr = d['store'] ctrl = getattr(self, attr) info[attr] = ctrl.Value getattr(self, 'info_' + self.formtype, lambda *a: {})(info) for info_cb in self.info_callbacks: info_cb(info) defaults = self.protocolinfo.get('defaults', {}) for k in defaults: if k not in info: info[k] = getattr(self.account, k, defaults.get(k)) return info
class Discovery(threading.Thread): __devices_table = ("devices", ("id TEXT NOT NULL UNIQUE PRIMARY KEY", "name TEXT NOT NULL", "model TEXT NOT NULL", "local_credentials TEXT NOT NULL", "last_seen TEXT NOT NULL")) def __init__(self, mqtt_client: MQTTClient, device_sessions: typing.Dict[str, Session]): super().__init__(name="discovery", daemon=True) self.__mqtt_client = mqtt_client self.__device_sessions = device_sessions self.__device_pool: typing.Dict[str, Device] = dict() self.__publish_flag = False self.__lock = threading.Lock() self.__local_storage = Storage(conf.Discovery.db_path, "devices", (Discovery.__devices_table, )) def __handle_new_device(self, device_id: str, data: dict): try: logger.info("adding '{}'".format(device_id)) del data["last_seen"] device = Device(id=device_id, **data) self.__mqtt_client.publish( topic=mgw_dc.dm.gen_device_topic(conf.Client.id), payload=json.dumps(mgw_dc.dm.gen_set_device_msg(device)), qos=1) self.__device_pool[device_id] = device except Exception as ex: logger.error("adding '{}' failed - {}".format(device_id, ex)) def __handle_missing_device(self, device_id: str): try: logger.info("removing '{}' ...".format(device_id)) device = self.__device_pool[device_id] self.__mqtt_client.publish( topic=mgw_dc.dm.gen_device_topic(conf.Client.id), payload=json.dumps(mgw_dc.dm.gen_delete_device_msg(device)), qos=1) del self.__device_pool[device_id] except Exception as ex: logger.error("removing '{}' failed - {}".format(device_id, ex)) def __handle_existing_device(self, device_id: str, data: dict): try: logger.info("updating '{}' ...".format(device_id)) device = self.__device_pool[device_id] if device.name != data["name"]: name_bk = device.name device.name = data["name"] try: self.__mqtt_client.publish( topic=mgw_dc.dm.gen_device_topic(conf.Client.id), payload=json.dumps( mgw_dc.dm.gen_set_device_msg(device)), qos=1) except Exception as ex: device.name = name_bk raise ex if device.local_credentials != data["local_credentials"]: device.local_credentials = data["local_credentials"] except Exception as ex: logger.error("updating '{}' failed - {}".format(device_id, ex)) def __refresh_local_storage(self): try: logger.info("refreshing local storage ...") local_devices = to_dict( self.__local_storage.read(Discovery.__devices_table[0]), "id") remote_devices = get_cloud_devices(*get_cloud_credentials()) new_devices, missing_devices, existing_devices = diff( local_devices, remote_devices) if new_devices: for device_id in new_devices: logger.info("adding record for '{}' ...".format(device_id)) try: self.__local_storage.create( Discovery.__devices_table[0], { "id": device_id, **remote_devices[device_id] }) except Exception as ex: logger.error( "adding record for '{}' failed - {}".format( device_id, ex)) if missing_devices: for device_id in missing_devices: try: device_data = self.__local_storage.read( Discovery.__devices_table[0], id=device_id) now = time.time() age = now - float(device_data[0]["last_seen"]) if age > conf.Discovery.grace_period: logger.info( "removing record for '{}' due to exceeded grace period ..." .format(device_id)) try: self.__local_storage.delete( Discovery.__devices_table[0], id=device_id) except Exception as ex: logger.error( "removing record for '{}' failed - {}". format(device_id, ex)) else: logger.info( "remaining grace period for missing '{}': {}s". format(device_id, conf.Discovery.grace_period - age)) except Exception as ex: logger.error( "can't calculate grace period for missing '{}' - {}" .format(device_id, ex)) if existing_devices: for device_id in existing_devices: logger.info( "updating record for '{}' ...".format(device_id)) try: self.__local_storage.update( Discovery.__devices_table[0], remote_devices[device_id], id=device_id) except Exception as ex: logger.error( "updating record for '{}' failed - {}".format( device_id, ex)) except Exception as ex: logger.error("refreshing local storage failed - {}".format(ex)) def __refresh_devices(self): try: stored_devices = to_dict( self.__local_storage.read(Discovery.__devices_table[0]), "id") new_devices, missing_devices, existing_devices = diff( self.__device_pool, stored_devices) if new_devices: for device_id in new_devices: self.__handle_new_device(device_id, stored_devices[device_id]) if missing_devices: for device_id in missing_devices: self.__handle_missing_device(device_id) if existing_devices: for device_id in existing_devices: self.__handle_existing_device(device_id, stored_devices[device_id]) except Exception as ex: logger.error("refreshing devices failed - {}".format(ex)) def __start_device_session(self, device: Device, location: tuple): logger.info("found '{}' at '{}'".format(device.id, location[0])) session = Session(mqtt_client=self.__mqtt_client, device=device, ip=location[0], port=location[1]) session.start() self.__device_sessions[device.id] = session def run(self) -> None: if not self.__mqtt_client.connected(): time.sleep(3) logger.info("starting {} ...".format(self.name)) self.__refresh_local_storage() last_cloud_check = time.time() self.__refresh_devices() while True: if self.__publish_flag: self.__publish_devices(self.__publish_flag) if time.time() - last_cloud_check > conf.Discovery.cloud_delay: self.__refresh_local_storage() last_cloud_check = time.time() self.__refresh_devices() try: positive_hosts = probe_hosts(discover_hosts()) for device in self.__device_pool.values(): if device.id not in self.__device_sessions: for hostname, data in positive_hosts.items(): if device.id.replace( conf.Discovery.device_id_prefix, "") in hostname: self.__start_device_session(device=device, location=data) break else: if not self.__device_sessions[device.id].is_alive(): del self.__device_sessions[device.id] for hostname, data in positive_hosts.items(): if device.id.replace( conf.Discovery.device_id_prefix, "") in hostname: self.__start_device_session(device=device, location=data) break except Exception as ex: logger.error("discovery failed - {}".format(ex)) time.sleep(conf.Discovery.delay) def __publish_devices(self, flag: int): with self.__lock: if self.__publish_flag == flag: self.__publish_flag = 0 for device in self.__device_pool.values(): try: self.__mqtt_client.publish( topic=mgw_dc.dm.gen_device_topic(conf.Client.id), payload=json.dumps(mgw_dc.dm.gen_set_device_msg(device)), qos=1) except Exception as ex: logger.error("setting device '{}' failed - {}".format( device.id, ex)) if flag > 1 and device.state == mgw_dc.dm.device_state.online: try: self.__mqtt_client.subscribe( topic=mgw_dc.com.gen_command_topic(device.id), qos=1) except Exception as ex: logger.error("subscribing device '{}' failed - {}".format( device.id, ex)) def schedule_publish(self, subscribe: bool = False): with self.__lock: self.__publish_flag = max(self.__publish_flag, int(subscribe) + 1)