Loading plugins v 0.3 🔌
This commit is contained in:
@@ -84,10 +84,12 @@ def main ():
|
||||
# Header + init app state
|
||||
updateState("Initializing")
|
||||
|
||||
all_plugins = None
|
||||
|
||||
while True:
|
||||
|
||||
# re-load user configuration and plugins
|
||||
importConfigs(db)
|
||||
all_plugins = importConfigs(db, all_plugins)
|
||||
|
||||
# update time started
|
||||
conf.loop_start_time = timeNowTZ()
|
||||
@@ -96,14 +98,14 @@ def main ():
|
||||
|
||||
# Handle plugins executed ONCE
|
||||
if conf.plugins_once_run == False:
|
||||
pluginsState = run_plugin_scripts(db, 'once')
|
||||
pluginsState = run_plugin_scripts(db, all_plugins, 'once')
|
||||
conf.plugins_once_run = True
|
||||
|
||||
# check if there is a front end initiated event which needs to be executed
|
||||
pluginsState = check_and_run_user_event(db, pluginsState)
|
||||
pluginsState = check_and_run_user_event(db, all_plugins, pluginsState)
|
||||
|
||||
# Update API endpoints
|
||||
update_api(db)
|
||||
update_api(db, all_plugins)
|
||||
|
||||
# proceed if 1 minute passed
|
||||
if conf.last_scan_run + datetime.timedelta(minutes=1) < conf.loop_start_time :
|
||||
@@ -119,13 +121,13 @@ def main ():
|
||||
startTime = startTime.replace (microsecond=0)
|
||||
|
||||
# Check if any plugins need to run on schedule
|
||||
pluginsState = run_plugin_scripts(db,'schedule', pluginsState)
|
||||
pluginsState = run_plugin_scripts(db, all_plugins, 'schedule', pluginsState)
|
||||
|
||||
# determine run/scan type based on passed time
|
||||
# --------------------------------------------
|
||||
|
||||
# Runs plugin scripts which are set to run every timne after a scans finished
|
||||
pluginsState = run_plugin_scripts(db,'always_after_scan', pluginsState)
|
||||
pluginsState = run_plugin_scripts(db, all_plugins, 'always_after_scan', pluginsState)
|
||||
|
||||
|
||||
# process all the scanned data into new devices
|
||||
@@ -139,7 +141,7 @@ def main ():
|
||||
# --------
|
||||
# Reporting
|
||||
# run plugins before notification processing (e.g. Plugins to discover device names)
|
||||
pluginsState = run_plugin_scripts(db, 'before_name_updates', pluginsState)
|
||||
pluginsState = run_plugin_scripts(db, all_plugins, 'before_name_updates', pluginsState)
|
||||
|
||||
# Resolve devices names
|
||||
mylog('debug','[Main] Resolve devices names')
|
||||
@@ -153,7 +155,7 @@ def main ():
|
||||
# new devices were found
|
||||
if len(newDevices) > 0:
|
||||
# run all plugins registered to be run when new devices are found
|
||||
pluginsState = run_plugin_scripts(db, 'on_new_device', pluginsState)
|
||||
pluginsState = run_plugin_scripts(db, all_plugins, 'on_new_device', pluginsState)
|
||||
|
||||
# Notification handling
|
||||
# ----------------------------------------
|
||||
@@ -167,7 +169,7 @@ def main ():
|
||||
|
||||
# run all enabled publisher gateways
|
||||
if notificationObj.HasNotifications:
|
||||
pluginsState = run_plugin_scripts(db, 'on_notification', pluginsState)
|
||||
pluginsState = run_plugin_scripts(db, all_plugins, 'on_notification', pluginsState)
|
||||
notification.setAllProcessed()
|
||||
notification.clearPendingEmailFlag()
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ apiEndpoints = []
|
||||
#===============================================================================
|
||||
# API
|
||||
#===============================================================================
|
||||
def update_api(db, isNotification = False, updateOnlyDataSources = []):
|
||||
def update_api(db, all_plugins, isNotification = False, updateOnlyDataSources = []):
|
||||
mylog('debug', ['[API] Update API starting'])
|
||||
# return
|
||||
|
||||
folder = apiPath
|
||||
|
||||
# Save plugins
|
||||
write_file(folder + 'plugins.json' , json.dumps({"data" : conf.plugins}))
|
||||
write_file(folder + 'plugins.json' , json.dumps({"data" : all_plugins}))
|
||||
|
||||
# prepare database tables we want to expose
|
||||
dataSourcesSQLs = [
|
||||
|
||||
@@ -9,7 +9,6 @@ mySettingsSQLsafe = []
|
||||
cycle = 1
|
||||
userSubnets = []
|
||||
mySchedules = [] # bad solution for global - TO-DO
|
||||
plugins = [] # bad solution for global - TO-DO
|
||||
tz = ''
|
||||
|
||||
# modified time of the most recently imported config file
|
||||
|
||||
@@ -55,7 +55,7 @@ def ccd(key, default, config_dir, name, inputtype, options, group, events=[], de
|
||||
return result
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def importConfigs (db):
|
||||
def importConfigs (db, all_plugins):
|
||||
|
||||
sql = db.sql
|
||||
|
||||
@@ -75,9 +75,9 @@ def importConfigs (db):
|
||||
mylog('debug', ['[Import Config] fileModifiedTime :', fileModifiedTime])
|
||||
|
||||
|
||||
if (fileModifiedTime == conf.lastImportedConfFile) :
|
||||
if (fileModifiedTime == conf.lastImportedConfFile) and all_plugins is not None:
|
||||
mylog('debug', ['[Import Config] skipping config file import'])
|
||||
return
|
||||
return all_plugins
|
||||
|
||||
# Header
|
||||
updateState("Import config", showSpinner = True)
|
||||
@@ -146,16 +146,18 @@ def importConfigs (db):
|
||||
|
||||
# Plugins START
|
||||
# -----------------
|
||||
conf.plugins = get_plugins_configs()
|
||||
all_plugins = get_plugins_configs()
|
||||
|
||||
mylog('none', ['[Config] Plugins: Number of available plugins (including not loaded): ', len(conf.plugins)])
|
||||
mylog('none', ['[Config] Plugins: Number of all plugins (including not loaded): ', len(all_plugins)])
|
||||
|
||||
plugin_indexes_to_remove = []
|
||||
|
||||
# handle plugins
|
||||
index = 0
|
||||
for plugin in conf.plugins:
|
||||
for plugin in all_plugins:
|
||||
|
||||
# Header on the frontend and the app_state.json
|
||||
updateState(f"Import plugin {index} of {len(conf.plugins)}")
|
||||
updateState(f"Import plugin {index} of {len(all_plugins)}")
|
||||
|
||||
index +=1
|
||||
|
||||
@@ -168,8 +170,8 @@ def importConfigs (db):
|
||||
plugin_run = get_plugin_setting(plugin, "RUN")
|
||||
|
||||
# get user-defined run value if available
|
||||
if key in c_d:
|
||||
plugin_run = c_d[key]
|
||||
if pref + "_RUN" in c_d:
|
||||
plugin_run = c_d[pref + "_RUN" ]
|
||||
|
||||
|
||||
# only include loaded plugins, and the ones that are enabled
|
||||
@@ -222,9 +224,24 @@ def importConfigs (db):
|
||||
sql.executemany ("""INSERT INTO Plugins_Language_Strings ("Language_Code", "String_Key", "String_Value", "Extra") VALUES (?, ?, ?, ?)""", stringSqlParams )
|
||||
|
||||
else:
|
||||
mylog('none', [f'[Config] Skipping plugin {pref} because not in the LOADED_PLUGINS setting'])
|
||||
# log which plugins to remove
|
||||
index_to_remove = 0
|
||||
for plugin in all_plugins:
|
||||
if plugin["unique_prefix"] == pref:
|
||||
break
|
||||
index_to_remove +=1
|
||||
|
||||
plugin_indexes_to_remove.append(index_to_remove)
|
||||
|
||||
|
||||
|
||||
# remove plugin at index_to_remove from list
|
||||
# Sort the list of indexes in descending order to avoid index shifting issues
|
||||
plugin_indexes_to_remove.sort(reverse=True)
|
||||
for indx in plugin_indexes_to_remove:
|
||||
pref = all_plugins[indx]["unique_prefix"]
|
||||
mylog('none', [f'[Config] ⛔ Unloading plugin {pref} because not in the LOADED_PLUGINS setting or disabled by default'])
|
||||
all_plugins.pop(indx)
|
||||
|
||||
|
||||
conf.plugins_once_run = False
|
||||
@@ -240,10 +257,10 @@ def importConfigs (db):
|
||||
db.commitDB()
|
||||
|
||||
# update only the settings datasource
|
||||
update_api(db, False, ["settings"])
|
||||
update_api(db, all_plugins, False, ["settings"])
|
||||
|
||||
# run plugins that are modifying the config
|
||||
run_plugin_scripts(db, 'before_config_save' )
|
||||
run_plugin_scripts(db, all_plugins, 'before_config_save' )
|
||||
|
||||
# Used to determine the next import
|
||||
conf.lastImportedConfFile = os.path.getmtime(config_file)
|
||||
@@ -252,6 +269,8 @@ def importConfigs (db):
|
||||
|
||||
mylog('minimal', '[Config] Imported new config')
|
||||
|
||||
return all_plugins
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@@ -101,14 +101,14 @@ class plugins_state:
|
||||
self.processScan = processScan
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def run_plugin_scripts(db, runType, pluginsState = plugins_state()):
|
||||
def run_plugin_scripts(db, all_plugins, runType, pluginsState = plugins_state()):
|
||||
|
||||
# Header
|
||||
updateState("Run: Plugins")
|
||||
|
||||
mylog('debug', ['[Plugins] Check if any plugins need to be executed on run type: ', runType])
|
||||
|
||||
for plugin in conf.plugins:
|
||||
for plugin in all_plugins:
|
||||
|
||||
shouldRun = False
|
||||
prefix = plugin["unique_prefix"]
|
||||
@@ -131,7 +131,7 @@ def run_plugin_scripts(db, runType, pluginsState = plugins_state()):
|
||||
|
||||
print_plugin_info(plugin, ['display_name'])
|
||||
mylog('debug', ['[Plugins] CMD: ', get_plugin_setting(plugin, "CMD")["value"]])
|
||||
pluginsState = execute_plugin(db, plugin, pluginsState)
|
||||
pluginsState = execute_plugin(db, all_plugins, plugin, pluginsState)
|
||||
# update last run time
|
||||
if runType == "schedule":
|
||||
for schd in conf.mySchedules:
|
||||
@@ -146,7 +146,7 @@ def run_plugin_scripts(db, runType, pluginsState = plugins_state()):
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Executes the plugin command specified in the setting with the function specified as CMD
|
||||
def execute_plugin(db, plugin, pluginsState = plugins_state() ):
|
||||
def execute_plugin(db, all_plugins, plugin, pluginsState = plugins_state() ):
|
||||
sql = db.sql
|
||||
|
||||
|
||||
@@ -374,7 +374,7 @@ def execute_plugin(db, plugin, pluginsState = plugins_state() ):
|
||||
pluginsState = process_plugin_events(db, plugin, pluginsState, sqlParams)
|
||||
|
||||
# update API endpoints
|
||||
update_api(db, False, ["plugins_events","plugins_objects", "plugins_history", "appevents"])
|
||||
update_api(db, all_plugins, False, ["plugins_events","plugins_objects", "plugins_history", "appevents"])
|
||||
|
||||
return pluginsState
|
||||
|
||||
@@ -729,7 +729,7 @@ class plugin_object_class:
|
||||
#===============================================================================
|
||||
# Handling of user initialized front-end events
|
||||
#===============================================================================
|
||||
def check_and_run_user_event(db, pluginsState):
|
||||
def check_and_run_user_event(db, all_plugins, pluginsState):
|
||||
# Check if the log file exists
|
||||
logFile = os.path.join(logPath, "execution_queue.log")
|
||||
|
||||
@@ -749,12 +749,12 @@ def check_and_run_user_event(db, pluginsState):
|
||||
event, param = columns
|
||||
|
||||
if event == 'test':
|
||||
pluginsState = handle_test(param, db, pluginsState)
|
||||
pluginsState = handle_test(param, db, all_plugins, pluginsState)
|
||||
if event == 'run':
|
||||
pluginsState = handle_run(param, db, pluginsState)
|
||||
pluginsState = handle_run(param, db, all_plugins, pluginsState)
|
||||
if event == 'update_api':
|
||||
# update API endpoints
|
||||
update_api(db, False, param.split(','))
|
||||
update_api(db, all_plugins, False, param.split(','))
|
||||
|
||||
# Clear the log file
|
||||
open(logFile, "w").close()
|
||||
@@ -763,14 +763,14 @@ def check_and_run_user_event(db, pluginsState):
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def handle_run(runType, db, pluginsState):
|
||||
def handle_run(runType, db, all_plugins, pluginsState):
|
||||
|
||||
mylog('minimal', ['[', timeNowTZ(), '] START Run: ', runType])
|
||||
|
||||
# run the plugin to run
|
||||
for plugin in conf.plugins:
|
||||
for plugin in all_plugins:
|
||||
if plugin["unique_prefix"] == runType:
|
||||
pluginsState = execute_plugin(db, plugin, pluginsState)
|
||||
pluginsState = execute_plugin(db, all_plugins, plugin, pluginsState)
|
||||
|
||||
mylog('minimal', ['[', timeNowTZ(), '] END Run: ', runType])
|
||||
return pluginsState
|
||||
@@ -778,7 +778,7 @@ def handle_run(runType, db, pluginsState):
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def handle_test(runType, db, pluginsState):
|
||||
def handle_test(runType, db, all_plugins, pluginsState):
|
||||
|
||||
mylog('minimal', ['[', timeNowTZ(), '] [Test] START Test: ', runType])
|
||||
|
||||
@@ -792,7 +792,7 @@ def handle_test(runType, db, pluginsState):
|
||||
notificationObj = notification.create(sample_json, "")
|
||||
|
||||
# Run test
|
||||
pluginsState = handle_run(runType, db, pluginsState)
|
||||
pluginsState = handle_run(runType, db, all_plugins, pluginsState)
|
||||
|
||||
# Remove sample notification
|
||||
notificationObj.remove(notificationObj.GUID)
|
||||
|
||||
Reference in New Issue
Block a user