Files
community-plugins/pass/service.luau
T

103 lines
2.6 KiB
Luau

--!nonstrict
local entries = {}
local scanInFlight = false
local function publish()
noctalia.state.set("entries", entries)
end
local function shellEscape(value)
return "'" .. value:gsub("'", "'\\''") .. "'"
end
local function passwordStoreDir()
local dir = noctalia.getenv("PASSWORD_STORE_DIR")
if dir and dir ~= "" then
return noctalia.expandPath(dir)
end
return noctalia.expandPath("~/.password-store")
end
local function rebuild()
if scanInFlight then
return
end
local root = passwordStoreDir()
if not noctalia.fileExists(root) then
noctalia.notifyError("Pass", noctalia.tr("notification.store_not_found"))
return
end
-- Directory traversal can exceed Noctalia's callback CPU budget on large stores.
-- Run it in a subprocess and only build the small launcher cache in Luau.
local command = "cd " .. shellEscape(root)
.. " && find . -mindepth 1"
.. " \\( -type d -name '.*' -prune \\)"
.. " -o \\( -name '*.gpg' ! -name '.*' -print0 \\)"
scanInFlight = true
local accepted = noctalia.runAsync(command, function(result)
scanInFlight = false
if result.exitCode ~= 0 then
noctalia.log("Failed to scan " .. root .. ": " .. (result.stderr or "unknown error"))
return
end
if result.stdoutTruncated then
noctalia.log("Failed to scan " .. root .. ": command output was truncated")
return
end
local nextEntries = {}
for file in (result.stdout or ""):gmatch("([^%z]+)%z") do
-- find returns paths as ./folder/entry.gpg.
local path = file:sub(3, -5)
local title = path
local subtitle = ""
local lastSlash = path:match("^.*()/")
if lastSlash then
subtitle = path:sub(1, lastSlash - 1)
title = path:sub(lastSlash + 1)
end
table.insert(nextEntries, {
id = path,
path = path,
title = title,
subtitle = subtitle,
})
end
table.sort(nextEntries, function(a, b)
return a.title:lower() < b.title:lower()
end)
entries = nextEntries
publish()
end, 60000)
if not accepted then
scanInFlight = false
noctalia.log("Failed to start password-store scan")
end
end
function update()
rebuild()
end
local refresh = noctalia.getConfig("refresh_interval") or 30
noctalia.setUpdateInterval(refresh * 1000)
rebuild()