def handle_time_range(ruleId, methodParams): with TimerModule.SCHEDULER_LOCK: keyName = TimerModule._PARAM_TIME_RANGE.get_kbx_param_name() tVal = TimerModule.__get_arg(keyName, methodParams) if tVal is not None: try: tVal = TimerModule._PARAM_TIME_RANGE.cast(tVal) startTime = tVal.get_start_time() except Exception as e: Logger.log_warning("Invalid time range value, val:", tVal, "ex:", e) return else: # Backward compatible to daily_task. kbxTime = KBXTime(kbxParamName="time") try: startTime = kbxTime.cast( TimerModule.__get_arg("time", methodParams)) except Exception as e: Logger.log_warning("Invalid time range value (old), val:", tVal, "ex:", e) return # Add scheduler TimerModule.__add_scheduler(ruleId, "time_range", str(startTime.get_second()), str(startTime.get_minute()), str(startTime.get_hour()), "*", "*", "*")
def __on_record_deleted(self, kbxMethodId, kbxMethodEvent, kbxMethodIdentifier): result = self.__db.execute('SELECT COUNT(kbxMethodId) AS "total" FROM "event" WHERE "kbxMethodEvent"=?', (kbxMethodEvent,)).fetchall() if result[0]["total"] == 0: try: self.on_event_deleted(kbxMethodEvent) except Exception as e: Logger.log_warning("EventController.__on_record_added ex:", e, "- tag:", kbxMethodEvent)
def __add_scheduler(ruleId, kbxMethodIdentifier, second, minute, hour, dayOfMonth, month, dayOfWeek): ''' second="0", minute="*", hour="*", dayOfMonth="*", month="*", dayOfWeek="*" ''' try: uniqueName = "_".join([kbxMethodIdentifier, second, minute, hour, dayOfMonth, month, dayOfWeek]) schedulerName = hash(uniqueName) if schedulerName not in TimerModule.SCHEDULER_ID_TRACKER: SchedulerService.add_cron_job(str(schedulerName), kbxTargetAppId=AppInfo.get_app_id(), kbxTargetMethod="scheduler_callback", kbxTargetModule="timer_module", second=second, minute=minute, hour=hour, dayOfMonth=dayOfMonth, month=month, dayOfWeek=dayOfWeek, kbxTargetParams={"kbxMethodIdentifier":kbxMethodIdentifier}, store=False) TimerModule.SCHEDULER_ID_TRACKER[schedulerName] = [ruleId] TimerModule.RULE_ID_SCHEDULER_TRACKER[ruleId] = [schedulerName] Logger.log_debug("Added Timer:", schedulerName, uniqueName) else: TimerModule.SCHEDULER_ID_TRACKER[schedulerName].append(ruleId) TimerModule.RULE_ID_SCHEDULER_TRACKER[ruleId].append(schedulerName) except Exception as e: Logger.log_warning("Failed to add timer:", e)
def on_group_icon_change(*args, **kwargs): with self.__lock___group_icon_change: for callback in self.__group_icon_change_callbacks: try: callback(*args, **kwargs) except Exception as e: Logger.log_warning("GroupController.listen_to_group_icon_change.on_group_icon_change callback ex:", e)
def kbx_method_after_delete(self, kbxMethodId, kbxGroupId): if Util.is_empty(kbxGroupId): return self.__delete_kbx_group_if_necessary(kbxGroupId) try: Database.KBX_METHOD_AFTER_DELETE(kbxMethodId) except Exception as e: Logger.log_warning("Database.KBX_METHOD_AFTER_DELETE raised error:", e)
def on_method_status_change(*args, **kwargs): with self.__lock___method_status_change: for callback in self.__method_status_change_callbacks: try: callback(*args, **kwargs) except Exception as e: Logger.log_warning("MethodController.listen_to_method_status_change.on_method_status_change callback ex:", e)
def __get_arg(keyName, methodParams): ''' Method to parse out corresponding value from methodParams. ''' for methodParam in methodParams: if methodParam.get(AppConstants.ARG_NAME) == keyName: return methodParam.get(AppConstants.ARG_CURRENT_VALUE) else: Logger.log_warning("Unable to find value:", keyName) return None
def kbx_method_after_delete(self, kbxMethodId, kbxGroupId): if Util.is_empty(kbxGroupId): return self.__delete_kbx_group_if_necessary(kbxGroupId) try: Database.KBX_METHOD_AFTER_DELETE(kbxMethodId) except Exception as e: Logger.log_warning( "Database.KBX_METHOD_AFTER_DELETE raised error:", e)
def __get_arg(keyName, methodParams): ''' Method to parse out corresponding value from methodParams. ''' for methodParam in methodParams: if methodParam.get(AppConstants.ARG_NAME) == keyName: return methodParam.get(AppConstants.ARG_CURRENT_VALUE) else: Logger.log_warning("Unable to find value:", keyName) return None
def __scheduler_callback(self, request): self.send_response({}, request.requestId) try: self.send_system_event( TimerModule.EVENT_TAG, "".join( ("{\"kbxMethodIdentifier\":\"", str(request.get_arg("kbxMethodIdentifier")), "\"}"))) except Exception as e: Logger.log_warning( "Timer Module failed to process scheduler callback:", str(e))
def __on_record_deleted(self, kbxMethodId, kbxMethodEvent, kbxMethodIdentifier): result = self.__db.execute( 'SELECT COUNT(kbxMethodId) AS "total" FROM "event" WHERE "kbxMethodEvent"=?', (kbxMethodEvent, )).fetchall() if result[0]["total"] == 0: try: self.on_event_deleted(kbxMethodEvent) except Exception as e: Logger.log_warning("EventController.__on_record_added ex:", e, "- tag:", kbxMethodEvent)
def on_group_icon_change(*args, **kwargs): with self.__lock___group_icon_change: for callback in self.__group_icon_change_callbacks: try: callback(*args, **kwargs) except Exception as e: Logger.log_warning( "GroupController.listen_to_group_icon_change.on_group_icon_change callback ex:", e)
def on_method_status_change(*args, **kwargs): with self.__lock___method_status_change: for callback in self.__method_status_change_callbacks: try: callback(*args, **kwargs) except Exception as e: Logger.log_warning( "MethodController.listen_to_method_status_change.on_method_status_change callback ex:", e)
def reset(self): result = self.__db.execute('SELECT DISTINCT "kbxMethodEvent" FROM "event"').fetchall() for row in result: kbxMethodEvent = row["kbxMethodEvent"] try: self.on_event_deleted(kbxMethodEvent) except Exception as e: Logger.log_warning("EventController.reset on_event_removed ex:", e, "- tag:", kbxMethodEvent) self.__db.close() self.__init__()
def handle_dow(ruleId, methodParams): with TimerModule.SCHEDULER_LOCK: keyName = TimerModule._PARAM_DOW.get_kbx_param_name() dowVal = TimerModule.__get_arg(keyName, methodParams) try: dowVal = TimerModule._PARAM_DOW.cast(dowVal) except Exception as e: Logger.log_warning("Invalid day of week value, val:", dowVal, "ex:", e) return # Add scheduler dayOfWeek = ",".join((str(d) for d in dowVal)) TimerModule.__add_scheduler(ruleId, "day_of_week", "0", "0", "0", "*", "*", dayOfWeek)
def reset(self): result = self.__db.execute( 'SELECT DISTINCT "kbxMethodEvent" FROM "event"').fetchall() for row in result: kbxMethodEvent = row["kbxMethodEvent"] try: self.on_event_deleted(kbxMethodEvent) except Exception as e: Logger.log_warning( "EventController.reset on_event_removed ex:", e, "- tag:", kbxMethodEvent) self.__db.close() self.__init__()
def delete_scheduler(ruleId): with TimerModule.SCHEDULER_LOCK: try: schedulerNames = TimerModule.RULE_ID_SCHEDULER_TRACKER.pop(ruleId, set({})) for schedulerName in schedulerNames: TimerModule.SCHEDULER_ID_TRACKER[schedulerName].remove(ruleId) if not TimerModule.SCHEDULER_ID_TRACKER[schedulerName]: SchedulerService.remove_job(str(schedulerName)) del(TimerModule.SCHEDULER_ID_TRACKER[schedulerName]) Logger.log_debug("Removed Timer:", schedulerName) except Exception as e: Logger.log_warning("Failed to remove timer:", e)
def handle_dow(ruleId, methodParams): with TimerModule.SCHEDULER_LOCK: keyName = TimerModule._PARAM_DOW.get_kbx_param_name() dowVal = TimerModule.__get_arg(keyName, methodParams) try: dowVal = TimerModule._PARAM_DOW.cast(dowVal) except Exception as e: Logger.log_warning("Invalid day of week value, val:", dowVal, "ex:", e) return # Add scheduler dayOfWeek = ",".join((str(d) for d in dowVal)) TimerModule.__add_scheduler(ruleId, "day_of_week", "0", "0", "0", "*", "*", dayOfWeek)
def handle_date_time_range(ruleId, methodParams): with TimerModule.SCHEDULER_LOCK: keyName = TimerModule._PARAM_DT_RANGE.get_kbx_param_name() dtVal = TimerModule.__get_arg(keyName, methodParams) try: dtVal = TimerModule._PARAM_DT_RANGE.cast(dtVal) except Exception as e: Logger.log_warning("Invalid date time range value, val:", dtVal, "ex:", e) return # Add scheduler startDateTime = dtVal.get_start_date_time() dtObj = startDateTime.get_date_time_obj() weekday = dtObj.isoweekday() % 7 TimerModule.__add_scheduler(ruleId, "date_time_range", str(dtObj.second), str(dtObj.minute), str(dtObj.hour), str(dtObj.day), str(dtObj.month), str(weekday))
def register_timer_module_schedulers(self): # TODO: REMEMBER TO ADD index to kbxMethodId timerModuleHnds = {TimerModule.METHOD_ID_DATE_TIME_RANGE: TimerModule.handle_date_time_range, TimerModule.METHOD_ID_TIME_RANGE: TimerModule.handle_time_range, TimerModule.METHOD_ID_DAY_OF_WEEK: TimerModule.handle_dow} timerMethodIds = (TimerModule.METHOD_ID_DATE_TIME_RANGE, TimerModule.METHOD_ID_TIME_RANGE, TimerModule.METHOD_ID_DAY_OF_WEEK) result = self.__db.execute_and_fetch_all('SELECT "rcRuleId", "kbxMethodId", "kbxMethodParams" FROM "rule_condition" WHERE "kbxMethodId" IN (?, ?, ?)', timerMethodIds) for row in result: try: timerModuleHnd = timerModuleHnds[row["kbxMethodId"]] timerModuleHnd(row["rcRuleId"], row["kbxMethodParams"]) except Exception as e: Logger.log_warning("BootstrapService.register_timer_module_schedulers ex:", e, "-- debug info --", dict(row))
def delete_scheduler(ruleId): with TimerModule.SCHEDULER_LOCK: try: schedulerNames = TimerModule.RULE_ID_SCHEDULER_TRACKER.pop( ruleId, set({})) for schedulerName in schedulerNames: TimerModule.SCHEDULER_ID_TRACKER[schedulerName].remove( ruleId) if not TimerModule.SCHEDULER_ID_TRACKER[schedulerName]: SchedulerService.remove_job(str(schedulerName)) del (TimerModule.SCHEDULER_ID_TRACKER[schedulerName]) Logger.log_debug("Removed Timer:", schedulerName) except Exception as e: Logger.log_warning("Failed to remove timer:", e)
def handle_date_time_range(ruleId, methodParams): with TimerModule.SCHEDULER_LOCK: keyName = TimerModule._PARAM_DT_RANGE.get_kbx_param_name() dtVal = TimerModule.__get_arg(keyName, methodParams) try: dtVal = TimerModule._PARAM_DT_RANGE.cast(dtVal) except Exception as e: Logger.log_warning("Invalid date time range value, val:", dtVal, "ex:", e) return # Add scheduler startDateTime = dtVal.get_start_date_time() dtObj = startDateTime.get_date_time_obj() weekday = dtObj.isoweekday() % 7 TimerModule.__add_scheduler(ruleId, "date_time_range", str(dtObj.second), str(dtObj.minute), str(dtObj.hour), str(dtObj.day), str(dtObj.month), str(weekday))
def __add_scheduler(ruleId, kbxMethodIdentifier, second, minute, hour, dayOfMonth, month, dayOfWeek): ''' second="0", minute="*", hour="*", dayOfMonth="*", month="*", dayOfWeek="*" ''' try: uniqueName = "_".join([ kbxMethodIdentifier, second, minute, hour, dayOfMonth, month, dayOfWeek ]) schedulerName = hash(uniqueName) if schedulerName not in TimerModule.SCHEDULER_ID_TRACKER: SchedulerService.add_cron_job( str(schedulerName), kbxTargetAppId=AppInfo.get_app_id(), kbxTargetMethod="scheduler_callback", kbxTargetModule="timer_module", second=second, minute=minute, hour=hour, dayOfMonth=dayOfMonth, month=month, dayOfWeek=dayOfWeek, kbxTargetParams={ "kbxMethodIdentifier": kbxMethodIdentifier }, store=False) TimerModule.SCHEDULER_ID_TRACKER[schedulerName] = [ruleId] TimerModule.RULE_ID_SCHEDULER_TRACKER[ruleId] = [schedulerName] Logger.log_debug("Added Timer:", schedulerName, uniqueName) else: TimerModule.SCHEDULER_ID_TRACKER[schedulerName].append(ruleId) TimerModule.RULE_ID_SCHEDULER_TRACKER[ruleId].append( schedulerName) except Exception as e: Logger.log_warning("Failed to add timer:", e)
def handle_time_range(ruleId, methodParams): with TimerModule.SCHEDULER_LOCK: keyName = TimerModule._PARAM_TIME_RANGE.get_kbx_param_name() tVal = TimerModule.__get_arg(keyName, methodParams) if tVal is not None: try: tVal = TimerModule._PARAM_TIME_RANGE.cast(tVal) startTime = tVal.get_start_time() except Exception as e: Logger.log_warning("Invalid time range value, val:", tVal, "ex:", e) return else: # Backward compatible to daily_task. kbxTime = KBXTime(kbxParamName="time") try: startTime = kbxTime.cast(TimerModule.__get_arg("time", methodParams)) except Exception as e: Logger.log_warning("Invalid time range value (old), val:", tVal, "ex:", e) return # Add scheduler TimerModule.__add_scheduler(ruleId, "time_range", str(startTime.get_second()), str(startTime.get_minute()), str(startTime.get_hour()), "*", "*", "*")
def __broadcast_group_status_update(self, eventObj): ''' Broadcast group updated status so that UI listen to the changes. ''' try: eventTag = eventObj["eventTag"] eventData = json.loads(eventObj["eventData"]) # Check if group parent id belongs to groups in automation. dataToBroadcast = {"kbxGroupId":eventData["kbxGroupId"], "kbxGroupParentId":eventData["kbxGroupParentId"], "enabled":bool((eventData.get("enabled", True) is not False) and eventTag != Event.EVENT_SHARED_METHOD_GROUP_DELETED)} eventTagsToBroadcast = {Event.EVENT_SHARED_METHOD_GROUP_ADDED: AppConstants.EVENT_AUTOMATION_GROUP_ADDED, Event.EVENT_SHARED_METHOD_GROUP_UPDATED: AppConstants.EVENT_AUTOMATION_GROUP_UPDATED, Event.EVENT_SHARED_METHOD_GROUP_DELETED: AppConstants.EVENT_AUTOMATION_GROUP_DELETED} dataToBroadcast = json.dumps(dataToBroadcast) self.send_web_server_event(eventTagsToBroadcast[eventTag], dataToBroadcast) except Exception as e: Logger.log_warning("AutomationApp __broadcast_group_status_update ex:", e)
def __broadcast_group_status_update(self, eventObj): ''' Broadcast group updated status so that UI listen to the changes. ''' try: eventTag = eventObj["eventTag"] eventData = json.loads(eventObj["eventData"]) # Check if group parent id belongs to groups in automation. dataToBroadcast = { "kbxGroupId": eventData["kbxGroupId"], "kbxGroupParentId": eventData["kbxGroupParentId"], "enabled": bool((eventData.get("enabled", True) is not False) and eventTag != Event.EVENT_SHARED_METHOD_GROUP_DELETED) } eventTagsToBroadcast = { Event.EVENT_SHARED_METHOD_GROUP_ADDED: AppConstants.EVENT_AUTOMATION_GROUP_ADDED, Event.EVENT_SHARED_METHOD_GROUP_UPDATED: AppConstants.EVENT_AUTOMATION_GROUP_UPDATED, Event.EVENT_SHARED_METHOD_GROUP_DELETED: AppConstants.EVENT_AUTOMATION_GROUP_DELETED } dataToBroadcast = json.dumps(dataToBroadcast) self.send_web_server_event(eventTagsToBroadcast[eventTag], dataToBroadcast) except Exception as e: Logger.log_warning( "AutomationApp __broadcast_group_status_update ex:", e)
def register_timer_module_schedulers(self): # TODO: REMEMBER TO ADD index to kbxMethodId timerModuleHnds = { TimerModule.METHOD_ID_DATE_TIME_RANGE: TimerModule.handle_date_time_range, TimerModule.METHOD_ID_TIME_RANGE: TimerModule.handle_time_range, TimerModule.METHOD_ID_DAY_OF_WEEK: TimerModule.handle_dow } timerMethodIds = (TimerModule.METHOD_ID_DATE_TIME_RANGE, TimerModule.METHOD_ID_TIME_RANGE, TimerModule.METHOD_ID_DAY_OF_WEEK) result = self.__db.execute_and_fetch_all( 'SELECT "rcRuleId", "kbxMethodId", "kbxMethodParams" FROM "rule_condition" WHERE "kbxMethodId" IN (?, ?, ?)', timerMethodIds) for row in result: try: timerModuleHnd = timerModuleHnds[row["kbxMethodId"]] timerModuleHnd(row["rcRuleId"], row["kbxMethodParams"]) except Exception as e: Logger.log_warning( "BootstrapService.register_timer_module_schedulers ex:", e, "-- debug info --", dict(row))
def db_1_update(self, resourcePath): Logger.log_info("Database v1 update started") self.__execute_script("/".join([resourcePath, "tablestructure.sql"])) Logger.log_info("Database v1 update: Table structures built") # #################### Migration codes #################### try: from automationApp.migration.storage import Storage allGroups = Storage.list_all_groups() if len(allGroups) > 0: # Probably no rule is set. ''' All Groups: e.g. {25: 'Yeelight Blue II'} ''' for kbxGroupId, kbxGroupLabel in allGroups.items(): self.__con.execute( 'INSERT INTO "kbx_group"("kbxGroupId", "kbxGroupLabel", "kbxGroupStatus") VALUES (?, ?, ?)', (kbxGroupId, kbxGroupLabel, -1)) del (allGroups) ''' All Groups Methods: e.g. {69: 25, 71: 25} ''' allMethodGroups = Storage.list_all_method_groups() for kbxMethodId, kbxGroupId in allMethodGroups.items(): self.__con.execute('INSERT INTO "kbx_method"("kbxMethodId", "kbxGroupId", "kbxMethodStatus") ' + \ 'VALUES (?, ?, ?)', (kbxMethodId, kbxGroupId, -1)) ''' All Rules: e.g. [{ 'execution': [{'kbxMethodId': 71, 'kbxMethodParams': [{'kbxParamCurrentValue': '4', 'kbxParamName': 'pairedDeviceId'},{'kbxParamCurrentValue': [False], 'kbxParamName': 'on'}]}], 'trigger': {'type': 0, 'value': None}, 'ruleId': '1425284835.0756288', 'enabled': True, 'condition': [{'kbxMethodId': 69, 'kbxMethodParams': [{'kbxParamCurrentValue': '4', 'kbxParamName': 'pairedDeviceId'}, {'kbxParamCurrentValue': [True], 'kbxParamName': 'on'}]}], 'ruleName': 'ReTestet' }] ''' allRules = Storage.list_all_rules() cursor = self.__con.cursor() createdTime = updatedTime = time.time() triggerController = TriggerController.instance() for sort, rule in enumerate(allRules): trigger = triggerController.parse_to_trigger_dto( rule["trigger"]) cursor.execute('INSERT INTO "rule"("ruleName", "ruleProtected", "trigger", "enabled", "statusProcessed", "createdTime", "updatedTime", "sort") ' + \ 'VALUES (?, ?, ?, ?, ?, ?, ?, ?)', (rule["ruleName"], False, json.dumps(trigger), rule["enabled"], "updated", createdTime, updatedTime, sort)) ruleId = cursor.lastrowid for vals in (["execution", "rule_execution", "reRuleId"], ["condition", "rule_condition", "rcRuleId"]): for kbxMethodSort, kbxMethodWithCurrentValue in enumerate( rule[vals[0]]): self.__con.execute('INSERT INTO "' + vals[1] + '"("' + vals[2] + '", "kbxMethodId", "kbxMethodParams", "createdTime", "sort") ' + \ 'VALUES (?, ?, ?, ?, ?)', (ruleId, kbxMethodWithCurrentValue["kbxMethodId"], json.dumps(kbxMethodWithCurrentValue["kbxMethodParams"]), createdTime, kbxMethodSort)) cursor.close() del (allRules) self.__con.commit() except Exception as e: self.__con.rollback() Logger.log_warning( "Database failed to migrate rules from system, ex:", e, "---- rolled back") else: Logger.log_info("Database v1 update: Rules migrated") try: Storage.delete_all_rules() Storage.delete_all_method_groups() Storage.delete_all_groups() except Exception as e: Logger.log_warning( "Database failed to remove rules from system after migration, ex:", e) # #################### End of migration codes #################### self.__execute_script("/".join([resourcePath, "triggers.sql"])) Logger.log_info("Database v1 update: Triggers built") self.__execute_script("/".join([resourcePath, "indexes.sql"])) Logger.log_info("Database v1 update: Indexes built") Logger.log_info("Database v1 update completed")
def delete_all_method_groups(): try: StorageManagerService.del_data(Storage.STORAGE_METHOD_GROUP) except Exception as e: Logger.log_warning("Migration.Storage.delete_all_method_groups ex:", e)
def __scheduler_callback(self, request): self.send_response({}, request.requestId) try: self.send_system_event(TimerModule.EVENT_TAG, "".join(("{\"kbxMethodIdentifier\":\"", str(request.get_arg("kbxMethodIdentifier")), "\"}"))) except Exception as e: Logger.log_warning("Timer Module failed to process scheduler callback:", str(e))
def delete_all_rules(): try: StorageManagerService.del_data(Storage.STORAGE_RULE) except Exception as e: Logger.log_warning("Migration.Storage.delete_all_rules ex:", e)
def db_1_update(self, resourcePath): Logger.log_info("Database v1 update started") self.__execute_script("/".join([resourcePath, "tablestructure.sql"])) Logger.log_info("Database v1 update: Table structures built") # #################### Migration codes #################### try: from automationApp.migration.storage import Storage allGroups = Storage.list_all_groups() if len(allGroups) > 0: # Probably no rule is set. ''' All Groups: e.g. {25: 'Yeelight Blue II'} ''' for kbxGroupId, kbxGroupLabel in allGroups.items(): self.__con.execute('INSERT INTO "kbx_group"("kbxGroupId", "kbxGroupLabel", "kbxGroupStatus") VALUES (?, ?, ?)', (kbxGroupId, kbxGroupLabel, -1)) del(allGroups) ''' All Groups Methods: e.g. {69: 25, 71: 25} ''' allMethodGroups = Storage.list_all_method_groups() for kbxMethodId, kbxGroupId in allMethodGroups.items(): self.__con.execute('INSERT INTO "kbx_method"("kbxMethodId", "kbxGroupId", "kbxMethodStatus") ' + \ 'VALUES (?, ?, ?)', (kbxMethodId, kbxGroupId, -1)) ''' All Rules: e.g. [{ 'execution': [{'kbxMethodId': 71, 'kbxMethodParams': [{'kbxParamCurrentValue': '4', 'kbxParamName': 'pairedDeviceId'},{'kbxParamCurrentValue': [False], 'kbxParamName': 'on'}]}], 'trigger': {'type': 0, 'value': None}, 'ruleId': '1425284835.0756288', 'enabled': True, 'condition': [{'kbxMethodId': 69, 'kbxMethodParams': [{'kbxParamCurrentValue': '4', 'kbxParamName': 'pairedDeviceId'}, {'kbxParamCurrentValue': [True], 'kbxParamName': 'on'}]}], 'ruleName': 'ReTestet' }] ''' allRules = Storage.list_all_rules() cursor = self.__con.cursor() createdTime = updatedTime = time.time() triggerController = TriggerController.instance() for sort, rule in enumerate(allRules): trigger = triggerController.parse_to_trigger_dto(rule["trigger"]) cursor.execute('INSERT INTO "rule"("ruleName", "ruleProtected", "trigger", "enabled", "statusProcessed", "createdTime", "updatedTime", "sort") ' + \ 'VALUES (?, ?, ?, ?, ?, ?, ?, ?)', (rule["ruleName"], False, json.dumps(trigger), rule["enabled"], "updated", createdTime, updatedTime, sort)) ruleId = cursor.lastrowid for vals in (["execution", "rule_execution", "reRuleId"], ["condition", "rule_condition", "rcRuleId"]): for kbxMethodSort, kbxMethodWithCurrentValue in enumerate(rule[vals[0]]): self.__con.execute('INSERT INTO "' + vals[1] + '"("' + vals[2] + '", "kbxMethodId", "kbxMethodParams", "createdTime", "sort") ' + \ 'VALUES (?, ?, ?, ?, ?)', (ruleId, kbxMethodWithCurrentValue["kbxMethodId"], json.dumps(kbxMethodWithCurrentValue["kbxMethodParams"]), createdTime, kbxMethodSort)) cursor.close() del(allRules) self.__con.commit() except Exception as e: self.__con.rollback() Logger.log_warning("Database failed to migrate rules from system, ex:", e , "---- rolled back") else: Logger.log_info("Database v1 update: Rules migrated") try: Storage.delete_all_rules() Storage.delete_all_method_groups() Storage.delete_all_groups() except Exception as e: Logger.log_warning("Database failed to remove rules from system after migration, ex:", e) # #################### End of migration codes #################### self.__execute_script("/".join([resourcePath, "triggers.sql"])) Logger.log_info("Database v1 update: Triggers built") self.__execute_script("/".join([resourcePath, "indexes.sql"])) Logger.log_info("Database v1 update: Indexes built") Logger.log_info("Database v1 update completed")