From bc9d556f3a890cf5f99e9dced0117e2d8a91ff09 Mon Sep 17 00:00:00 2001 From: "Avi Halachmi (:avih)" Date: Thu, 10 Jun 2021 12:32:28 +0300 Subject: js: add mp.utils.append_file Also, for consistency with other APIs, mp.utils.{write,append}_file now return true on success (and still throw on any error). --- DOCS/man/javascript.rst | 10 ++++++++-- player/javascript.c | 22 +++++++++++++--------- player/javascript/defaults.js | 2 ++ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/DOCS/man/javascript.rst b/DOCS/man/javascript.rst index 1e5ce99cdc..0cd4fb806e 100644 --- a/DOCS/man/javascript.rst +++ b/DOCS/man/javascript.rst @@ -221,7 +221,8 @@ Additional utilities ``mp.utils.get_user_path(path)`` Expands (mpv) meta paths like ``~/x``, ``~~/y``, ``~~desktop/z`` etc. - ``read_file``, ``write_file`` and ``require`` already use this internaly. + ``read_file``, ``write_file``, ``append_file`` and ``require`` already use + this internaly. ``mp.utils.read_file(fname [,max])`` Returns the content of file ``fname`` as string. If ``max`` is provided and @@ -232,7 +233,12 @@ Additional utilities prefixed with ``file://`` as simple protection against accidental arguments switch, e.g. ``mp.utils.write_file("file://~/abc.txt", "hello world")``. -Note: ``read_file`` and ``write_file`` throw on errors, allow text content only. +``mp.utils.append_file(fname, str)`` + Same as ``mp.utils.write_file`` if the file ``fname`` does not exist. If it + does exist then append instead of overwrite. + +Note: ``read_file``, ``write_file`` and ``append_file`` throw on errors, allow +text content only. ``mp.get_time_ms()`` Same as ``mp.get_time()`` but in ms instead of seconds. diff --git a/player/javascript.c b/player/javascript.c index 406a469447..136a5965b9 100644 --- a/player/javascript.c +++ b/player/javascript.c @@ -924,27 +924,31 @@ static void script_get_user_path(js_State *J, void *af) js_pushstring(J, mp_get_user_path(af, jctx(J)->mpctx->global, path)); } -// args: prefixed file name, data (c-str) -static void script_write_file(js_State *J, void *af) +// args: is_append, prefixed file name, data (c-str) +static void script__write_file(js_State *J, void *af) { static const char *prefix = "file://"; - const char *fname = js_tostring(J, 1); - const char *data = js_tostring(J, 2); + bool append = js_toboolean(J, 1); + const char *fname = js_tostring(J, 2); + const char *data = js_tostring(J, 3); + const char *opstr = append ? "append" : "write"; + if (strstr(fname, prefix) != fname) // simple protection for incorrect use js_error(J, "File name must be prefixed with '%s'", prefix); fname += strlen(prefix); fname = mp_get_user_path(af, jctx(J)->mpctx->global, fname); - MP_VERBOSE(jctx(J), "Writing file '%s'\n", fname); + MP_VERBOSE(jctx(J), "%s file '%s'\n", opstr, fname); - FILE *f = fopen(fname, "wb"); + FILE *f = fopen(fname, append ? "ab" : "wb"); if (!f) - js_error(J, "Cannot open file for writing: '%s'", fname); + js_error(J, "Cannot open (%s) file: '%s'", opstr, fname); add_af_file(af, f); int len = strlen(data); // limited by terminating null int wrote = fwrite(data, 1, len, f); if (len != wrote) - js_error(J, "Cannot write to file: '%s'", fname); + js_error(J, "Cannot %s to file: '%s'", opstr, fname); + js_pushboolean(J, 1); // success. doesn't touch last_error } // args: env var name @@ -1179,7 +1183,7 @@ static const struct fn_entry utils_fns[] = { FN_ENTRY(get_env_list, 0), FN_ENTRY(read_file, 2), - AF_ENTRY(write_file, 2), + AF_ENTRY(_write_file, 3), FN_ENTRY(getenv, 1), FN_ENTRY(compile_js, 2), FN_ENTRY(_gc, 1), diff --git a/player/javascript/defaults.js b/player/javascript/defaults.js index c4482c88ce..037f931d94 100644 --- a/player/javascript/defaults.js +++ b/player/javascript/defaults.js @@ -665,6 +665,8 @@ mp.get_time = function() { return mp.get_time_ms() / 1000 }; mp.utils.getcwd = function() { return mp.get_property("working-directory") }; mp.utils.getpid = function() { return mp.get_property_number("pid") } mp.get_mouse_pos = function() { return mp.get_property_native("mouse-pos") }; +mp.utils.write_file = mp.utils._write_file.bind(null, false); +mp.utils.append_file = mp.utils._write_file.bind(null, true); mp.dispatch_event = dispatch_event; mp.process_timers = process_timers; mp.notify_idle_observers = notify_idle_observers; -- cgit v1.2.3