From 1928d9275253562fe9d984e0115fa782bbed9355 Mon Sep 17 00:00:00 2001 From: jcorporation Date: Mon, 13 May 2024 21:05:26 +0200 Subject: [PATCH] Feat: populate scriptevent variable for lua scripts #1279 --- docs/scripting/index.md | 1 + htdocs/js/apidoc.js | 5 +++ htdocs/js/modalScriptExec.js | 2 ++ src/mympd_api/mympd_api_handler.c | 8 +++-- src/mympd_api/scripts/scripts.c | 54 +++++++++++++++++++++++++------ src/mympd_api/scripts/scripts.h | 13 +++++++- src/mympd_api/timer_handlers.c | 2 ++ src/mympd_api/trigger.c | 2 ++ 8 files changed, 74 insertions(+), 13 deletions(-) diff --git a/docs/scripting/index.md b/docs/scripting/index.md index 4d7d8736f..c44640bfb 100644 --- a/docs/scripting/index.md +++ b/docs/scripting/index.md @@ -14,6 +14,7 @@ myMPD populates automatically some global variables. | -------- | ----------- | | `arguments` | Script arguments | | `partition` | MPD partition | +| `scriptevent` | Script start event: `extern`, `http`, `timer`, `trigger` or `user` | | `scriptname` | Script name | ### Arguments diff --git a/htdocs/js/apidoc.js b/htdocs/js/apidoc.js index cede9d5f4..bfbaa861c 100644 --- a/htdocs/js/apidoc.js +++ b/htdocs/js/apidoc.js @@ -1816,6 +1816,11 @@ const APImethods = { "desc": "Executes a script", "params": { "script": APIparams.script, + "event": { + "type": APItypes.string, + "example": "user", + "desc": "One of: extern, http, timer, trigger or user" + }, "arguments": APIparams.scriptArguments } }, diff --git a/htdocs/js/modalScriptExec.js b/htdocs/js/modalScriptExec.js index cb1e750e9..3ddfb687e 100644 --- a/htdocs/js/modalScriptExec.js +++ b/htdocs/js/modalScriptExec.js @@ -28,6 +28,7 @@ function execScript(cmd) { if (cmd.arguments.length === 0) { sendAPI("MYMPD_API_SCRIPT_EXECUTE", { "script": cmd.script, + "event": "user", "arguments": {} }, null, false); } @@ -64,6 +65,7 @@ function execScriptArgs(target) { } sendAPI("MYMPD_API_SCRIPT_EXECUTE", { "script": script, + "event": "user", "arguments": args }, modalClose, true); } diff --git a/src/mympd_api/mympd_api_handler.c b/src/mympd_api/mympd_api_handler.c index de243a0ec..fb256d54b 100644 --- a/src/mympd_api/mympd_api_handler.c +++ b/src/mympd_api/mympd_api_handler.c @@ -333,12 +333,14 @@ void mympd_api_handler(struct t_mympd_state *mympd_state, struct t_partition_sta break; } case MYMPD_API_SCRIPT_EXECUTE: { - //malloc list - it is used in another thread + //malloc list - it is used in the script thread struct t_list *arguments = list_new(); if (json_get_string(request->data, "$.params.script", 1, FILENAME_LEN_MAX, &sds_buf1, vcb_isfilename, &parse_error) == true && + json_get_string(request->data, "$.params.event", 0, FILENAME_LEN_MAX, &sds_buf2, vcb_isfilename, &parse_error) == true && json_get_object_string(request->data, "$.params.arguments", arguments, vcb_isname, 10, &parse_error) == true) { - rc = mympd_api_script_start(config->workdir, sds_buf1, config->lualibs, arguments, partition_state->name, true); + enum script_start_events script_event = script_start_event_parse(sds_buf2); + rc = mympd_api_script_start(config->workdir, sds_buf1, config->lualibs, arguments, partition_state->name, true, script_event); response->data = jsonrpc_respond_with_ok_or_error(response->data, request->cmd_id, request->id, rc, JSONRPC_FACILITY_SCRIPT, "Can't create mympd_script thread"); } @@ -355,7 +357,7 @@ void mympd_api_handler(struct t_mympd_state *mympd_state, struct t_partition_sta if (json_get_string(request->data, "$.params.script", 1, CONTENT_LEN_MAX, &sds_buf1, vcb_istext, &parse_error) == true && json_get_object_string(request->data, "$.params.arguments", arguments, vcb_isname, 10, &parse_error) == true) { - rc = mympd_api_script_start(config->workdir, sds_buf1, config->lualibs, arguments, partition_state->name, false); + rc = mympd_api_script_start(config->workdir, sds_buf1, config->lualibs, arguments, partition_state->name, false, SCRIPT_START_EXTERN); response->data = jsonrpc_respond_with_ok_or_error(response->data, request->cmd_id, request->id, rc, JSONRPC_FACILITY_SCRIPT, "Can't create mympd_script thread"); } diff --git a/src/mympd_api/scripts/scripts.c b/src/mympd_api/scripts/scripts.c index 7651a2b96..6c2474a66 100644 --- a/src/mympd_api/scripts/scripts.c +++ b/src/mympd_api/scripts/scripts.c @@ -45,13 +45,14 @@ * Struct for passing values to the script thread */ struct t_script_thread_arg { - sds lualibs; //!< comma separated string of lua libs to load - bool localscript; //!< true = read script from filesystem, false = use script_content - sds script_fullpath; //!< full uri of the script - sds script_name; //!< name of the script - sds script_content; //!< script content if localscript = false - sds partition; //!< execute the script in this partition - struct t_list *arguments; //!< argumentlist + sds lualibs; //!< comma separated string of lua libs to load + bool localscript; //!< true = read script from filesystem, false = use script_content + sds script_fullpath; //!< full uri of the script + sds script_name; //!< name of the script + sds script_content; //!< script content if localscript = false + sds partition; //!< execute the script in this partition + struct t_list *arguments; //!< argumentlist + enum script_start_events start_event; //!< script start event }; static lua_State *script_load(struct t_script_thread_arg *script_arg, int *rc); @@ -286,7 +287,7 @@ sds mympd_api_script_get(sds workdir, sds buffer, unsigned request_id, sds scrip * @return true on success, else false */ bool mympd_api_script_start(sds workdir, sds script, sds lualibs, struct t_list *arguments, - const char *partition, bool localscript) + const char *partition, bool localscript, enum script_start_events start_event) { pthread_t mympd_script_thread; pthread_attr_t attr; @@ -303,8 +304,9 @@ bool mympd_api_script_start(sds workdir, sds script, sds lualibs, struct t_list script_thread_arg->localscript = localscript; script_thread_arg->arguments = arguments; script_thread_arg->partition = sdsnew(partition); + script_thread_arg->start_event = start_event; if (localscript == true) { - script_thread_arg->script_name = sdsnew(script); + script_thread_arg->script_name = sdsdup(script); script_thread_arg->script_fullpath = sdscatfmt(sdsempty(), "%S/%s/%S.lua", workdir, DIR_WORK_SCRIPTS, script); script_thread_arg->script_content = sdsempty(); } @@ -322,6 +324,37 @@ bool mympd_api_script_start(sds workdir, sds script, sds lualibs, struct t_list return true; } +/** + * Returns the name for the script start event + * @param start_event start event enum + * @return start event name or empty if unknown + */ +const char *script_start_event_name(enum script_start_events start_event) { + switch (start_event) { + case SCRIPT_START_EXTERN: return "extern"; + case SCRIPT_START_HTTP: return "http"; + case SCRIPT_START_TIMER: return "timer"; + case SCRIPT_START_TRIGGER: return "trigger"; + case SCRIPT_START_USER: return "user"; + case SCRIPT_START_UNKNOWN: return ""; + } + return ""; +} + +/** + * Parses the name for the script start event + * @param str string to parse + * @return script_start_event enum + */ +enum script_start_events script_start_event_parse(const char *str) { + if (strcmp(str, "http") == 0) { return SCRIPT_START_HTTP; } + if (strcmp(str, "timer") == 0) { return SCRIPT_START_TIMER; } + if (strcmp(str, "trigger") == 0) { return SCRIPT_START_TRIGGER; } + if (strcmp(str, "user") == 0) { return SCRIPT_START_USER; } + if (strcmp(str, "extern") == 0) { return SCRIPT_START_EXTERN; } + return SCRIPT_START_UNKNOWN; +} + /** * Private functions */ @@ -481,6 +514,9 @@ static void *script_execute(void *script_thread_arg) { //set global lua variable scriptname lua_pushstring(lua_vm, script_arg->script_name); lua_setglobal(lua_vm, "scriptname"); + //set global lua variable scriptevent + lua_pushstring(lua_vm, script_start_event_name(script_arg->start_event)); + lua_setglobal(lua_vm, "scriptevent"); //set arguments lua table lua_newtable(lua_vm); if (script_arg->arguments->length > 0) { diff --git a/src/mympd_api/scripts/scripts.h b/src/mympd_api/scripts/scripts.h index 5909bd47a..a31239b97 100644 --- a/src/mympd_api/scripts/scripts.h +++ b/src/mympd_api/scripts/scripts.h @@ -12,12 +12,23 @@ #include +enum script_start_events { + SCRIPT_START_UNKNOWN = -1, + SCRIPT_START_TIMER, + SCRIPT_START_TRIGGER, + SCRIPT_START_USER, + SCRIPT_START_HTTP, + SCRIPT_START_EXTERN +}; + bool mympd_api_script_save(sds workdir, sds script, sds oldscript, int order, sds content, struct t_list *arguments, sds *error); bool mympd_api_script_validate(sds name, sds content, sds lualibs, sds *error); bool mympd_api_script_delete(sds workdir, sds script); sds mympd_api_script_get(sds workdir, sds buffer, unsigned request_id, sds script); sds mympd_api_script_list(sds workdir, sds buffer, unsigned request_id, bool all); bool mympd_api_script_start(sds workdir, sds script, sds lualibs, struct t_list *arguments, - const char *partition, bool localscript); + const char *partition, bool localscript, enum script_start_events start_event); +const char *script_start_event_name(enum script_start_events start_event); +enum script_start_events script_start_event_parse(const char *str); #endif diff --git a/src/mympd_api/timer_handlers.c b/src/mympd_api/timer_handlers.c index 4a78cf4b0..bc8ee175b 100644 --- a/src/mympd_api/timer_handlers.c +++ b/src/mympd_api/timer_handlers.c @@ -19,6 +19,7 @@ #include "src/mpd_client/shortcuts.h" #include "src/mpd_client/volume.h" #include "src/mympd_api/requests.h" +#include "src/mympd_api/scripts/scripts.h" #include @@ -79,6 +80,7 @@ void timer_handler_select(unsigned timer_id, struct t_timer_definition *definiti else if (strcmp(definition->action, "script") == 0) { struct t_work_request *request = create_request(REQUEST_TYPE_DISCARD, 0, 0, MYMPD_API_SCRIPT_EXECUTE, NULL, definition->partition); request->data = tojson_sds(request->data, "script", definition->subaction, true); + request->data = tojson_char(request->data, "event", script_start_event_name(SCRIPT_START_TIMER), true); request->data = sdscat(request->data, "\"arguments\":{"); struct t_list_node *argument = definition->arguments.head; int i = 0; diff --git a/src/mympd_api/trigger.c b/src/mympd_api/trigger.c index e8b16f5d0..91860ce6c 100644 --- a/src/mympd_api/trigger.c +++ b/src/mympd_api/trigger.c @@ -17,6 +17,7 @@ #include "src/lib/msg_queue.h" #include "src/lib/sds_extras.h" #include "src/lib/state_files.h" +#include "src/mympd_api/scripts/scripts.h" #include #include @@ -488,6 +489,7 @@ static sds trigger_to_line_cb(sds buffer, struct t_list_node *current, bool newl void trigger_execute(sds script, struct t_list *arguments, const char *partition) { struct t_work_request *request = create_request(REQUEST_TYPE_DISCARD, 0, 0, MYMPD_API_SCRIPT_EXECUTE, NULL, partition); request->data = tojson_sds(request->data, "script", script, true); + request->data = tojson_char(request->data, "event", script_start_event_name(SCRIPT_START_TIMER), true); request->data = sdscat(request->data, "\"arguments\": {"); struct t_list_node *argument = arguments->head; int i = 0;