Modul:NeoWiki/API
Erscheinungsbild
Die Dokumentation für dieses Modul kann unter Modul:NeoWiki/API/Doku erstellt werden
-- Datums-Testfassung: benötigt NeoWikiBaseBridge 0.10.0-test.
local p = {}
local function backend()
return require('mw.neowiki')
end
local function scalar(value)
if type(value) == 'boolean' then return value and 'ja' or 'nein' end
if type(value) == 'number' then return tostring(value) end
if type(value) == 'string' then return value end
error('NeoWiki/API: Nicht unterstützter Werttyp.', 0)
end
-- Own historical dates now follow the agreed Wikipedia calendar convention.
local function ownTime(raw)
local y, m, d = raw:match('^(-?%d%d%d%d)%-(%d%d)%-(%d%d)$')
local precision = 11
if not y then y, m = raw:match('^(-?%d%d%d%d)%-(%d%d)$'); precision = 10 end
if not y then y = raw:match('^(-?%d%d%d%d)$'); precision = 9 end
if not y or tonumber(y) == 0 then error('NeoWiki/API: Ungültige eigene Datierung.', 0) end
local year, month, day = tonumber(y), tonumber(m) or 1, tonumber(d) or 1
local gregorian = year > 1582 or year == 1582 and (month > 10 or month == 10 and day >= 15)
return { kind = 'time', own = true, raw = raw, year = year, month = m and month or nil, day = d and day or nil,
sourceTime = { time = (year < 0 and '-' or '+') .. string.format('%04d', math.abs(year))
.. '-' .. (m or '00') .. '-' .. (d or '00') .. 'T00:00:00Z',
precision = precision, calendarmodel = 'http://www.wikidata.org/entity/' .. (gregorian and 'Q1985727' or 'Q1985786') } }
end
local function ownTimeLabel(value, definition, language)
local en = language:match('^en') ~= nil
local months = en and {'January','February','March','April','May','June','July','August','September','October','November','December'}
or {'Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'}
local link = definition.wikiLink or {}
local suffix = en and (link.dateBceEn or 'BC') or (link.dateBceDe or 'v. Chr.')
local prefix = value.day and (value.day .. (en and ' ' or '. ')) or ''
if value.month then prefix = prefix .. months[value.month] .. ' ' end
return prefix .. math.abs(value.year) .. (value.year < 0 and (' ' .. suffix) or '')
end
function p.collect(options)
options = options or {}
if options.page and options.subject then
error('NeoWiki/API: Seite oder Subjekt angeben, nicht beides.', 0)
end
local nw = backend()
local subject = options.subject and nw.getSubject(options.subject)
or (not options.subject and nw.getMainSubject(options.page))
if not subject then return { fields = {}, missing = true } end
local schema = nw.getSchema(subject.schema)
if not schema then error('NeoWiki/API: Schema ist nicht verfügbar.', 0) end
local selected, needsExternal = {}, false
local found = false
for _, definition in ipairs(schema.properties or {}) do
if (not options.field or options.field == definition.name)
and (options.includeImages or definition.type ~= 'image') then
found = true
selected[#selected + 1] = definition
if definition.externalProperty then needsExternal = true end
end
end
if options.field and not found then
error('NeoWiki/API: Feld nicht im Schema gefunden: ' .. options.field, 0)
end
local external = {}
if needsExternal and options.origin ~= 'own' then
local bridge = require('mw.neowikibase')
if type(bridge.getFields) ~= 'function' then
error('NeoWiki/API: Die Lua-Anbindung für abgerufene P-Werte fehlt noch. '
.. 'Es wurden keine SMW-Werte gesetzt.', 0)
end
-- Strukturierte Werte der installierten Bridge, keine HTML-Ausgabe.
-- PHP prüft Leserechte, Seiten-/Subjektbezug und Quellenzuordnung.
local result = bridge.getFields({ page = options.page,
subject = subject.id, language = options.language })
if type(result) ~= 'table' or result.version ~= 1
or result.scope ~= 'current' or result.mainSubjectId ~= subject.id then
error('NeoWiki/API: Ungültige Antwort der P-Wert-Schnittstelle.', 0)
end
for _, field in ipairs(result.fields or {}) do external[field.name] = field end
end
local fields = {}
for _, definition in ipairs(selected) do
local field = { name = definition.name, type = definition.type,
externalProperty = definition.externalProperty, values = {} }
local seen = {}
local function add(text, origin, metadata)
text = scalar(text)
if text ~= '' then
field.values[#field.values + 1] = {
value = text, origin = origin, metadata = metadata,
duplicate = seen[text] or false }
seen[text] = true
end
end
if options.origin ~= 'external' then
for _, value in ipairs(nw.getAll(definition.name, { subject = subject.id }) or {}) do
if definition.type == 'historicalDate' then
local time = ownTime(value)
add(ownTimeLabel(time, definition, options.language or mw.language.getContentLanguage().code), 'own', time)
else
add(value, 'own')
end
end
end
if definition.externalProperty and options.origin ~= 'own'
and not (definition.type == 'historicalDate' and #field.values > 0) then
local remote = external[definition.name]
if not remote or (remote.status ~= 'resolved' and remote.status ~= 'missing' and not (definition.type == 'historicalDate' and remote.status == 'manual')) then
error('NeoWiki/API: Abgerufene Werte für „' .. definition.name
.. '“ sind nicht zuverlässig verfügbar.', 0)
end
if remote.source ~= definition.externalProperty.source
or remote.propertyId ~= definition.externalProperty.id then
error('NeoWiki/API: Quellenzuordnung stimmt nicht überein.', 0)
end
field.status = remote.status
field.reason = remote.reason
for _, value in ipairs(remote.values or {}) do
-- Bilder bleiben im ersten Durchlauf ausgeschlossen.
-- Unbekannte/fehlende Werte werden nicht als Text annotiert.
if value.kind == 'time' and definition.type == 'historicalDate' then
if type(value.sourceTime) ~= 'table' or type(value.label) ~= 'string' then
error('NeoWiki/API: Ungültiger Zeitwert.', 0)
end
add(value.label, remote.source, value)
elseif value.kind == 'entity' then
if not value.label or value.label == '' or value.label == value.id then
error('NeoWiki/API: Aufgelöste Wertbezeichnung fehlt.', 0)
end
add(value.label, remote.source, value)
elseif value.kind ~= 'somevalue' and value.kind ~= 'novalue' then
error('NeoWiki/API: Nicht unterstützter abgerufener Wert.', 0)
end
end
end
fields[#fields + 1] = field
end
return { subject = subject, schema = schema, fields = fields }
end
return p