Zum Inhalt springen

Modul:Wikidata/API

aus AufEinWort, der freien Forschung

Die Dokumentation für dieses Modul kann unter Modul:Wikidata/API/Doku erstellt werden

-- Modul:Wikidata/API — Zugriff ausschliesslich ueber UnlinkedWikibase.
-- Erste Kompatibilitaetsstufe: das mitgelieferte Modul:Wikidata.
local p = {}
local cache = {}

local function backend()
    local api = mw.ext and mw.ext.UnlinkedWikibase
    if not api or type(api.getEntity) ~= 'function' then
        error('Wikidata/API: mw.ext.UnlinkedWikibase.getEntity ist nicht verfuegbar.', 2)
    end
    return api
end

local function copy(value)
    if type(value) ~= 'table' then return value end
    local result = {}
    for key, item in pairs(value) do result[key] = copy(item) end
    return result
end

function p.isValidEntityId(id)
    return type(id) == 'string' and (
        id:match('^[QPL][1-9]%d*$') ~= nil or
        id:match('^L[1-9]%d*%-[FS][1-9]%d*$') ~= nil)
end

function p.getEntityIdForCurrentPage()
    local api = backend()
    if type(api.getEntityIdForCurrentPage) ~= 'function' then
        error('Wikidata/API: Diese UnlinkedWikibase-Fassung bietet keine externe '
            .. 'getEntityIdForCurrentPage-Funktion. Bitte vorerst id=Q… angeben.', 2)
    end
    local id = api.getEntityIdForCurrentPage()
    if id == nil or id == '' or id == false then return nil end
    if not p.isValidEntityId(id) then
        error('Wikidata/API: Die externe Seitenzuordnung enthaelt keine gueltige ID.', 2)
    end
    return id
end

function p.getEntity(id)
    if id == nil or id == '' then id = p.getEntityIdForCurrentPage() end
    if id == nil then return nil end
    if not p.isValidEntityId(id) then error('Wikidata/API: Ungueltige ID: ' .. tostring(id), 2) end
    if cache[id] ~= nil then return cache[id] ~= false and copy(cache[id]) or nil end
    -- Fehler nicht als fehlendes Objekt verschlucken. Kein lokaler Fallback.
    local entity = backend().getEntity(id)
    if type(entity) == 'table' and entity.error then
        error('Wikidata/API: Externe Objektdaten fuer ' .. id
            .. ' sind derzeit nicht verfuegbar. Moeglicherweise steht der Hintergrundabruf '
            .. 'noch aus oder ist fehlgeschlagen. UnlinkedWikibaseFetch-Jobs und runJobs '
            .. 'pruefen; nach erfolgreichem Abruf die betroffene Seite erneut parsen '
            .. '(z. B. action=purge). Rueckmeldung: ' .. tostring(entity.error)
            .. '. Dies bestaetigt nicht, dass das Objekt auf Wikidata fehlt.', 2)
    end
    -- Manche Bruecken reichen den PHP-Ergebnisumschlag durch.
    if type(entity) == 'table' and type(entity.result) == 'table' then entity = entity.result end
    if type(entity) == 'table' and entity.missing ~= nil then
        cache[id] = false
        return nil
    end
    if type(entity) ~= 'table' or entity.id ~= id then
        error('Wikidata/API: Keine bestaetigten Objektdaten fuer ' .. id
            .. ' erhalten. Moeglicherweise steht der Hintergrundabruf noch aus, '
            .. 'der Abruf ist fehlgeschlagen oder die Antwort ist unvollstaendig. '
            .. 'UnlinkedWikibaseFetch-Jobs und runJobs pruefen; nach erfolgreichem Abruf '
            .. 'die betroffene Seite erneut parsen (z. B. action=purge). '
            .. 'Dies bestaetigt nicht, dass das Objekt auf Wikidata fehlt.', 2)
    end
    cache[id] = copy(entity)
    return copy(entity)
end

function p.entityExists(id)
    return p.getEntity(id) ~= nil
end

function p.resolvePropertyId(property)
    if type(property) == 'string' and property:match('^P[1-9]%d*$') then return property end
    error('Wikidata/API: Bitte eine ausdrueckliche P-ID verwenden; '
        .. 'Eigenschaftsnamen werden in dieser Fassung nicht aufgeloest.', 2)
end

local function term(id, field, language)
    local entity = p.getEntity(id)
    local entry = entity and entity[field] and entity[field][language]
    return type(entry) == 'table' and entry.value or nil
end

function p.getLabelByLang(id, language) return term(id, 'labels', language) end
function p.getDescriptionByLang(id, language) return term(id, 'descriptions', language) end

function p.getLabel(id)
    return p.getLabelByLang(id, mw.language.getContentLanguage().code)
end
p.label = p.getLabel

function p.getDescription(id)
    return p.getDescriptionByLang(id, mw.language.getContentLanguage().code)
end

function p.getSitelink(id, site)
    local entity = p.getEntity(id)
    if not entity then return nil end
    if site then
        local link = entity.sitelinks and entity.sitelinks[site]
        return link and link.title or nil
    end
    -- AufEinWort-Seitenzuordnung statt dewiki-Titel als lokalen Link ausgeben.
    local api = backend()
    if type(api.getLocalTitle) ~= 'function' then
        error('Wikidata/API: getLocalTitle ist nicht verfuegbar.', 2)
    end
    local title = api.getLocalTitle(entity.id)
    return title and title.prefixedText or nil
end
p.sitelink = p.getSitelink

function p.renderSnak(snak)
    if type(snak) ~= 'table' then error('Wikidata/API: Ungueltiger Snak.', 2) end
    if snak.snaktype == 'novalue' then return 'kein Wert' end
    if snak.snaktype == 'somevalue' then return 'unbekannter Wert' end
    -- Normale Datentypen formatiert Modul:Wikidata selbst. Nicht stillschweigend
    -- den lokalen Wikibase-Formatter fuer externe Entitaeten verwenden.
    error('Wikidata/API: Nicht unterstuetzter Werttyp: '
        .. tostring(snak.datavalue and snak.datavalue.type or snak.snaktype), 2)
end

return p