local fes = require("fes") local std = fes.std local u = fes.util local site = fes.fes() local title = "Free Software Distributions" site.title = title .. " - Site news" site.copyright = u.copyright("[https://git.vxserver.dev/fSD](https://git.vxserver.dev/fSD)", "fSD") site:banner(fes.app.header.render(std)) local function url_encode(s) if not s then return "" end s = s:gsub("([^%w%-_.~])", function(c) return string.format("%%%02X", string.byte(c)) end) return s end local function list_files_in_dir(dir) local files = {} local ok, lfs = pcall(require, "lfs") if ok and lfs then for name in lfs.dir(dir) do if name ~= "." and name ~= ".." then local attr = lfs.attributes(dir .. "/" .. name) if attr and attr.mode == "file" then table.insert(files, name) end end end table.sort(files) return files end local p = io.popen('ls -1 "' .. dir:gsub('"','\"') .. '" 2>/dev/null') if not p then return files end for line in p:lines() do if line ~= "." and line ~= ".." then local f = dir .. "/" .. line local fh = io.open(f, "r") if fh then fh:close() table.insert(files, line) end end end p:close() table.sort(files) return files end local function read_file(path) local f = io.open(path, "r") if not f then return nil end local data = f:read("*a") f:close() return data end local dir = "news" local files = list_files_in_dir(dir) local params = fes.bus.params or {} local article = params.article if type(article) == "table" then article = article[1] end if article then local candidates = {article, article .. ".txt", article .. ".md", article .. ".html"} local body for _, c in ipairs(candidates) do local p = dir .. "/" .. c body = read_file(p) if body then break end end site.title = article if body then site:custom(fes.markdown_to_html(body)) else site:note(u.cc { std.h1(article), std.p("article not found"), }) end site:note(fes.app.footer.render(std)) return site end local articles = {} local n = 0 for _, v in ipairs(files) do local display = v:gsub("%.[^%.]+$", "") local link = "/news?article=" .. url_encode(display) table.insert(articles, std.a(link, display)) n = n + 1 end if n > 0 then site:h1("Site news") site:note(std.ul(articles)) else site:h1("No articles") end site:note(fes.app.footer.render(std)) return site