|
@@ -17,7 +17,23 @@ local transformers = require "pocket_archive.transformers"
|
|
-- "nil" table - for missing key fallback in chaining.
|
|
-- "nil" table - for missing key fallback in chaining.
|
|
local NT = {}
|
|
local NT = {}
|
|
|
|
|
|
--- Compile all templates once.
|
|
|
|
|
|
+-- Default store graph to search all triples.
|
|
|
|
+local gr = graph.new(pkar.store, term.DEFAULT_CTX)
|
|
|
|
+
|
|
|
|
+-- Some commonly used terms.
|
|
|
|
+local dc_title_p = term.new_iriref_ns("dc:title")
|
|
|
|
+local tn_p = term.new_iriref_ns("pas:thumbnail")
|
|
|
|
+local first_p = term.new_iriref_ns("pas:first")
|
|
|
|
+local next_p = term.new_iriref_ns("pas:next")
|
|
|
|
+local path_p = term.new_iriref_ns("pas:path")
|
|
|
|
+local content_type_p = term.new_iriref_ns("pas:contentType")
|
|
|
|
+local file_t = term.new_iriref_ns("pas:File")
|
|
|
|
+
|
|
|
|
+-- Namespaces.
|
|
|
|
+local par_ns = nsm.get_ns("par")
|
|
|
|
+--local pas_ns = namespace.get_ns("pas")
|
|
|
|
+
|
|
|
|
+-- HTML templates. Compile them only once.
|
|
-- TODO Add override for user-maintained templates.
|
|
-- TODO Add override for user-maintained templates.
|
|
local fh, idx_tpl, dres_tpl, ores_tpl
|
|
local fh, idx_tpl, dres_tpl, ores_tpl
|
|
fh = datafile.open("templates/index.html")
|
|
fh = datafile.open("templates/index.html")
|
|
@@ -39,9 +55,9 @@ fh:close()
|
|
|
|
|
|
-- HTML generator module.
|
|
-- HTML generator module.
|
|
local M = {
|
|
local M = {
|
|
- res_dir = pkar.config.htmlgen.out_dir .. "/res",
|
|
|
|
- asset_dir = pkar.config.htmlgen.out_dir .. "/assets",
|
|
|
|
- media_dir = pkar.config.htmlgen.out_dir .. "/media",
|
|
|
|
|
|
+ res_dir = plpath.join(pkar.config.htmlgen.out_dir, "res"),
|
|
|
|
+ asset_dir = plpath.join(pkar.config.htmlgen.out_dir, "assets"),
|
|
|
|
+ media_dir = plpath.join(pkar.config.htmlgen.out_dir, "media"),
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -60,9 +76,22 @@ local function get_breadcrumbs(mconf)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
-local function generate_dres(s, mconf)
|
|
|
|
- local gr = graph.new(pkar.store, term.DEFAULT_CTX)
|
|
|
|
|
|
+local function get_tn_url(s)
|
|
|
|
+ if gr:attr(s, pkar.RDF_TYPE)[file_t] then
|
|
|
|
+ -- The subject is a file.
|
|
|
|
+ tn_fname = (s.data:gsub(par_ns, "") .. ".jpg") -- FIXME do not hardcode.
|
|
|
|
+ return plpath.join(
|
|
|
|
+ M.media_dir, tn_fname:sub(1, 2), tn_fname:sub(3, 4), tn_fname)
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ -- Recurse through all first children until one with a thumbnail, or a
|
|
|
|
+ -- leaf without children, is found.
|
|
|
|
+ first_child = next(gr:attr(s, first_p))
|
|
|
|
+ if first_child then return get_tn_url(first_child) end
|
|
|
|
+end
|
|
|
|
+
|
|
|
|
|
|
|
|
+local function generate_dres(s, mconf)
|
|
local dmd = {}
|
|
local dmd = {}
|
|
local rel = {}
|
|
local rel = {}
|
|
local children = {}
|
|
local children = {}
|
|
@@ -80,25 +109,22 @@ local function generate_dres(s, mconf)
|
|
for o in pairs(ots) do table.insert(dmd[fname], o.data) end
|
|
for o in pairs(ots) do table.insert(dmd[fname], o.data) end
|
|
elseif fname == "pas:first" then
|
|
elseif fname == "pas:first" then
|
|
-- Build a linked list for every first found.
|
|
-- Build a linked list for every first found.
|
|
- local dc_title = term.new_iriref_ns("dc:title")
|
|
|
|
- local tn_p = term.new_iriref_ns("pas:thumbnail")
|
|
|
|
for o in pairs(ots) do
|
|
for o in pairs(ots) do
|
|
-- Loop through all first children.
|
|
-- Loop through all first children.
|
|
- local node_uri = o
|
|
|
|
- logger:debug("local node_uri: ", node_uri.data)
|
|
|
|
|
|
+ local child_s = o
|
|
|
|
+ logger:debug("local child_s: ", child_s.data)
|
|
local ll = {}
|
|
local ll = {}
|
|
- --require "debugger"()
|
|
|
|
- while node_uri do
|
|
|
|
|
|
+ require "debugger"()
|
|
|
|
+ while child_s do
|
|
-- Loop trough all next nodes for each first child.
|
|
-- Loop trough all next nodes for each first child.
|
|
table.insert(ll, {
|
|
table.insert(ll, {
|
|
- href = node_uri.data:gsub(
|
|
|
|
|
|
+ href = child_s.data:gsub(
|
|
nsm.get_ns("par"), "/res/") .. ".html",
|
|
nsm.get_ns("par"), "/res/") .. ".html",
|
|
- label = (next(gr:attr(node_uri, dc_title)) or NT).data,
|
|
|
|
- tn = next(gr:attr(node_uri, tn_p)),
|
|
|
|
|
|
+ label = (next(gr:attr(child_s, dc_title_p)) or NT).data,
|
|
|
|
+ tn = get_tn_url(child_s),
|
|
})
|
|
})
|
|
- local next_attr = gr:attr(
|
|
|
|
- node_uri, term.new_iriref_ns("pas:next"))
|
|
|
|
- node_uri = next(next_attr) -- There can only be one "next"
|
|
|
|
|
|
+ -- There can only be one "next"
|
|
|
|
+ child_s = next(gr:attr(child_s, next_p))
|
|
end
|
|
end
|
|
table.insert(children, ll)
|
|
table.insert(children, ll)
|
|
end
|
|
end
|
|
@@ -111,7 +137,7 @@ local function generate_dres(s, mconf)
|
|
-- TODO differentiate term types
|
|
-- TODO differentiate term types
|
|
for o in pairs(ots) do table.insert(attr, o.data) end
|
|
for o in pairs(ots) do table.insert(attr, o.data) end
|
|
table.sort(attr)
|
|
table.sort(attr)
|
|
- if p == term.new_iriref_ns("dc:title") then title = attr[1] end
|
|
|
|
|
|
+ if p == dc_title_p then title = attr[1] end
|
|
table.insert(dmd, attr)
|
|
table.insert(dmd, attr)
|
|
end
|
|
end
|
|
::skip::
|
|
::skip::
|
|
@@ -136,7 +162,6 @@ local function generate_dres(s, mconf)
|
|
children = children,
|
|
children = children,
|
|
ls_next = ls_next,
|
|
ls_next = ls_next,
|
|
breadcrumbs = get_breadcrumbs(mconf),
|
|
breadcrumbs = get_breadcrumbs(mconf),
|
|
- deliverable = deliverable,
|
|
|
|
})
|
|
})
|
|
|
|
|
|
local res_id = s.data:gsub(nsm.get_ns("par"), "")
|
|
local res_id = s.data:gsub(nsm.get_ns("par"), "")
|
|
@@ -150,8 +175,6 @@ end
|
|
|
|
|
|
|
|
|
|
local function generate_ores(s, mconf)
|
|
local function generate_ores(s, mconf)
|
|
- local gr = graph.new(pkar.store, term.DEFAULT_CTX)
|
|
|
|
-
|
|
|
|
local techmd = {}
|
|
local techmd = {}
|
|
local rel = {}
|
|
local rel = {}
|
|
-- Metadata
|
|
-- Metadata
|
|
@@ -184,21 +207,41 @@ local function generate_ores(s, mconf)
|
|
logger:debug("techmd:", pp.write(techmd))
|
|
logger:debug("techmd:", pp.write(techmd))
|
|
logger:debug("REL:", pp.write(rel))
|
|
logger:debug("REL:", pp.write(rel))
|
|
|
|
|
|
- --require "debugger"()
|
|
|
|
-- Transform and move media assets.
|
|
-- Transform and move media assets.
|
|
|
|
+ local dest_fname, dest_dir, dest -- Reused for thumbnail.
|
|
logger:info("Transforming resource file.")
|
|
logger:info("Transforming resource file.")
|
|
local res_path = techmd["pas:path"]
|
|
local res_path = techmd["pas:path"]
|
|
if not res_path then error("No file path for File resource!") end
|
|
if not res_path then error("No file path for File resource!") end
|
|
local txconf = (mconf.transformers or NT).deliverable or {fn = "copy"}
|
|
local txconf = (mconf.transformers or NT).deliverable or {fn = "copy"}
|
|
- local dest_fname = plpath.basename(res_path[1])
|
|
|
|
- if txconf.ext then
|
|
|
|
- dest_fname = plpath.splitext(dest_fname) .. txconf.ext
|
|
|
|
- end
|
|
|
|
- dest = M.media_dir .. "/" .. dest_fname
|
|
|
|
|
|
+ -- Set file name to resource ID + source extension.
|
|
|
|
+ dest_fname = (
|
|
|
|
+ s.data:gsub(par_ns, "") ..
|
|
|
|
+ (txconf.ext or plpath.extension(res_path[1])))
|
|
|
|
+ dest_dir = plpath.join(
|
|
|
|
+ M.media_dir, dest_fname:sub(1, 2), dest_fname:sub(3, 4))
|
|
|
|
+ dir.makepath(dest_dir)
|
|
|
|
+ dest = plpath.join(dest_dir, dest_fname)
|
|
assert(transformers[txconf.fn](
|
|
assert(transformers[txconf.fn](
|
|
res_path[1], dest, table.unpack(txconf or NT)))
|
|
res_path[1], dest, table.unpack(txconf or NT)))
|
|
- local deliverable = dest:gsub(pkar.config.htmlgen.out_dir, "..")
|
|
|
|
- logger:info("Deliverable: ", dest)
|
|
|
|
|
|
+ local deliverable = dest:gsub(pkar.config.htmlgen.out_dir, "")
|
|
|
|
+ logger:info("Access file: ", deliverable)
|
|
|
|
+
|
|
|
|
+ -- Thumbnail.
|
|
|
|
+ local tn
|
|
|
|
+ txconf = (mconf.transformers or NT).thumbnail
|
|
|
|
+ if txconf then
|
|
|
|
+ if txconf.ext then
|
|
|
|
+ dest_fname = plpath.splitext(dest_fname) .. txconf.ext
|
|
|
|
+ end
|
|
|
|
+ dest_dir = plpath.join(
|
|
|
|
+ M.media_dir, "tn", dest_fname:sub(1, 2), dest_fname:sub(3, 4))
|
|
|
|
+ dir.makepath(dest_dir)
|
|
|
|
+ dest = plpath.join(dest_dir, dest_fname)
|
|
|
|
+ assert(transformers[txconf.fn](
|
|
|
|
+ res_path[1], dest, table.unpack(txconf or NT)))
|
|
|
|
+ tn = dest:gsub(pkar.config.htmlgen.out_dir, "")
|
|
|
|
+ logger:info("Thumbnail: ", tn)
|
|
|
|
+ end
|
|
|
|
|
|
out_html = ores_tpl({
|
|
out_html = ores_tpl({
|
|
site_title = pkar.config.site.title or pkar.default_title,
|
|
site_title = pkar.config.site.title or pkar.default_title,
|
|
@@ -211,6 +254,7 @@ local function generate_ores(s, mconf)
|
|
ls_next = ls_next,
|
|
ls_next = ls_next,
|
|
breadcrumbs = get_breadcrumbs(mconf),
|
|
breadcrumbs = get_breadcrumbs(mconf),
|
|
deliverable = deliverable,
|
|
deliverable = deliverable,
|
|
|
|
+ thumbnail = tn,
|
|
})
|
|
})
|
|
|
|
|
|
local res_id = s.data:gsub(nsm.get_ns("par"), "")
|
|
local res_id = s.data:gsub(nsm.get_ns("par"), "")
|
|
@@ -224,12 +268,7 @@ end
|
|
|
|
|
|
|
|
|
|
M.generate_resource = function(s)
|
|
M.generate_resource = function(s)
|
|
- local gr = graph.new(pkar.store, term.DEFAULT_CTX)
|
|
|
|
-
|
|
|
|
- local res_type
|
|
|
|
- local type_attr = gr:attr(
|
|
|
|
- s, term.new_iriref_ns("pas:contentType"))
|
|
|
|
- res_type = next(type_attr).data
|
|
|
|
|
|
+ local res_type = next(gr:attr(s, content_type_p)).data
|
|
local mconf = model.models[res_type]
|
|
local mconf = model.models[res_type]
|
|
|
|
|
|
if mconf.types["pas:File"] then return generate_ores(s, mconf)
|
|
if mconf.types["pas:File"] then return generate_ores(s, mconf)
|
|
@@ -238,7 +277,6 @@ end
|
|
|
|
|
|
|
|
|
|
M.generate_resources = function()
|
|
M.generate_resources = function()
|
|
- local gr = graph.new(pkar.store, term.DEFAULT_CTX)
|
|
|
|
local subjects = gr:unique_terms(triple.POS_S)
|
|
local subjects = gr:unique_terms(triple.POS_S)
|
|
|
|
|
|
-- TODO parallelize
|
|
-- TODO parallelize
|
|
@@ -250,7 +288,6 @@ end
|
|
|
|
|
|
M.generate_idx = function()
|
|
M.generate_idx = function()
|
|
local obj_idx = {}
|
|
local obj_idx = {}
|
|
- local gr = graph.new(pkar.store, term.DEFAULT_CTX)
|
|
|
|
-- Get all subject of type: Artifact.
|
|
-- Get all subject of type: Artifact.
|
|
s_ts = gr:term_set(
|
|
s_ts = gr:term_set(
|
|
pkar.RDF_TYPE, triple.POS_P,
|
|
pkar.RDF_TYPE, triple.POS_P,
|
|
@@ -258,8 +295,7 @@ M.generate_idx = function()
|
|
)
|
|
)
|
|
for s in pairs(s_ts) do
|
|
for s in pairs(s_ts) do
|
|
local s_label = nsm.denormalize_uri(s.data)
|
|
local s_label = nsm.denormalize_uri(s.data)
|
|
- local titles = gr:attr(s, term.new_iriref_ns("dc:title"))
|
|
|
|
- local obj = {title = next(titles)}
|
|
|
|
|
|
+ local obj = {title = next(gr:attr(s, dc_title_p))}
|
|
if obj.title then obj_idx[s_label] = obj end
|
|
if obj.title then obj_idx[s_label] = obj end
|
|
end
|
|
end
|
|
|
|
|
|
@@ -271,7 +307,7 @@ M.generate_idx = function()
|
|
obj_idx = obj_idx,
|
|
obj_idx = obj_idx,
|
|
})
|
|
})
|
|
|
|
|
|
- local idx_path = pkar.config.htmlgen.out_dir .. "/index.html"
|
|
|
|
|
|
+ local idx_path = plpath.join(pkar.config.htmlgen.out_dir, "index.html")
|
|
local ofh = assert(io.open(idx_path, "w"))
|
|
local ofh = assert(io.open(idx_path, "w"))
|
|
|
|
|
|
logger:debug("Writing info at ", idx_path)
|
|
logger:debug("Writing info at ", idx_path)
|
|
@@ -288,7 +324,7 @@ M.generate_site = function()
|
|
dir.rmtree(M.asset_dir)
|
|
dir.rmtree(M.asset_dir)
|
|
dir.makepath(M.asset_dir)
|
|
dir.makepath(M.asset_dir)
|
|
dir.rmtree(M.media_dir)
|
|
dir.rmtree(M.media_dir)
|
|
- dir.makepath(M.media_dir)
|
|
|
|
|
|
+ dir.makepath(plpath.join(M.media_dir, "tn"))
|
|
|
|
|
|
assert(M.generate_idx())
|
|
assert(M.generate_idx())
|
|
assert(M.generate_resources())
|
|
assert(M.generate_resources())
|