mirror of
https://github.com/mpv-player/mpv
synced 2025-01-30 03:32:50 +00:00
lua+js: implement utils.file_info()
This commit introduces mp.utils.file_info() for querying information on file paths, implemented for both Lua and Javascript. The function takes a file path as an argument and returns a Lua table / JS object upon success. The table/object will contain the values: mode, size, atime, mtime, ctime and the convenience booleans is_file, is_dir. On error, the Lua side will return `nil, error` and the Javascript side will return `undefined` (and mark the last error). This feature utilizes the already existing cross-platform `mp_stat()` function.
This commit is contained in:
parent
47131365a3
commit
522bfe5be1
@ -168,6 +168,8 @@ Otherwise, where the Lua APIs return ``nil`` on error, JS returns ``undefined``.
|
|||||||
|
|
||||||
``mp.utils.readdir(path [, filter])`` (LE)
|
``mp.utils.readdir(path [, filter])`` (LE)
|
||||||
|
|
||||||
|
``mp.utils.file_info(path)`` (LE)
|
||||||
|
|
||||||
``mp.utils.split_path(path)``
|
``mp.utils.split_path(path)``
|
||||||
|
|
||||||
``mp.utils.join_path(p1, p2)``
|
``mp.utils.join_path(p1, p2)``
|
||||||
|
@ -591,6 +591,34 @@ strictly part of the guaranteed API.
|
|||||||
|
|
||||||
On error, ``nil, error`` is returned.
|
On error, ``nil, error`` is returned.
|
||||||
|
|
||||||
|
``utils.file_info(path)``
|
||||||
|
Stats the given path for information and returns a table with the
|
||||||
|
following entries:
|
||||||
|
|
||||||
|
``mode``
|
||||||
|
protection bits (on Windows, always 755 (octal) for directories
|
||||||
|
and 644 (octal) for files)
|
||||||
|
``size``
|
||||||
|
size in bytes
|
||||||
|
``atime``
|
||||||
|
time of last access
|
||||||
|
``mtime``
|
||||||
|
time of last modification
|
||||||
|
``ctime``
|
||||||
|
time of last metadata change (Linux) / time of creation (Windows)
|
||||||
|
``is_file``
|
||||||
|
Whether ``path`` is a regular file (boolean)
|
||||||
|
``is_dir``
|
||||||
|
Whether ``path`` is a directory (boolean)
|
||||||
|
|
||||||
|
``mode`` and ``size`` are integers.
|
||||||
|
Timestamps (``atime``, ``mtime`` and ``ctime``) are integer seconds since
|
||||||
|
the Unix epoch (Unix time).
|
||||||
|
The booleans ``is_file`` and ``is_dir`` are provided as a convenience;
|
||||||
|
they can be and are derived from ``mode``.
|
||||||
|
|
||||||
|
On error (eg. path does not exist), ``nil, error`` is returned.
|
||||||
|
|
||||||
``utils.split_path(path)``
|
``utils.split_path(path)``
|
||||||
Split a path into directory component and filename component, and return
|
Split a path into directory component and filename component, and return
|
||||||
them. The first return value is always the directory. The second return
|
them. The first return value is always the directory. The second return
|
||||||
|
@ -836,6 +836,41 @@ static void script_readdir(js_State *J, void *af)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void script_file_info(js_State *J)
|
||||||
|
{
|
||||||
|
const char *path = js_tostring(J, 1);
|
||||||
|
|
||||||
|
struct stat statbuf;
|
||||||
|
if (stat(path, &statbuf) != 0) {
|
||||||
|
push_failure(J, "Cannot stat path");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Clear last error
|
||||||
|
set_last_error(jctx(J), 0, NULL);
|
||||||
|
|
||||||
|
const char * stat_names[] = {
|
||||||
|
"mode", "size",
|
||||||
|
"atime", "mtime", "ctime", NULL
|
||||||
|
};
|
||||||
|
const double stat_values[] = {
|
||||||
|
statbuf.st_mode,
|
||||||
|
statbuf.st_size,
|
||||||
|
statbuf.st_atime,
|
||||||
|
statbuf.st_mtime,
|
||||||
|
statbuf.st_ctime
|
||||||
|
};
|
||||||
|
// Create an object and add all fields
|
||||||
|
push_nums_obj(J, stat_names, stat_values);
|
||||||
|
|
||||||
|
// Convenience booleans
|
||||||
|
js_pushboolean(J, S_ISREG(statbuf.st_mode));
|
||||||
|
js_setproperty(J, -2, "is_file");
|
||||||
|
|
||||||
|
js_pushboolean(J, S_ISDIR(statbuf.st_mode));
|
||||||
|
js_setproperty(J, -2, "is_dir");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void script_split_path(js_State *J)
|
static void script_split_path(js_State *J)
|
||||||
{
|
{
|
||||||
const char *p = js_tostring(J, 1);
|
const char *p = js_tostring(J, 1);
|
||||||
@ -1255,6 +1290,7 @@ static const struct fn_entry main_fns[] = {
|
|||||||
|
|
||||||
static const struct fn_entry utils_fns[] = {
|
static const struct fn_entry utils_fns[] = {
|
||||||
AF_ENTRY(readdir, 2),
|
AF_ENTRY(readdir, 2),
|
||||||
|
FN_ENTRY(file_info, 1),
|
||||||
FN_ENTRY(split_path, 1),
|
FN_ENTRY(split_path, 1),
|
||||||
AF_ENTRY(join_path, 2),
|
AF_ENTRY(join_path, 2),
|
||||||
AF_ENTRY(get_user_path, 1),
|
AF_ENTRY(get_user_path, 1),
|
||||||
|
43
player/lua.c
43
player/lua.c
@ -1085,6 +1085,48 @@ static int script_readdir(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int script_file_info(lua_State *L)
|
||||||
|
{
|
||||||
|
const char *path = luaL_checkstring(L, 1);
|
||||||
|
|
||||||
|
struct stat statbuf;
|
||||||
|
if (stat(path, &statbuf) != 0) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_pushstring(L, "error");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_newtable(L); // Result stat table
|
||||||
|
|
||||||
|
const char * stat_names[] = {
|
||||||
|
"mode", "size",
|
||||||
|
"atime", "mtime", "ctime", NULL
|
||||||
|
};
|
||||||
|
const unsigned int stat_values[] = {
|
||||||
|
statbuf.st_mode,
|
||||||
|
statbuf.st_size,
|
||||||
|
statbuf.st_atime,
|
||||||
|
statbuf.st_mtime,
|
||||||
|
statbuf.st_ctime
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add all fields
|
||||||
|
for (int i = 0; stat_names[i]; i++) {
|
||||||
|
lua_pushinteger(L, stat_values[i]);
|
||||||
|
lua_setfield(L, -2, stat_names[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience booleans
|
||||||
|
lua_pushboolean(L, S_ISREG(statbuf.st_mode));
|
||||||
|
lua_setfield(L, -2, "is_file");
|
||||||
|
|
||||||
|
lua_pushboolean(L, S_ISDIR(statbuf.st_mode));
|
||||||
|
lua_setfield(L, -2, "is_dir");
|
||||||
|
|
||||||
|
// Return table
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int script_split_path(lua_State *L)
|
static int script_split_path(lua_State *L)
|
||||||
{
|
{
|
||||||
const char *p = luaL_checkstring(L, 1);
|
const char *p = luaL_checkstring(L, 1);
|
||||||
@ -1291,6 +1333,7 @@ static const struct fn_entry main_fns[] = {
|
|||||||
|
|
||||||
static const struct fn_entry utils_fns[] = {
|
static const struct fn_entry utils_fns[] = {
|
||||||
FN_ENTRY(readdir),
|
FN_ENTRY(readdir),
|
||||||
|
FN_ENTRY(file_info),
|
||||||
FN_ENTRY(split_path),
|
FN_ENTRY(split_path),
|
||||||
FN_ENTRY(join_path),
|
FN_ENTRY(join_path),
|
||||||
FN_ENTRY(subprocess),
|
FN_ENTRY(subprocess),
|
||||||
|
Loading…
Reference in New Issue
Block a user