123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- local io = io
- local csv = require "csv"
- local uuid = require "uuid"
- -- Random number generator for uuid()
- local posix_uuid = pcall(function()
- uuid.set_rng(uuid.rng.urandom())
- end)
- if not posix_uuid then rng = uuid.set_rng(uuid.rng.win_ffi()) end
- local M = {} -- Submission module
- -- Adapted from lua-núcleo
- local function escape_pattern(s)
- local matches = {
- ["^"] = "%^";
- ["$"] = "%$";
- ["("] = "%(";
- [")"] = "%)";
- ["%"] = "%%";
- ["."] = "%.";
- ["["] = "%[";
- ["]"] = "%]";
- ["*"] = "%*";
- ["+"] = "%+";
- ["-"] = "%-";
- ["?"] = "%?";
- ["\0"] = "%z";
- }
- return (s:gsub(".", matches))
- end
- M.generate_sip = function(path)
- local sub_data = assert(csv.open(path))
- local md = {}
- local prev_ref, prev_k
- -- Collate metadata.
- local i = 1
- for row in sub_data:lines() do
- ref, k, v = table.unpack(row)
- -- nil-out empty cells (they come through as "")
- if ref == "" then ref = nil end
- if k == "" then k = nil end
- if v == "" then v = nil end
- print("Parsing row:", ref, k, v)
- -- v can be a legit false value.
- if ref and not k and v == nil then
- -- This can be a placeholder for ordering purposes.
- md[ref] = md_ref or {}
- goto continue
- elseif v == nil then
- goto continue
- else
- -- If ref or k are missing, reuse the previous one.
- if ref then prev_ref = ref
- else
- if not prev_ref then
- -- If column 1 is empty, it must have been set in a
- -- previous row.
- error(string.format(
- "Reference in column 1, row %d not found!", i), 2)
- end
- ref = prev_ref
- end
- if k then prev_k = k
- else
- if not prev_k then
- -- If column 2 is empty, it must have been set in a
- -- previous row.
- error(string.format(
- "Property key in column 2, row %d not found!", i), 2)
- end
- k = prev_k
- end
- end
- md[ref] = md[ref] or {id = uuid(), path = ref, _sort = i}
- md[ref][k] = md[ref][k] or {}
- if k == "type" then
- md[ref][k] = v
- else
- table.insert(md[ref][k], v)
- end
- ::continue::
- i = i + 1
- end
- -- Move md to an ordered list.
- mdlist = {root_path = path:match("(.*/)")}
- for _, v in pairs(md) do table.insert(mdlist, v) end
- table.sort(mdlist, function (a, b) return (a._sort < b._sort) end)
- -- Infer structure from paths and row ordering.
- for i, v in ipairs(mdlist) do
- for j = i + 1, #mdlist do
- --print(string.format("comparing %s : %s", v.path, mdlist[j].path))
- if not v["next"] and
- mdlist[j].path:match("(.*/)") == v.path:match("(.*/)") then
- --print("next match.")
- v["next"] = mdlist[j].path
- end
- if not v.firstChild and
- mdlist[j].path:match("^" .. escape_pattern(v.path)) then
- --print("First child match.")
- v.firstChild = mdlist[j].path
- end
- end
- v._sort = nil
- end
- return mdlist
- end
- M.deposit = function(sip)
- for i, rsrc in ipairs(sip) do
- print(("Processing resource #%d of %d"):format(i, #sip))
- abs_path = sip.root_path
- end
- end
- return M
|