Vorlagenprogrammierung | Diskussionen | Lua | Unterseiten | |||
Modul | Deutsch | English
|
Modul: | Dokumentation |
Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus
--[=[ SimpleDataAccess 2022-07-03
Data Management Module for simplified Access from Within Other Modules:
All functions return first values only.
Author: Vollbracht
* qualifyingValue(statement, propQual) wikiData first qualifier value
* statementQualOrMainSnack(qualifier, property, propQual) first value
* MainSnakValue(qualifier, property) wikiData first main snack value
* indirectMSValue(qualifier, properties) wikiData first main snack value
* qualifiersLineup(qualifier, property) sequence of wikiData qualifiers
*
]=]
--Module globals
local _, GeneralTime = pcall(require, "Modul:Wikidata/Time")
local Time = GeneralTime.service
local service = {}
--------------------------- local functions -----------------------------
--[[
unwrap(<source>)
object value of a given source: this function simplifies by ignoring a lot
like language e.g.
this function drops all object values if table and not
* time
* text
* id
enhance this function at will:
process additional table object values as follows:
return <return object>, 'f'
have <return object>:format(fmtString)
or
return <return object>, <new type>
enhance getSimple(...) and getList(...) then as well
parameters:
source mainsnak, mainsnak.datavalue, mainsnak.datavalue.value or
qualifier item
returns: (value text, value time, value id, simple type value or nil) and
type of value:
f if formatable
id if Q123... - string
result of format(value) in all other cases
]]
local unwrap = function(source)
if not source then return nil end
if type(source) == 'table' then
if source.datavalue then source = source.datavalue end
if source.value then source = source.value end
if source.text then return source.text, 'string' end
if source.time then return Time:new(source.time), 'f' end
if source.id then return source.id, 'id' end
return nil
end
return source, type(source)
end
--[[
getSimple
text value of a given value
parameters:
value as of mainsnak.datavalue.value
returns: simple data value:
value (if no table), value.text, or label of value.id
]]
local function getSimple(value)
local t = ''
value, t = unwrap(value)
if not value then return '' end
if t == 'f' then return value:format() end
if t == 'id' then
local label = mw.wikibase.getLabel(value)
if label then return label
else
mw.log('result entity w/o label')
mw.logObject(mw.wikibase.getEntity(value))
return value
end
end
return value
end
--[[
]]
local statements = function(object, property, all)
if type(object) == 'string' then
if not property then return nil end
if all then return mw.wikibase.getAllStatements(object, property) end
return mw.wikibase.getAllStatements(object, property)
end
return object
end
local get1stStatement = function(qualifier, property, test)
if qualifier == nil or qualifier == "" then
mw.log('no qualifier given for statement retrival')
return ""
end
local statementList = statements(qualifier, property)
if test then
if not statementList or #statementList == 0 then
mw.logObject(statementList, qualifier .. '.' .. property)
local all = nil
if type(qualifier) == "table" then
all = qualifier:getAllStatements(property)
mw.logObject(all, 'all of this')
else
all = mw.wikibase.getAllStatements(qualifier, property)
mw.logObject(all, 'all of ' .. qualifier)
end
if not all or #all == 0 then
all = mw.wikibase.getEntity(qualifier)
mw.logObject(all, 'all of entity: ' .. qualifier)
end
else mw.logObject(statementList) end
end
if statementList and type(statementList) == "table" then
local result = statementList[1]
if type(result) == "table" then
return result
end
end
mw.log('no data: (' .. qualifier .. '.' .. property .. '):')
return ""
end
-- obsolete, use Modul:Wikidata/Time or Modul:Time instead -->
service.time = { MATCHING = Time.MATCHING, PRECISIONLEVEL = Time.PRECISIONLEVEL,
DEFAULTFORMAT = Time.DEFAULTFORMAT, lessthan = Time.lessthan,
format = Time.format, timify = Time.timify
}
function service.time:new(source)
mw.log('indirect (avoid!)')
return Time:new(source)
end
-- <--obsolete--
--[[
snacks(object, <P...>, <all>)
snak values table:
either all main snaks of a wikidata object defined by property
or all snaks of a statement qualifying its mainsnak by property
parameters:
object: wikidata source:
qualifier string <Q...> of a wikidata object or
statement table as of mw.wikibase.getBestStatements or
single statement beeing source for qualifying snaks
property: defining source statement qualifier string <P...> for
getBestStatements or
filtering qualifying snaks
ignored if source object is table {[1]=..., [2]= ..., ...}
all: use getAllStatements instead of getBestStatements
ignored if source object is table
]]
service.getSnaks = function(object, property, all)
if not object then return nil end
if type(object) == 'string' then
object = object:match('Q%d+')
if not object then return nil end
if not property then return nil end
if all then object = mw.wikibase.getAllStatements(object, property)
else object = mw.wikibase.getBestStatements(object, property) end
elseif type(object) == 'table' then
if object.qualifiers and object.qualifiers[property] then
object = object.qualifiers[property]
elseif object[property] then
object = object[property]
end
if not object[1] then return nil end
else return nil end
local result = {}
if object[1].mainsnak then
for _, v in ipairs(object) do
local r = unwrap(v.mainsnak)
if r then table.insert(result, r) end
end
else
for _, v in ipairs(object) do
local r = unwrap(v)
if r then table.insert(result, r) end
end
end
return result
end
--[[
getList(<object>, <property>, <all>, <value type>, <separator string>)
statement mainsnak values comma or separator string separated
parameters:
object: wikidata source:
qualifier string <Q...> of a wikidata object or
statement table as of mw.wikibase.getBestStatements or
single statement beeing source for qualifying snaks
property: defining source statement qualifier string <P...> for
getBestStatements or
filtering qualifying snaks
ignored if source object is table {[1]=..., [2]= ..., ...}
all: use getAllStatements instead of getBestStatements
ignored if source object is table
vType: additional process information
sep: separator string
returns: string
]]
service.SnakList = function(object, property, all, vType, fmtString, sep)
local source = service.getSnaks(object, property, all)
if not source then return '' end
if not sep then sep = ', ' end
if not vType then return table.concat(source, sep) end
local result = {}
if vType == 'f' then
for _, v in ipairs(source) do
table.insert(result, v:format(fmtString))
end
elseif vType == 'id' then
for _, v in ipairs(source) do
local label = mw.wikibase.getLabel(v)
if label then table.insert(result,label)
else
mw.log('result entity w/o label')
mw.logObject(mw.wikibase.getEntity(value))
table.insert(result, v)
end
end
else result = source end
return table.concat(result, sep)
end
--[[
WD:qualifiedSnaks(Object, property, {{}})
limit a list of statements
parameters:
target either a table containing a list of statements
or an object name (Q1234, e.g.)
claim name of a property to get a statement list if target is name
qualificators struct of elements by which list of statements may be
qualified
currently knowing qualificators.time only:
if given only those statements are returned that share
the same time (not before start = P580 e.g.)
]]
service.qualifiedSnaks = function(this, target, claim, qualificators)
local result = {}
condInclude = function(statement)
if not statement then return nil, false end
if not statement.qualifiers then
return statement.datavalue.value, false
end
end
if not target then return nil end
if type(target) == 'string' then
target = target:match('Q%d+')
if not target then return nil end
if not claim then return nil end
claim = claim:match('P%d+')
if not pName then return nil end
target = mw.wikibase.getBestStatements(target, claim)
end
if type(target) ~= 'table' then return nil end
if qualificators then
if qualificators.time then
target = Time.filtered(target, qualificators.time)
end
else return target end
end
--[[
qualifyingValue(statement, propQual)
simplified view on data
Parameters:
statement: statement given for an entity
propQual: qualifier for a statement value, defaults to MainSnack
returns: a string value of MainSnack or property qualifier if available
]]
service.qualifyingValue = function(statement, propQual)
if statement == nil or statement == "" then
mw.log('no qualifier in pQV')
return ""
end
local result = ""
if propQual and propQual ~= "" then
local q = statement["qualifiers"]
if q and type(q[propQual]) == "table" then
-- no fall back to main snak if property value empty!
return getSimple(q[propQual][1]["datavalue"]["value"])
end
-- no fall back to main snak if property inavailable!
return ''
end
return getSimple(statement["mainsnak"]["datavalue"]["value"])
end
--[[
statementQualOrMainSnack
simple value of a statement with priority on qualifying value and fall back
to main snak value
parameters:
qualifier: string of Q[0-9]+ type for an entity with statements
property: string of P[0-9]+ type for usage of first statement
propQual: string of P[0-9]+ type for qualifying this statement
returns: simple value (no table)
]]
service.statementQualOrMainSnack = function(qualifier, property, propQual, test)
local statement = get1stStatement(qualifier, property, test)
if statement == "" then return "" end
local result = ''
local q = statement["qualifiers"]
if q and type(q[propQual]) == "table" then
result = getSimple(q[propQual][1]["datavalue"]["value"])
end
if result == '' then
return getSimple(statement["mainsnak"]["datavalue"]["value"])
end
return result
end
--[[
MainSnakValue(qualifier, property)
simplified view on data
Parameters:
qualifier: case 1: wikiData qualifier of an element with a property
case 2: wikiData element with a property
property: Property of the element having result as value
returns: a wikiData qualifier or a string value of MainSnack if available
limited: no regard of anything but first statement
limited: only label if id
limited: no regard of text language if text
]]
service.MainSnakValue = function(qualifier, property, test)
local result = get1stStatement(qualifier, property, test)
if result == "" then return "" end
local ms = result["mainsnak"]
if ms and ms["datavalue"] then
return getSimple(ms["datavalue"]["value"])
end
-- fallback: qualifier P1932 "object named as"
local q = result["qualifiers"]
if not q or type(q['P1932']) ~= 'table' then return '' end
return q['P1932'][1]["datavalue"]["value"]
end
service.MainSnackValue = service.MainSnakValue
--[[
indirectMSValue(qualifier, properties)
Parameters:
qualifier: case 1: wikiData qualifier of an element with a property
case 2: wikiData element with a property
properties: sequence of properties in a string, optionally separated
returns:
first MainSnackValue of last property of element given in seccond last
property ... of element given in first property of given element
]]
service.indirectMSValue = function(qualifier, properties)
if qualifier == nil or qualifier == "" then
mw.log('no qualifier')
return ""
end
local statementList = {}
local t = type(qualifier)
local qual = qualifier
local result = ""
mw.log(properties)
local props = {}
for prop in properties:gmatch('[pP]%d+') do
table.insert(props, prop)
end
if #props == {} then return "" end
if t == "table" then
statementList = qual:getBestStatements(props[1])
else
statementList = mw.wikibase.getBestStatements(qual, props[1])
end
local i = 1
-- process all but last properties
while i < #props do
if statementList == nil or statementList[1] == nil then
-- revoke result
mw.log('no ' .. props[i] .. ' in ' .. qual)
return ""
end
result = statementList[1]["mainsnak"]["datavalue"]["value"]
t = type(result)
if t ~= 'table' then
-- revoke result
mw.log(result .. ' is ' .. props[1] .. ' in ' .. qual .. ' but ' .. t)
return ""
end
result = result["id"]
if result == nil or result:find('[qQ]%d+') == nil then
mw.log(result .. ' is ' .. props[1] .. ' in ' .. qual .. ' but no id.')
return ""
end
qual = result
mw.log('next for ' .. mw.wikibase.getLabel(qual))
i = i + 1
statementList = mw.wikibase.getBestStatements(qual, props[i])
end
-- process last property
if statementList == nil or statementList[1] == nil then
-- revoke result
mw.log('no ' .. props[i] .. ' in ' .. qual)
return ""
end
result = statementList[1]["mainsnak"]["datavalue"]["value"]
if type(result) == 'table' then
if result["id"] then return mw.wikibase.getLabel(result["id"]) end
return ""
end
return result
end
--[[
qualifiersLineup(qualifier, property)
sequence of wikiData qualifiers
Parameters:
qualifier: case 1: wikiData qualifier of an element with a property
case 2: wikiData element with a property
property: Property of the element having result qualifiers as values
returns:
best statement's values as long as they are wikiData qualifiers lined up
in a table with respect on series ordinals if available
constraint:
It's in the responsibility of wikiData to provide correct data. In case
of corruption this function might return an empty table or one that
apears empty by starting with index ~= 1.
]]
service.qualifiersLineup = function(qualifier, property)
if qualifier == nil or qualifier == "" then
return {}
end
local statementList = {}
local t = type(qualifier)
if t == "table" then
statementList = qualifier:getBestStatements(property)
else
statementList = mw.wikibase.getBestStatements(qualifier, property)
end
if statementList == nil then
return {}
end
local result = {}
for i, elm in ipairs(statementList) do
local eVal = elm["mainsnak"]["datavalue"]["value"]
if eVal == nil then return result end
t = type(eVal)
if t ~= "table" then return result end
local eQual = eVal["id"]
if eQual == nil then return result end
local iQual = elm["qualifiers"]
if iQual == nil then
mw.log('kein qualifier in ' .. eQual)
table.insert(result, eQual)
else
iQual = iQual["P1545"]
if iQual == nil then
mw.log('keine Ornungsnummer in ' .. eQual)
table.insert(result, eQual)
else
local eNum = iQual[1]["datavalue"]["value"]
table.insert(result, eNum, eQual)
end
end
end
return result
end
service.test = function(frame)
return service.MainSnackValue('Q115122668', 'P577', 2)
end
return service