gears.filesystem: Improve get_random_file_from_dir.
Previously, only a filename was returned. Getting the path was inconvinient when used within a declarative construct. It was also misbehaving then the directory didn't exist. Finally, the extention list now accept extension names starting with a dot.
This commit is contained in:
parent
eddabebac4
commit
cefd4f843e
|
@ -172,28 +172,39 @@ end
|
||||||
-- @tparam string path The directory to search.
|
-- @tparam string path The directory to search.
|
||||||
-- @tparam[opt] table exts Specific extensions to limit the search to. eg:`{ "jpg", "png" }`
|
-- @tparam[opt] table exts Specific extensions to limit the search to. eg:`{ "jpg", "png" }`
|
||||||
-- If ommited, all files are considered.
|
-- If ommited, all files are considered.
|
||||||
|
-- @tparam[opt=false] boolean absolute_path Return the absolute path instead of the filename.
|
||||||
-- @treturn string|nil A randomly selected filename from the specified path (with
|
-- @treturn string|nil A randomly selected filename from the specified path (with
|
||||||
-- a specified extension if required) or nil if no suitable file is found.
|
-- a specified extension if required) or nil if no suitable file is found. If `absolute_path`
|
||||||
|
-- is set, then a path is returned instead of a file name.
|
||||||
-- @staticfct gears.filesystem.get_random_file_from_dir
|
-- @staticfct gears.filesystem.get_random_file_from_dir
|
||||||
function filesystem.get_random_file_from_dir(path, exts)
|
function filesystem.get_random_file_from_dir(path, exts, absolute_path)
|
||||||
local files, valid_exts = {}, {}
|
local files, valid_exts = {}, {}
|
||||||
|
|
||||||
-- Transforms { "jpg", ... } into { [jpg] = #, ... }
|
-- Transforms { "jpg", ... } into { [jpg] = #, ... }
|
||||||
if exts then for i, j in ipairs(exts) do valid_exts[j:lower()] = i end end
|
if exts then for i, j in ipairs(exts) do valid_exts[j:lower():gsub("^[.]", "")] = i end end
|
||||||
|
|
||||||
-- Build a table of files from the path with the required extensions
|
-- Build a table of files from the path with the required extensions
|
||||||
local file_list = Gio.File.new_for_path(path):enumerate_children("standard::*", 0)
|
local file_list = Gio.File.new_for_path(path):enumerate_children("standard::*", 0)
|
||||||
|
|
||||||
|
-- This will happen when the directory doesn't exist.
|
||||||
|
if not file_list then return nil end
|
||||||
|
|
||||||
for file in function() return file_list:next_file() end do
|
for file in function() return file_list:next_file() end do
|
||||||
if file:get_file_type() == "REGULAR" then
|
if file:get_file_type() == "REGULAR" then
|
||||||
local file_name = file:get_display_name()
|
local file_name = file:get_display_name()
|
||||||
|
|
||||||
if not exts or valid_exts[file_name:lower():match(".+%.(.*)$") or ""] then
|
if not exts or valid_exts[file_name:lower():match(".+%.(.*)$") or ""] then
|
||||||
table.insert(files, file_name)
|
table.insert(files, file_name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if #files == 0 then return nil end
|
||||||
|
|
||||||
-- Return a randomly selected filename from the file table
|
-- Return a randomly selected filename from the file table
|
||||||
return #files > 0 and files[math.random(#files)] or nil
|
local file = files[math.random(#files)]
|
||||||
|
|
||||||
|
return absolute_path and (path:gsub("[/]*$", "") .. "/" .. file) or file
|
||||||
end
|
end
|
||||||
|
|
||||||
return filesystem
|
return filesystem
|
||||||
|
|
|
@ -115,22 +115,40 @@ describe("gears.filesystem", function()
|
||||||
assert.is_true(test_b == "a.png"
|
assert.is_true(test_b == "a.png"
|
||||||
or test_b == "b.jpg")
|
or test_b == "b.jpg")
|
||||||
|
|
||||||
|
-- Any file found (selected extensions)
|
||||||
|
local test_c = gfs.get_random_file_from_dir(root .. "filesystem_tests", {".png", ".jpg"})
|
||||||
|
assert.is_true(test_c == "a.png"
|
||||||
|
or test_c == "b.jpg")
|
||||||
|
|
||||||
|
-- Test absolute paths.
|
||||||
|
local test_d = gfs.get_random_file_from_dir(root .. "filesystem_tests", {".png", ".jpg"}, true)
|
||||||
|
assert.is_true(test_d == root .. "filesystem_tests/a.png"
|
||||||
|
or test_d == root .. "filesystem_tests/b.jpg")
|
||||||
|
|
||||||
|
-- Make sure the paths are generated correctly.
|
||||||
|
assert.is_nil(test_d:match("//"))
|
||||||
|
|
||||||
-- "." in filename test cases with extensions
|
-- "." in filename test cases with extensions
|
||||||
local test_c = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {"ext"})
|
local test_e = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {"ext"})
|
||||||
assert.is_true(test_c == "filename.ext"
|
assert.is_true(test_e == "filename.ext"
|
||||||
or test_c == ".filename.ext"
|
or test_e == ".filename.ext"
|
||||||
or test_c == "file.name.ext"
|
or test_e == "file.name.ext"
|
||||||
or test_c == ".file.name.ext")
|
or test_e == ".file.name.ext")
|
||||||
|
|
||||||
-- "." in filename test cases with no extensions
|
-- "." in filename test cases with no extensions
|
||||||
local test_d = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {""})
|
local test_f = gfs.get_random_file_from_dir(root .. "filesystem_tests/y", {""})
|
||||||
assert.is_true(test_d == "filename"
|
assert.is_true(test_f == "filename"
|
||||||
or test_d == "filename."
|
or test_f == "filename."
|
||||||
or test_d == "filename.ext."
|
or test_f == "filename.ext."
|
||||||
or test_d == ".filename"
|
or test_f == ".filename"
|
||||||
or test_d == ".filename."
|
or test_f == ".filename."
|
||||||
or test_d == "file.name.ext."
|
or test_f == "file.name.ext."
|
||||||
or test_d == ".file.name.ext.")
|
or test_f == ".file.name.ext.")
|
||||||
|
|
||||||
|
-- Test invalid directories.
|
||||||
|
local test_g = gfs.get_random_file_from_dir(root .. "filesystem_tests/fake_dir")
|
||||||
|
assert.is_nil(test_g)
|
||||||
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
Loading…
Reference in New Issue