Separated example and unit test task to separate files.

This commit is contained in:
David Maisonave
2024-08-18 07:43:55 -04:00
parent 65767909c1
commit fb0760acde
4 changed files with 229 additions and 187 deletions

View File

@@ -9,7 +9,13 @@ import watchdog # pip install watchdog # https://pythonhosted.org/watchdog/
from watchdog.observers import Observer # This is also needed for event attributes
from threading import Lock, Condition
from multiprocessing import shared_memory
from filemonitor_config import config # Import settings from filemonitor_config.py
from filemonitor_config import config
from filemonitor_task_examples import task_examples
from filemonitor_self_unit_test import self_unit_test
config['task_scheduler'] = config['task_scheduler'] + task_examples['task_scheduler']
if self_unit_test['selfUnitTest']:
config['task_scheduler'] = config['task_scheduler'] + self_unit_test['task_scheduler']
CONTINUE_RUNNING_SIG = 99
STOP_RUNNING_SIG = 32
@@ -74,11 +80,6 @@ fileExtTypes = stash.pluginConfig['fileExtTypes'].split(",") if stash.pluginConf
includePathChanges = stash.pluginConfig['includePathChanges'] if len(stash.pluginConfig['includePathChanges']) > 0 else stash.STASH_PATHS
excludePathChanges = stash.pluginConfig['excludePathChanges']
stash.Trace(f"(apiKey={stash.API_KEY})")
stash.Trace(f"(includePathChanges={includePathChanges})")
if stash.DRY_RUN:
stash.Log("Dry run mode is enabled.")
stash.Trace(f"(SCAN_MODIFIED={SCAN_MODIFIED}) (SCAN_ON_ANY_EVENT={SCAN_ON_ANY_EVENT}) (RECURSIVE={RECURSIVE})")
@@ -88,7 +89,6 @@ StartFileMonitorAsAServiceTaskName = "Start Library Monitor Service"
StartFileMonitorAsAPluginTaskID = "start_library_monitor"
StartFileMonitorAsAServiceTaskID = "start_library_monitor_service"
FileMonitorPluginIsOnTaskQue = stash.CALLED_AS_STASH_PLUGIN
StopLibraryMonitorWaitingInTaskQueue = False
JobIdInTheQue = 0
@@ -211,25 +211,7 @@ class StashScheduler: # Stash Scheduler
elif task['task'] == "Generate":
result = stash.metadata_generate()
elif task['task'] == "Backup":
stash.LogOnce("Note: Backup task does not get listed in the Task Queue, but user can verify that it started by looking in the Stash log file as an INFO level log line.")
result = stash.backup_database()
maximumBackup = stash.pluginSettings['zmaximumBackups']
stash.Trace(f"maximumBackup={maximumBackup}")
if "maxBackups" in task:
maximumBackup = task['maxBackups']
stash.Trace(f"maximumBackup={maximumBackup}")
if isinstance(maximumBackup,str):
maximumBackup = int(maximumBackup)
if maximumBackup < 2:
stash.TraceOnce(f"Skipping DB backup file trim because zmaximumBackups={maximumBackup}. Value has to be greater than 1.")
elif 'backupDirectoryPath' in stash.STASH_CONFIGURATION:
if len(stash.STASH_CONFIGURATION['backupDirectoryPath']) < 5:
stash.TraceOnce(f"Skipping DB backup file trim because backupDirectoryPath length is to short. Len={len(stash.STASH_CONFIGURATION['backupDirectoryPath'])}. Only support length greater than 4 characters.")
elif os.path.exists(stash.STASH_CONFIGURATION['backupDirectoryPath']):
stash.LogOnce(f"Checking quantity of DB backups if path {stash.STASH_CONFIGURATION['backupDirectoryPath']} exceeds {maximumBackup} backup files.")
self.trimDbFiles(stash.STASH_CONFIGURATION['backupDirectoryPath'], maximumBackup)
else:
stash.TraceOnce(f"Skipping DB backup file trim because backupDirectoryPath does NOT exist. backupDirectoryPath={stash.STASH_CONFIGURATION['backupDirectoryPath']}")
result = self.runBackupTask(task)
elif task['task'] == "Scan":
result = stash.metadata_scan(paths=targetPaths)
elif task['task'] == "Auto Tag":
@@ -261,94 +243,138 @@ class StashScheduler: # Stash Scheduler
Msg = task['msg']
result = stash.TraceOnce(Msg)
elif task['task'] == "CheckStashIsRunning":
try:
result = stash.stash_version()
except:
pass
# Note: Can not call stash.Error if Stash is not running, because that might throw another exception.
stash.Trace("Failed to get response from Stash.")
if platform.system() == "Windows":
args = [f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-win.exe"]
elif platform.system() == "Darwin": # MacOS
args = [f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep} stash-macos "]
elif platform.system().lower().startswith("linux"):
# ToDo: Need to verify this method will work for (stash-linux-arm32v6, stash-linux-arm32v7, and stash-linux-arm64v8)
if platform.system().lower().find("32v6") > -1:
args = [f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-linux-arm32v6"]
elif platform.system().lower().find("32v7") > -1:
args = [f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-linux-arm32v7"]
elif platform.system().lower().find("64v8 ") > -1:
args = [f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-linux-arm64v8"]
else:
args = [f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-linux"]
elif platform.system().lower().startswith("freebsd"):
args = [f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-freebsd"]
elif 'command' not in task or task['command'] == "":
stash.Trace("Error: Can not start Stash, because failed to determine platform OS. As a workaround, add 'command' field to this task.")
return
if 'command' in task and task['command'] != "":
cmd = task['command'].replace("<stash_path>", f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}")
args = [cmd]
result = f"Execute process PID = {stash.ExecuteProcess(args)}"
time.sleep(10)
if "RunAfter" in task and len(task['RunAfter']) > 0:
for runAfterTask in task['RunAfter']:
self.runTask(runAfterTask)
result = self.checkStashIsRunning(task)
elif task['task'] == "python":
if 'script' in task and task['script'] != "":
script = task['script'].replace("<plugin_path>", f"{pathlib.Path(__file__).resolve().parent}{os.sep}")
stash.Log(f"Executing python script {script}.")
args = [script]
if 'args' in task and len(task['args']) > 0:
args = args + [task['args']]
detached = True
if 'detach' in task:
detached = task['detach']
result = f"Python process PID = {stash.ExecutePythonScript(args, ExecDetach=detached)}"
else:
stash.Error(f"Can not run task '{task['task']}', because it's missing 'script' field.")
result = self.runPythonScript(task)
elif task['task'] == "execute":
if 'command' in task and task['command'] != "":
cmd = task['command'].replace("<plugin_path>", f"{pathlib.Path(__file__).resolve().parent}{os.sep}")
args = [cmd]
if 'args' in task and len(task['args']) > 0:
args = args + [task['args']]
stash.Log(f"Executing command arguments {args}.")
result = f"Execute process PID = {stash.ExecuteProcess(args)}"
else:
stash.Error(f"Can not run task '{task['task']}', because it's missing 'command' field.")
result = self.runExecuteProcessTask(task)
else:
# ToDo: Add code to check if plugin is installed.
try:
if 'pluginId' in task and task['pluginId'] != "":
invalidDir = False
validDirMsg = ""
if 'validateDir' in task and task['validateDir'] != "":
invalidDir = True
communityPluginPath = f"{stash.PLUGINS_PATH}{os.sep}community{os.sep}{task['validateDir']}"
basePluginPath = f"{stash.PLUGINS_PATH}{os.sep}{task['validateDir']}"
if os.path.exists(communityPluginPath):
invalidDir = False
validDirMsg = f"Valid path in {communityPluginPath}"
elif os.path.exists(basePluginPath):
invalidDir = False
validDirMsg = f"Valid path in {basePluginPath}"
if invalidDir:
stash.Error(f"Could not run task '{task['task']}' because sub directory '{task['validateDir']}' does not exist under path '{stash.PLUGINS_PATH}'")
else:
stash.Trace(f"Running plugin task pluginID={task['pluginId']}, task name = {task['task']}. {validDirMsg}")
stash.run_plugin_task(plugin_id=task['pluginId'], task_name=task['task'])
else:
stash.Error(f"Can not run task '{task['task']}', because it's an invalid task.")
stash.LogOnce(f"If task '{task['task']}' is supposed to be a built-in task, check for correct task name spelling.")
stash.LogOnce(f"If task '{task['task']}' is supposed to be a plugin, make sure to include the pluginId field in the task. task={task}")
except Exception as e:
stash.LogOnce(f"Failed to call plugin {task['task']} with plugin-ID {task['pluginId']}. Error: {e}")
pass
result = self.runPluginTask(task)
if result:
stash.Trace(f"Task '{task['task']}' result={result}")
def runExecuteProcessTask(self, task):
if 'command' in task and task['command'] != "":
cmd = task['command'].replace("<plugin_path>", f"{pathlib.Path(__file__).resolve().parent}{os.sep}")
args = [cmd]
if 'args' in task and len(task['args']) > 0:
args = args + [task['args']]
stash.Log(f"Executing command arguments {args}.")
return f"Execute process PID = {stash.ExecuteProcess(args)}"
else:
stash.Error(f"Can not run task '{task['task']}', because it's missing 'command' field.")
return None
def runPythonScript(self, task):
if 'script' in task and task['script'] != "":
script = task['script'].replace("<plugin_path>", f"{pathlib.Path(__file__).resolve().parent}{os.sep}")
stash.Log(f"Executing python script {script}.")
args = [script]
if 'args' in task and len(task['args']) > 0:
args = args + [task['args']]
detached = True
if 'detach' in task:
detached = task['detach']
return f"Python process PID = {stash.ExecutePythonScript(args, ExecDetach=detached)}"
else:
stash.Error(f"Can not run task '{task['task']}', because it's missing 'script' field.")
return None
def runPluginTask(self, task):
# ToDo: Add code to check if plugin is installed.
try:
if 'pluginId' in task and task['pluginId'] != "":
invalidDir = False
validDirMsg = ""
if 'validateDir' in task and task['validateDir'] != "":
invalidDir = True
communityPluginPath = f"{stash.PLUGINS_PATH}{os.sep}community{os.sep}{task['validateDir']}"
basePluginPath = f"{stash.PLUGINS_PATH}{os.sep}{task['validateDir']}"
if os.path.exists(communityPluginPath):
invalidDir = False
validDirMsg = f"Valid path in {communityPluginPath}"
elif os.path.exists(basePluginPath):
invalidDir = False
validDirMsg = f"Valid path in {basePluginPath}"
if invalidDir:
stash.Error(f"Could not run task '{task['task']}' because sub directory '{task['validateDir']}' does not exist under path '{stash.PLUGINS_PATH}'")
else:
stash.Trace(f"Running plugin task pluginID={task['pluginId']}, task name = {task['task']}. {validDirMsg}")
return stash.run_plugin_task(plugin_id=task['pluginId'], task_name=task['task'])
else:
stash.Error(f"Can not run task '{task['task']}', because it's an invalid task.")
stash.LogOnce(f"If task '{task['task']}' is supposed to be a built-in task, check for correct task name spelling.")
stash.LogOnce(f"If task '{task['task']}' is supposed to be a plugin, make sure to include the pluginId field in the task. task={task}")
except Exception as e:
stash.LogOnce(f"Failed to call plugin {task['task']} with plugin-ID {task['pluginId']}. Error: {e}")
pass
return None
def checkStashIsRunning(self, task):
try:
result = stash.stash_version()
except:
pass
stash.Error("Failed to get response from Stash.")
if platform.system() == "Windows":
execPath = f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-win.exe"
elif platform.system() == "Darwin": # MacOS
execPath = f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep} stash-macos "
elif platform.system().lower().startswith("linux"):
# ToDo: Need to verify this method will work for (stash-linux-arm32v6, stash-linux-arm32v7, and stash-linux-arm64v8)
if platform.system().lower().find("32v6") > -1:
execPath = f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-linux-arm32v6"
elif platform.system().lower().find("32v7") > -1:
execPath = f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-linux-arm32v7"
elif platform.system().lower().find("64v8 ") > -1:
execPath = f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-linux-arm64v8"
else:
execPath = f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-linux"
elif platform.system().lower().startswith("freebsd"):
execPath = f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}stash-freebsd"
elif 'command' not in task or task['command'] == "":
stash.Error("Can not start Stash, because failed to determine platform OS. As a workaround, add 'command' field to this task.")
return None
if 'command' in task and task['command'] != "":
cmd = task['command'].replace("<stash_path>", f"{pathlib.Path(stash.PLUGINS_PATH).resolve().parent}{os.sep}")
args = [cmd]
else:
if os.path.isfile(execPath):
args = [execPath]
else:
stash.Error("Could not start Stash, because could not find executable Stash file '{execPath}'")
return None
result = f"Execute process PID = {stash.ExecuteProcess(args)}"
time.sleep(10)
if "RunAfter" in task and len(task['RunAfter']) > 0:
for runAfterTask in task['RunAfter']:
self.runTask(runAfterTask)
return result
def runBackupTask(self, task):
stash.LogOnce("Note: Backup task does not get listed in the Task Queue, but user can verify that it started by looking in the Stash log file as an INFO level log line.")
result = stash.backup_database()
maximumBackup = stash.pluginSettings['zmaximumBackups']
stash.Trace(f"maximumBackup={maximumBackup}")
if "maxBackups" in task:
maximumBackup = task['maxBackups']
stash.Trace(f"maximumBackup={maximumBackup}")
if isinstance(maximumBackup,str):
maximumBackup = int(maximumBackup)
if maximumBackup < 2:
stash.TraceOnce(f"Skipping DB backup file trim because zmaximumBackups={maximumBackup}. Value has to be greater than 1.")
elif 'backupDirectoryPath' in stash.STASH_CONFIGURATION:
if len(stash.STASH_CONFIGURATION['backupDirectoryPath']) < 5:
stash.TraceOnce(f"Skipping DB backup file trim because backupDirectoryPath length is to short. Len={len(stash.STASH_CONFIGURATION['backupDirectoryPath'])}. Only support length greater than 4 characters.")
elif os.path.exists(stash.STASH_CONFIGURATION['backupDirectoryPath']):
stash.LogOnce(f"Checking quantity of DB backups if path {stash.STASH_CONFIGURATION['backupDirectoryPath']} exceeds {maximumBackup} backup files.")
self.trimDbFiles(stash.STASH_CONFIGURATION['backupDirectoryPath'], maximumBackup)
else:
stash.TraceOnce(f"Skipping DB backup file trim because backupDirectoryPath does NOT exist. backupDirectoryPath={stash.STASH_CONFIGURATION['backupDirectoryPath']}")
return result
def trimDbFiles(self, dbPath, maxFiles):
if not os.path.exists(dbPath):
stash.LogOnce(f"Exiting trimDbFiles, because path {dbPath} does not exists.")

View File

@@ -8,7 +8,8 @@ config = {
# The [Auto Tag] task is an example of a daily scheduled task.
# The [Generate] task is an example of a weekly scheduled task.
# The [Backup] task is an example of a monthly scheduled task.
# Note: The hour section in time MUST be a two digit number, and use military time format. Example: 1PM = "13:00" and 1AM = "01:00"
# The hour section in time MUST be a two digit number, and use military time format. Example: 1PM = "13:00" and 1AM = "01:00"
# Note: Look at filemonitor_task_examples.py for many example task having more detailed usage.
"task_scheduler": [
# To create a daily task, include each day of the week for the weekday field.
{"task" : "Auto Tag", "weekday" : "monday,tuesday,wednesday,thursday,friday,saturday,sunday", "time" : "06:00"}, # Auto Tag -> [Auto Tag] (Daily at 6AM)
@@ -32,86 +33,10 @@ config = {
{"task" : "Clean", "weekday" : "sunday", "time" : "01:00", "monthly" : 3}, # Maintenance -> [Clean]
{"task" : "Clean Generated Files", "weekday" : "sunday", "time" : "03:00", "monthly" : 3}, # Maintenance -> [Clean Generated Files]
# The [CheckStashIsRunning] task checks if Stash is running. If it's not, it will start up stash. This task only works if FileMonitor is started as a service or in command line mode.
# The [CheckStashIsRunning] task checks if Stash is running. If not running, it will start up stash.
# This task only works if FileMonitor is started as a service or in command line mode.
# For more detailed usage, see examples #C1 and #C2 in filemonitor_task_examples.py
{"task" : "CheckStashIsRunning", "minutes" :5}, # Checks every 5 minutes
# Example#C1 Some OS may need the "command" field, which specifies the binary path
{"task" : "CheckStashIsRunning", "command" : "<stash_path>stash-linux-arm64v8", "minutes" :0},
# Example#C2 RunAfter field can be used to specify task to run after starting Stash
{"task" : "CheckStashIsRunning", "RunAfter" : [{"task" : "Scan"},{"task" : "Backup", "maxBackup" : 0},{"task" : "Clean"}], "minutes" :0},
# Example#A1: Task to call call_GQL API with custom input
{"task" : "GQL", "input" : "mutation OptimiseDatabase { optimiseDatabase }", "weekday" : "sunday", "time" : "DISABLED"}, # To enable, change "DISABLED" to valid time
# Example#A2: Task to call a python script. When this task is executed, the keyword <plugin_path> is replaced by filemonitor.py current directory.
# The args field is NOT required.
{"task" : "python", "script" : "<plugin_path>test_script_hello_world.py", "args" : "--MyArguments Hello", "weekday" : "monday", "time" : "DISABLED"}, # change "DISABLED" to valid time
# Example#A3: The following task types can optionally take a [paths] field. If the paths field does not exists, the paths in the Stash library is used.
{"task" : "Scan", "paths" : [r"E:\MyVideos\downloads", r"V:\MyOtherVideos"], "weekday" : "sunday", "time" : "DISABLED"}, # Library -> [Scan]
{"task" : "Auto Tag", "paths" : [r"E:\MyVideos\downloads", r"V:\MyOtherVideos"], "weekday" : "monday,tuesday,wednesday,thursday,friday,saturday,sunday", "time" : "DISABLED"}, # Auto Tag -> [Auto Tag]
{"task" : "Clean", "paths" : ["E:\\MyVideos\\downloads", "V:\\MyOtherVideos"], "weekday" : "sunday", "time" : "DISABLED"}, # Generated Content-> [Generate]
# Example#A4: Task which calls Migrations -> [Rename generated files]
{"task" : "RenameGeneratedFiles", "weekday" : "tuesday,thursday", "time" : "DISABLED"}, # (bi-weekly) example
# Example#A5: The Backup task using optional field maxBackup, which overrides the UI [Max DB Backups] value
{"task" : "Backup", "maxBackup" : 12, "weekday" : "sunday", "time" : "DISABLED"}, # Trim the DB backup files down to 12 backup files.
{"task" : "Backup", "maxBackup" : 0, "weekday" : "sunday", "time" : "DISABLED"}, # When used with a zero value, it will make sure no file trimming will occur no matter the value of the UI [Max DB Backups]
# The above weekday method is the more reliable method to schedule task, because it doesn't rely on FileMonitor running continuously (non-stop).
# The below examples use frequency field method which can work with minutes and hours. A zero frequency value disables the task.
# Note: Both seconds and days are also supported for the frequency field.
# However, seconds is mainly used for test purposes.
# And days usage is discourage, because it only works if FileMonitor is running for X many days non-stop.
# The below example tasks are done using hours and minutes, however any of these task types can be converted to a daily, weekly, or monthly syntax.
# Example#B1: The following task is the syntax used for a plugin. A plugin task requires the plugin name for the [task] field, and the plugin-ID for the [pluginId] field.
{"task" : "PluginButtonName_Here", "pluginId" : "PluginId_Here", "hours" : 0}, # The zero frequency value makes this task disabled.
# Example#B2: Optionally, the validateDir field can be included which is used to validate that the plugin is installed either under the plugins folder or under the plugins-community folder.
{"task" : "PluginButtonName_Here", "pluginId" : "PluginId_Here", "validateDir" : "UsuallySameAsPluginID", "hours" : 0}, # The zero frequency value makes this task disabled.
# Example#B3: Task to execute a command
{"task" : "execute", "command" : "C:\\MyPath\\HelloWorld.bat", "hours" : 0},
# Example#B4: Task to execute a command with optional args field, and using keyword <plugin_path>, which gets replaced with filemonitor.py current directory.
{"task" : "execute", "command" : "<plugin_path>HelloWorld.cmd", "args" : "--name David", "minutes" : 0},
# Comment out **test** tasks.
# To run test, enable all task, and start FileMonitor as a service.
# When executed, these task should be seen in the Task Queue unless otherwise stated in comments.
# These tasks are usually executed before updating major releases on https://github.com/David-Maisonave/Axter-Stash/blob/main/plugins/FileMonitor
# These tasks are ALWAYS executed before updating to https://github.com/stashapp/CommunityScripts
# MUST ToDo: Always comment out below test task before checking in this code!!!
# {"task" : "TestBadTaskNameError", "minutes" : 1}, # Test invalid task name
# {"task" : "execute", "minutes" : 1}, # Test invalid task (missing command)
# {"task" : "python", "minutes" : 1}, # Test invalid task (missing scripts)
# {"task" : "PluginWithOutID", "minutes" : 1}, # Test invalid task (missing pluginId)
# {"task" : "execute", "command" : "", "minutes" : 1}, # Test invalid task (missing command)
# {"task" : "python", "script" : "", "minutes" : 1}, # Test invalid task (missing scripts)
# {"task" : "PluginWithOutID", "pluginId" : "", "minutes" : 1}, # Test invalid task (missing pluginId)
# {"task" : "Foo","pluginId":"foo","validateDir":"foo", "minutes" : 1}, # Test invalid task (missing plugin directory)
# {"task" : "Log", "msg" : "Testing Scheduled Log", "minutes" : 1}, # Test plugin log file
# {"task" : "Trace", "minutes" : 1}, # Test plugin trace logging
# {"task" : "LogOnce", "seconds" :15}, # Test LogOnce
# {"task" : "TraceOnce", "seconds" : 5}, # Test TraceOnce
# {"task" : "CheckStashIsRunning", "RunAfter" : [{"task" : "Scan"},{"task" : "Backup", "maxBackup" : 0},{"task" : "Clean"}], "seconds" :15}, # Test RunAfter
# {"task" : "CheckStashIsRunning", "command" : "<stash_path>stash-win.exe", "seconds" :10}, # Check if Stash is running. If not running, start up Stash.
# {"task" : "Generate", "weekday" : "friday", "time" : "12:03"},
# {"task" : "Clean", "weekday" : "friday", "time" : "12:03"},
# {"task" : "Auto Tag", "weekday" : "friday", "time" : "12:03"},
# {"task" : "Optimise Database", "weekday" : "friday", "time" : "12:03"},
# {"task" : "Create Tags", "pluginId" : "pathParser", "validateDir" : "pathParser", "weekday" : "friday", "time" : "12:03"}, # In task queue as -> Running plugin task: Create Tags
# {"task" : "Scan","paths": [r"B:\_\SpecialSet", r"C:\foo"], "weekday" : "friday", "time" : "12:03"},
# {"task" : "GQL", "input" : "mutation OptimiseDatabase { optimiseDatabase }", "weekday" : "friday", "time" : "12:03"}, # In task queue as -> Optimising database...
# {"task" : "Clean Generated Files", "weekday" : "friday", "time" : "12:03"},
# {"task" : "RenameGeneratedFiles", "weekday" : "friday", "time" : "12:03"}, # In task queue as -> Migrating scene hashes...
# {"task" : "Backup", "maxBackups" : 0, "weekday" : "friday", "time" : "12:03"}, # Does NOT show up in the Task Queue. Must check STASH log file to verify run.
# {"task" : "python", "script" : "<plugin_path>test_hello_world2.py", "weekday" : "friday", "time" : "12:03"}, # Does NOT show up in the Task Queue. Check FileMonitor log file, and look for -> Task 'python' result=???
# {"task" : "python", "script" : "<plugin_path>test_hello_world.py", "detach" : False, "weekday" : "friday", "time" : "12:03"}, # Does NOT show up in the Task Queue. Check FileMonitor log file, and look for -> Task 'python' result=???
# {"task" : "execute", "command" : "<plugin_path>test_hello_world2.cmd", "weekday" : "friday", "time" : "12:03"}, # Does NOT show up in the Task Queue. Check FileMonitor log file, and look for -> Task 'execute' result=???
# {"task" : "execute", "command" : "<plugin_path>test_hello_world.bat", "args" : "--name David", "weekday" : "friday", "time" : "12:03"}, # Does NOT show up in the Task Queue. Check FileMonitor log file, and look for -> Task 'execute' result=???
],
# ApiKey only needed when Stash credentials are set and while calling FileMonitor via command line.

View File

@@ -0,0 +1,42 @@
# **test** tasks which are disabled by default. To enable test tasks, set selfUnitTest to True.
# To run test, enable all task, and start FileMonitor as a service.
# When executed, these task should be seen in the Task Queue unless otherwise stated in comments.
# These tasks are usually executed before updating major releases on https://github.com/David-Maisonave/Axter-Stash/blob/main/plugins/FileMonitor
# These tasks are ALWAYS executed before updating to https://github.com/stashapp/CommunityScripts
self_unit_test = {
"task_scheduler": [
{"task" : "TestBadTaskNameError", "minutes" : 1}, # Test invalid task name
{"task" : "execute", "minutes" : 1}, # Test invalid task (missing command)
{"task" : "python", "minutes" : 1}, # Test invalid task (missing scripts)
{"task" : "PluginWithOutID", "minutes" : 1}, # Test invalid task (missing pluginId)
{"task" : "execute", "command" : "", "minutes" : 1}, # Test invalid task (missing command)
{"task" : "python", "script" : "", "minutes" : 1}, # Test invalid task (missing scripts)
{"task" : "PluginWithOutID", "pluginId" : "", "minutes" : 1}, # Test invalid task (missing pluginId)
{"task" : "Foo","pluginId":"foo","validateDir":"foo", "minutes" : 1}, # Test invalid task (missing plugin directory)
{"task" : "Log", "msg" : "Testing Scheduled Log", "minutes" : 1}, # Test plugin log file
{"task" : "Trace", "minutes" : 1}, # Test plugin trace logging
{"task" : "LogOnce", "seconds" :15}, # Test LogOnce
{"task" : "TraceOnce", "seconds" : 5}, # Test TraceOnce
# {"task" : "CheckStashIsRunning", "RunAfter" : [{"task" : "Scan"}], "seconds" :15}, # To test CheckStashIsRunning, kill Stash after starting FileMonitor service via following command:taskkill /F /IM "stash-win.exe"
{"task" : "CheckStashIsRunning", "RunAfter" : [{"task" : "Scan"},{"task" : "Backup", "maxBackup" : 0},{"task" : "Clean"}], "seconds" :15}, # Test RunAfter
{"task" : "CheckStashIsRunning", "command" : "<stash_path>stash-win.exe", "seconds" :10}, # Check if Stash is running. If not running, start up Stash.
{"task" : "Generate", "weekday" : "friday", "time" : "12:03"},
{"task" : "Clean", "weekday" : "friday", "time" : "12:03"},
{"task" : "Auto Tag", "weekday" : "friday", "time" : "12:03"},
{"task" : "Optimise Database", "weekday" : "friday", "time" : "12:03"},
{"task" : "Create Tags", "pluginId" : "pathParser", "validateDir" : "pathParser", "weekday" : "friday", "time" : "12:03"}, # In task queue as -> Running plugin task: Create Tags
{"task" : "Scan","paths": [r"B:\_\SpecialSet", r"C:\foo"], "weekday" : "friday", "time" : "12:03"},
{"task" : "GQL", "input" : "mutation OptimiseDatabase { optimiseDatabase }", "weekday" : "friday", "time" : "12:03"}, # In task queue as -> Optimising database...
{"task" : "Clean Generated Files", "weekday" : "friday", "time" : "12:03"},
{"task" : "RenameGeneratedFiles", "weekday" : "friday", "time" : "12:03"}, # In task queue as -> Migrating scene hashes...
{"task" : "Backup", "maxBackups" : 0, "weekday" : "friday", "time" : "12:03"}, # Does NOT show up in the Task Queue. Must check STASH log file to verify run.
{"task" : "python", "script" : "<plugin_path>test_hello_world2.py", "weekday" : "friday", "time" : "12:03"}, # Does NOT show up in the Task Queue. Check FileMonitor log file, and look for -> Task 'python' result=???
{"task" : "python", "script" : "<plugin_path>test_hello_world.py", "detach" : False, "weekday" : "friday", "time" : "12:03"}, # Does NOT show up in the Task Queue. Check FileMonitor log file, and look for -> Task 'python' result=???
{"task" : "execute", "command" : "<plugin_path>test_hello_world2.cmd", "weekday" : "friday", "time" : "12:03"}, # Does NOT show up in the Task Queue. Check FileMonitor log file, and look for -> Task 'execute' result=???
{"task" : "execute", "command" : "<plugin_path>test_hello_world.bat", "args" : "--name David", "weekday" : "friday", "time" : "12:03"}, # Does NOT show up in the Task Queue. Check FileMonitor log file, and look for -> Task 'execute' result=???
],
# MUST ToDo: Always set selfUnitTest to False before checking in this code!!!
# Enable to turn on self unit test.
"selfUnitTest": False,
}

View File

@@ -0,0 +1,49 @@
# Below are example tasks.
# They are all disabled by default, by having zero value for time frequency, or by having "DISABLED" set for the time field.
# To enable these tasks, set the frequency or the time value to a valid frequency or time stamp.
task_examples = {
"task_scheduler": [
# Example#A1: Task to call call_GQL API with custom input
{"task" : "GQL", "input" : "mutation OptimiseDatabase { optimiseDatabase }", "weekday" : "sunday", "time" : "DISABLED"}, # To enable, change "DISABLED" to valid time
# Example#A2: Task to call a python script. When this task is executed, the keyword <plugin_path> is replaced by filemonitor.py current directory.
# The args field is NOT required.
{"task" : "python", "script" : "<plugin_path>test_script_hello_world.py", "args" : "--MyArguments Hello", "weekday" : "monday", "time" : "DISABLED"}, # change "DISABLED" to valid time
# Example#A3: The following task types can optionally take a [paths] field. If the paths field does not exists, the paths in the Stash library is used.
{"task" : "Scan", "paths" : [r"E:\MyVideos\downloads", r"V:\MyOtherVideos"], "weekday" : "sunday", "time" : "DISABLED"}, # Library -> [Scan]
{"task" : "Auto Tag", "paths" : [r"E:\MyVideos\downloads", r"V:\MyOtherVideos"], "weekday" : "monday,tuesday,wednesday,thursday,friday,saturday,sunday", "time" : "DISABLED"}, # Auto Tag -> [Auto Tag]
{"task" : "Clean", "paths" : ["E:\\MyVideos\\downloads", "V:\\MyOtherVideos"], "weekday" : "sunday", "time" : "DISABLED"}, # Generated Content-> [Generate]
# Example#A4: Task which calls Migrations -> [Rename generated files]
{"task" : "RenameGeneratedFiles", "weekday" : "tuesday,thursday", "time" : "DISABLED"}, # (bi-weekly) example
# Example#A5: The Backup task using optional field maxBackup, which overrides the UI [Max DB Backups] value
{"task" : "Backup", "maxBackup" : 12, "weekday" : "sunday", "time" : "DISABLED"}, # Trim the DB backup files down to 12 backup files.
{"task" : "Backup", "maxBackup" : 0, "weekday" : "sunday", "time" : "DISABLED"}, # When used with a zero value, it will make sure no file trimming will occur no matter the value of the UI [Max DB Backups]
# The above weekday method is the more reliable method to schedule task, because it doesn't rely on FileMonitor running continuously (non-stop).
# The below examples use frequency field method which can work with minutes and hours. A zero frequency value disables the task.
# Note: Both seconds and days are also supported for the frequency field.
# However, seconds is mainly used for test purposes.
# And days usage is discourage, because it only works if FileMonitor is running for X many days non-stop.
# The below example tasks are done using hours and minutes, however any of these task types can be converted to a daily, weekly, or monthly syntax.
# Example#B1: The following task is the syntax used for a plugin. A plugin task requires the plugin name for the [task] field, and the plugin-ID for the [pluginId] field.
{"task" : "PluginButtonName_Here", "pluginId" : "PluginId_Here", "hours" : 0}, # The zero frequency value makes this task disabled.
# Example#B2: Optionally, the validateDir field can be included which is used to validate that the plugin is installed either under the plugins folder or under the plugins-community folder.
{"task" : "PluginButtonName_Here", "pluginId" : "PluginId_Here", "validateDir" : "UsuallySameAsPluginID", "hours" : 0}, # The zero frequency value makes this task disabled.
# Example#B3: Task to execute a command
{"task" : "execute", "command" : "C:\\MyPath\\HelloWorld.bat", "hours" : 0},
# Example#B4: Task to execute a command with optional args field, and using keyword <plugin_path>, which gets replaced with filemonitor.py current directory.
{"task" : "execute", "command" : "<plugin_path>HelloWorld.cmd", "args" : "--name David", "minutes" : 0},
# Example#C1 Some OS may need the "command" field, which specifies the binary path
{"task" : "CheckStashIsRunning", "command" : "<stash_path>stash-linux-arm64v8", "minutes" :0},
# Example#C2 RunAfter field can be used to specify task to run after starting Stash
{"task" : "CheckStashIsRunning", "RunAfter" : [{"task" : "Scan"},{"task" : "Backup", "maxBackup" : 0},{"task" : "Clean"}], "minutes" :0},
],
}