472
edits
(Update package: OSW Core) |
(Update package: OSW Core) |
||
Line 156: | Line 156: | ||
elseif type(v) == 'table' then | elseif type(v) == 'table' then | ||
if (v[1] == nil) then --key value array = object/dict | if (v[1] == nil) then --key value array = object/dict | ||
local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=v, template=eval_template, mode=mode, stringify_arrays=stringify_arrays}) | local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=v, jsonschema=p.defaultArgPath(jsonschema, {"properties", k}, {}), template=eval_template, mode=mode, stringify_arrays=stringify_arrays}) | ||
msg = msg .. sub_res.debug_msg | msg = msg .. sub_res.debug_msg | ||
jsondata[k] = sub_res.res | jsondata[k] = sub_res.res | ||
Line 173: | Line 173: | ||
end | end | ||
end | end | ||
local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=e, template=eval_template, mode=mode, stringify_arrays=stringify_arrays}) | local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=e, jsonschema=p.defaultArgPath(jsonschema, {"properties", k, "items"}, {}), template=eval_template, mode=mode, stringify_arrays=stringify_arrays}) | ||
msg = msg .. sub_res.debug_msg | msg = msg .. sub_res.debug_msg | ||
if (type(sub_res.res) == 'table') then | if (type(sub_res.res) == 'table') then | ||
Line 251: | Line 251: | ||
local schema_res = p.walkJsonSchema({jsonschema=jsonschema, categories=categories, mode=mode, recursive=recursive, debug=debug}) | local schema_res = p.walkJsonSchema({jsonschema=jsonschema, categories=categories, mode=mode, recursive=recursive, debug=debug}) | ||
jsonschema = schema_res.jsonschema | jsonschema = p.expandJsonRef({json=schema_res.jsonschema, debug=debug}).json | ||
--mw.logObject(jsonschema) | --mw.logObject(jsonschema) | ||
Line 275: | Line 275: | ||
if (type(v) == "string") then | if (type(v) == "string") then | ||
local vpart = p.splitString(v, ':') | local vpart = p.splitString(v, ':') | ||
if (vpart[1] == "File") then jsonld[k] = mw.getCurrentFrame():callParserFunction( 'filepath', { vpart[2] } ) end --google does not follow redirects via "File":"wiki:Special:Redirect/file/" | if (p.tableLength(vpart) == 2 and vpart[1] == "File") then jsonld[k] = mw.getCurrentFrame():callParserFunction( 'filepath', { vpart[2] } ) end --google does not follow redirects via "File":"wiki:Special:Redirect/file/" | ||
end | end | ||
end | end | ||
Line 434: | Line 434: | ||
--[[ test | --[[ test | ||
category = "Category: | category = "Category:Entity" | ||
jsonschema = p.expandJsonRef({json=p.loadJson({title=category, slot="jsonschema"}).json}).json | |||
jsonschema =p. | mw.logObject(p.buildContext({jsonschema=jsonschema, debug=true})) | ||
or | |||
jsonschema = { | |||
["@context"]={test="level 0"}, | |||
properties={ | |||
test={ | |||
type="object", | |||
["@context"]={test1="level 1"}, | |||
properties= { | |||
test= { | |||
type="array", | |||
items= { | |||
type="object", | |||
["@context"]={test2="level 2"} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
mw.logObject(p.buildContext({jsonschema=jsonschema, debug=true})) | mw.logObject(p.buildContext({jsonschema=jsonschema, debug=true})) | ||
--]] | --]] | ||
function p.buildContext(args) | function p.buildContext(args) | ||
local schema = p.defaultArg(args.jsonschema, {}) | local schema = p.defaultArg(args.jsonschema, {}) | ||
--mw.logObject(schema) | |||
local context = p.defaultArg(args.context, schema[p.keys.context]) | local context = p.defaultArg(args.context, schema[p.keys.context]) | ||
local result = {} | local result = p.defaultArg(args.result, {}) | ||
if (context ~= nil) then | if (context ~= nil) then | ||
for k,v in pairs(context) do | for k,v in pairs(context) do | ||
Line 454: | Line 475: | ||
result[k] = v | result[k] = v | ||
end | end | ||
end | |||
end | |||
local properties = p.defaultArg(schema.properties, {}) | |||
for k,v in pairs(properties) do | |||
local subcontext = nil | |||
if (p.defaultArgPath(properties, {k, 'type'}) == 'object') then | |||
--mw.logObject(properties[k]) | |||
subcontext = p.buildContext({jsonschema=properties[k]}).context | |||
elseif (p.defaultArgPath(properties, {k, 'items', 'type'}) == 'object') then | |||
mw.logObject(properties[k]['items']) | |||
subcontext = p.buildContext({jsonschema=properties[k]['items']}).context | |||
end | |||
if (subcontext ~= nil and p.tableLength(subcontext) > 0) then | |||
if (result[k] == nil) then result[k] = {} end | |||
if (type(result[k]) == 'string') then result[k] = {["@id"]=result[k]} end | |||
if (result[k][p.keys.context] == nil) then result[k][p.keys.context] = {} end | |||
result[k][p.keys.context] = p.tableMerge(result[k][p.keys.context], subcontext) | |||
end | end | ||
end | end | ||
Line 493: | Line 532: | ||
local properties = {} --semantic properties | local properties = {} --semantic properties | ||
local property_data = {} | local property_data = {} | ||
local context = p.defaultArg(args.context, p.buildContext({jsonschema=schema}).context) | local context = p.defaultArg(args.context, p.buildContext({jsonschema=schema}).context) | ||
local error = "" | local error = "" | ||
if (debug) then mw.logObject(context) end | if (debug) then mw.logObject(context) end | ||
Line 536: | Line 575: | ||
--if (debug) then mw.logObject("prop " .. k .. " = " .. mw.dumpObject(v)) end | --if (debug) then mw.logObject("prop " .. k .. " = " .. mw.dumpObject(v)) end | ||
if (mapping_found) then | if (mapping_found) then | ||
local subcontext = p.copy(p.defaultArgPath(context, {k, p.keys.context}, {})) --deepcopy, see also https://phabricator.wikimedia.org/T269990 | |||
context = p.tableMerge(context, subcontext) -- pull up nested context | |||
local values = {} | local values = {} | ||
if (v[1] == nil) then --key value array = object/dict | if (v[1] == nil) then --key value array = object/dict | ||
local | local subproperties_res = p.getSemanticProperties({jsonschema=schema, jsondata=v, store=true, root=false, debug=debug, context=context, subschema=schema_properties[k], parent_schema_property=property_data[k]}) | ||
local id = subproperties_res.id --subobject_id | |||
if (id ~= nil) then | if (id ~= nil) then | ||
id = mw.title.getCurrentTitle().fullText .. '#' .. id | id = mw.title.getCurrentTitle().fullText .. '#' .. id | ||
table.insert(values, id) | table.insert(values, id) | ||
end | end | ||
properties = p.processStatement({subject=properties, statement=subproperties_res.properties, debug=debug}).subject | |||
else --list array | else --list array | ||
for i, e in pairs(v) do | for i, e in pairs(v) do | ||
if (type(e) == 'table') then | if (type(e) == 'table') then | ||
local | local subproperties_res = p.getSemanticProperties({jsonschema=schema, jsondata=e, store=true, root=false, debug=debug, context=context, subschema=schema_properties[k], parent_schema_property=property_data[k]}) | ||
local id = subproperties_res.id --subobject_id | |||
if (id ~= nil) then | if (id ~= nil) then | ||
id = mw.title.getCurrentTitle().fullText .. '#' .. id | id = mw.title.getCurrentTitle().fullText .. '#' .. id | ||
table.insert(values, id) | table.insert(values, id) | ||
end | end | ||
properties = p.processStatement({subject=properties, statement=subproperties_res.properties, debug=debug}).subject | |||
else values = v end --plain strings | else values = v end --plain strings | ||
end | end | ||
Line 589: | Line 633: | ||
if (p.tableLength(properties) > 0) then | if (p.tableLength(properties) > 0) then | ||
store_res = mw.smw.subobject( properties, subobjectId ) --store as subobject | store_res = mw.smw.subobject( properties, subobjectId ) --store as subobject | ||
if (debug) then mw.logObject("Store subobject with id " .. subobjectId) end | if (debug) then mw.logObject("Store subobject with id " .. (subobjectId or "<random>")) end | ||
end | end | ||
end | end | ||
Line 599: | Line 643: | ||
if (debug) then mw.logObject(error) end | if (debug) then mw.logObject(error) end | ||
return {properties=properties, definitions=property_data, id=subobjectId, context=context, error=error} | return {properties=properties, definitions=property_data, id=subobjectId, context=context, error=error} | ||
end | |||
function p.processStatement(args) | |||
local statement = p.defaultArg(args.statement) | |||
local subject = p.defaultArg(args.subject) | |||
local debug = p.defaultArg(args.debug, false) | |||
-- handle "approved" statements | |||
if (statement["HasSubject"] == nil or statement["HasSubject"][1] == nil or statement["HasSubject"][1] == "") then --implicit subject | |||
if (statement["HasProperty"] ~= nil and statement["HasProperty"][1] ~= nil and statement["HasProperty"][1] ~= "" and statement["HasObject"] ~= nil) then | |||
local property = p.splitString(statement["HasProperty"][1], ":")[2] | |||
if (debug) then | |||
mw.log("Set property " .. property .. " from statement to ") | |||
mw.logObject(statement["HasObject"]) | |||
end | |||
if (subject[property] == nil) then subject[property] = {} end | |||
for k, v in pairs(statement["HasObject"]) do table.insert(subject[property], v) end | |||
end | |||
end | |||
return {subject=subject} | |||
end | end | ||
Line 647: | Line 711: | ||
-- HELPERS | -- HELPERS | ||
-- expands all $ref | |||
--test: mw.logObject(p.expandJsonRef({json={items={test="value", ["$ref"]="/wiki/JsonSchema:Label?action=raw"}}}).json) | |||
--test: mw.logObject(p.expandJsonRef({json={["$ref"]="/wiki/Category:Item?action=raw&slot=jsonschema"}}).json) | |||
--test: mw.logObject(p.expandJsonRef({json={["$ref"]="/wiki/JsonSchema:Statement?action=raw"}}).json) | |||
function p.expandJsonRef(args) | |||
local json = p.defaultArg(args.json, {}) | |||
local debug = p.defaultArg(args.debug, false) | |||
local refs = {} | |||
for k,v in pairs(json) do | |||
if (k == "$ref") then | |||
-- e. g. "/wiki/JsonSchema:Label?action=raw" or "/wiki/Category:Entity?action=raw&slot=jsonschema" | |||
if string.find(v, "#") then | |||
if (debug) then mw.logObject("Skip relative reference") end | |||
else | |||
local uri = mw.uri.new(v) | |||
local ref_title = mw.text.split(uri.path, "wiki/", true)[2] | |||
local ref_slot = uri.query["slot"] | |||
if (debug) then | |||
if (ref_slot ~= nil) then mw.logObject("Ref found with title " .. ref_title .. " and slot " .. ref_slot) | |||
else mw.logObject("Ref found with title " .. ref_title) end | |||
end | |||
local ref_json = p.loadJson({title=ref_title, slot=ref_slot}).json | |||
refs[v] = ref_json | |||
json[k] = nil | |||
end | |||
end | |||
end | |||
--mw.logObject(refs) | |||
for k,v in pairs(refs) do | |||
json = p.tableMerge(v, json) | |||
end | |||
for k,v in pairs(json) do | |||
if type(v) == "table" then | |||
json[k] = p.expandJsonRef({json=v}).json | |||
end | |||
end | |||
return {json=json} | |||
end | |||
function p.defaultArg(arg, default) | function p.defaultArg(arg, default) | ||
if (arg == nil) then | if (arg == nil) then |
edits