submission.lua 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. local io = io
  2. local csv = require "csv"
  3. local uuid = require "uuid"
  4. -- Random number generator for uuid()
  5. local posix_uuid = pcall(function()
  6. uuid.set_rng(uuid.rng.urandom())
  7. end)
  8. if not posix_uuid then rng = uuid.set_rng(uuid.rng.win_ffi()) end
  9. local M = {} -- Submission module
  10. -- Adapted from lua-núcleo
  11. local function escape_pattern(s)
  12. local matches = {
  13. ["^"] = "%^";
  14. ["$"] = "%$";
  15. ["("] = "%(";
  16. [")"] = "%)";
  17. ["%"] = "%%";
  18. ["."] = "%.";
  19. ["["] = "%[";
  20. ["]"] = "%]";
  21. ["*"] = "%*";
  22. ["+"] = "%+";
  23. ["-"] = "%-";
  24. ["?"] = "%?";
  25. ["\0"] = "%z";
  26. }
  27. return (s:gsub(".", matches))
  28. end
  29. M.generate_sip = function(path)
  30. local sub_data = assert(csv.open(path))
  31. local md = {}
  32. local prev_ref, prev_k
  33. -- Collate metadata.
  34. local i = 1
  35. for row in sub_data:lines() do
  36. ref, k, v = table.unpack(row)
  37. -- nil-out empty cells (they come through as "")
  38. if ref == "" then ref = nil end
  39. if k == "" then k = nil end
  40. if v == "" then v = nil end
  41. print("Parsing row:", ref, k, v)
  42. -- v can be a legit false value.
  43. if ref and not k and v == nil then
  44. -- This can be a placeholder for ordering purposes.
  45. md[ref] = md_ref or {}
  46. goto continue
  47. elseif v == nil then
  48. goto continue
  49. else
  50. -- If ref or k are missing, reuse the previous one.
  51. if ref then prev_ref = ref
  52. else
  53. if not prev_ref then
  54. -- If column 1 is empty, it must have been set in a
  55. -- previous row.
  56. error(string.format(
  57. "Reference in column 1, row %d not found!", i), 2)
  58. end
  59. ref = prev_ref
  60. end
  61. if k then prev_k = k
  62. else
  63. if not prev_k then
  64. -- If column 2 is empty, it must have been set in a
  65. -- previous row.
  66. error(string.format(
  67. "Property key in column 2, row %d not found!", i), 2)
  68. end
  69. k = prev_k
  70. end
  71. end
  72. md[ref] = md[ref] or {id = uuid(), path = ref, _sort = i}
  73. md[ref][k] = md[ref][k] or {}
  74. if k == "type" then
  75. md[ref][k] = v
  76. else
  77. table.insert(md[ref][k], v)
  78. end
  79. ::continue::
  80. i = i + 1
  81. end
  82. -- Move md to an ordered list.
  83. mdlist = {root_path = path:match("(.*/)")}
  84. for _, v in pairs(md) do table.insert(mdlist, v) end
  85. table.sort(mdlist, function (a, b) return (a._sort < b._sort) end)
  86. -- Infer structure from paths and row ordering.
  87. for i, v in ipairs(mdlist) do
  88. for j = i + 1, #mdlist do
  89. --print(string.format("comparing %s : %s", v.path, mdlist[j].path))
  90. if not v["next"] and
  91. mdlist[j].path:match("(.*/)") == v.path:match("(.*/)") then
  92. --print("next match.")
  93. v["next"] = mdlist[j].path
  94. end
  95. if not v.firstChild and
  96. mdlist[j].path:match("^" .. escape_pattern(v.path)) then
  97. --print("First child match.")
  98. v.firstChild = mdlist[j].path
  99. end
  100. end
  101. v._sort = nil
  102. end
  103. return mdlist
  104. end
  105. M.deposit = function(sip)
  106. for i, rsrc in ipairs(sip) do
  107. print(("Processing resource #%d of %d"):format(i, #sip))
  108. abs_path = sip.root_path
  109. end
  110. end
  111. return M