Vorlagenprogrammierung Diskussionen Lua Unterseiten
Modul Deutsch English

Modul: Dokumentation

Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus

Dies ist die (produktive) Mutterversion eines global benutzten Lua-Moduls.
Wenn die serial-Information nicht übereinstimmt, müsste eine Kopie hiervon in das lokale Wiki geschrieben werden.
Versionsbezeichnung auf WikiData: 2022-10-19

local BadgesQuery = { suite  = "BadgesQuery",
                      serial = "2022-10-19",
                      item   = 114773646 }
--[==[
Query badges registered at Wikidata
]==]
local Failsafe = BadgesQuery



local function find( access, another )
    -- Find badges of item
    -- Precondition:
    --    access     -- string, with Q-item
    --    another    -- string, with site, or not
    -- Postcondition:
    --     Returns
    --         1 -- string, with page name, if sitelink, or not
    --         2 -- sequence table, non-empty, with badges, or not
    local e = mw.wikibase.getEntity( access )
    local r1, r2
    if e then
        local t = e.sitelinks
        if t then
            local site
            if type( another ) == "string" then
                site = mw.text.trim( another )
                if site == "" then
                    site = false
                end
            end
            site = site  or  mw.wikibase.getGlobalSiteId()
            t    = t[ site ]
            if t then
                r1 = t.title
                r2 = t.badges
                if type( r2 ) == "table"  and
                   #r2 == 0 then
                    r2 = false
                end
            end
        end
    end
    return r1, r2
end    -- find()



BadgesQuery.features = function ( arglist, frame )
    -- Present (linked) page, may be decorated with badges
    -- Precondition:
    --    arglist    -- table, with options
    --    frame      -- object, or not
    -- Postcondition:
    --     Returns string
    local r, self
    if type( arglist ) == "table"  and
       type( arglist.sTransclude ) == "string" then
        local sq
        self = mw.wikibase.getEntityIdForCurrentPage()
        if type( arglist.nsTransclude ) ~= "number" then
            arglist.nsTransclude = 10
        end
        if arglist.subject then
            sq = mw.wikibase.getEntityIdForTitle( arglist.subject )
            if sq  and  sq ~= self then
                self = false
            end
        else
            sq = self
        end
        if sq then
            local s, badges = find( sq, arglist.site )
            if badges then
                local t
                if not arglist.subject then
                    arglist.subject = s
                end
                for i = 1, #badges do
                    s = badges[ i ]:lower()
                    arglist[ s ] = "1"
                end    -- for i
                t = mw.title.makeTitle( arglist.nsTransclude,
                                        arglist.sTransclude )
                if t and t.exists then
                    frame = frame  or  mw.getCurrentFrame()
                    if arglist.link  and  not self then
                        arglist.linked = "1"
                    end
                    r = frame:expandTemplate{ title = t,
                                              args  = arglist }
                end
            end
        end
    end
    if not r then
        if not arglist.subject then
            self            = true
            arglist.subject = mw.title.getCurrentTitle().prefixedText
        end
        if arglist.link  and  not self then
            r = string.format( "[[%s]]", arglist.subject )
        else
            r = arglist.subject
        end
    end
    return r
end    -- BadgesQuery.features()



BadgesQuery.fulfils = function ( ask, array, another )
    -- Test badge requirement
    -- Precondition:
    --    ask        -- string, with local page name, or not
    --    array      -- sequence table, with badge item numbers
    --    another    -- string, with site, or not
    -- Postcondition:
    --     Returns boolean
    local r
    if type( array ) == "table" then
        local sq
        if ask then
            sq = mw.wikibase.getEntityIdForTitle( ask )
        else
            sq = mw.wikibase.getEntityIdForCurrentPage()
        end
        if sq then
            local x, badges = find( sq, another )
            if badges then
                local k, query
                for j = 1, #array do
                    k = array[ j ]
                    if type( k ) == "number"  and
                       k > 0 then
                        query = query  or  { }
                        table.insert( query,  "Q" .. k )
                    end
                end    -- for j
                if query then
                    for i = 1, #badges do
                        for j = 1, #query do
                            if badges[ i ] == query[ j ] then
                                r = true
                                break    -- for j
                            end
                        end    -- for j
                        if r then
                            break    -- for i
                        end
                    end    -- for i
                end
            end
        end
    end
    return r or false
end    -- BadgesQuery.fulfils()



Failsafe.failsafe = function ( atleast )
    -- Retrieve versioning and check for compliance
    -- Precondition:
    --     atleast  -- string, with required version
    --                         or wikidata|item|~|@ or false
    -- Postcondition:
    --     Returns  string  -- with queried version/item, also if problem
    --              false   -- if appropriate
    -- 2020-08-17
    local since  = atleast
    local last   = ( since == "~" )
    local linked = ( since == "@" )
    local link   = ( since == "item" )
    local r
    if last  or  link  or  linked  or  since == "wikidata" then
        local item = Failsafe.item
        since = false
        if type( item ) == "number"  and  item > 0 then
            local suited = string.format( "Q%d", item )
            if link then
                r = suited
            else
                local entity = mw.wikibase.getEntity( suited )
                if type( entity ) == "table" then
                    local seek = Failsafe.serialProperty or "P348"
                    local vsn  = entity:formatPropertyValues( seek )
                    if type( vsn ) == "table"  and
                       type( vsn.value ) == "string"  and
                       vsn.value ~= "" then
                        if last  and  vsn.value == Failsafe.serial then
                            r = false
                        elseif linked then
                            if mw.title.getCurrentTitle().prefixedText
                               ==  mw.wikibase.getSitelink( suited ) then
                                r = false
                            else
                                r = suited
                            end
                        else
                            r = vsn.value
                        end
                    end
                end
            end
        end
    end
    if type( r ) == "nil" then
        if not since  or  since <= Failsafe.serial then
            r = Failsafe.serial
        else
            r = false
        end
    end
    return r
end -- Failsafe.failsafe()



-- Export
local p = { }



p.features = function ( frame )
    local submit = frame.args.sTransclude
    local r
    if submit  and  submit ~= "" then
        local subject = frame.args[ 1 ]
        local ns      = tonumber( frame.args.nsTransclude )
        local link    = frame.args.link
        local long    = frame.args.long
        local px      = frame.args.px
        local site    = frame.args.site
        local space   = frame.args.space
        local params  = { site         = site,
                          nsTransclude = ns,
                          sTransclude  = submit }
        if link == "1" then
            params.link = true
        end
        if long == "1" then
            params.long = true
        end
        if px then
            local k = tonumber( px )
            if k  and  k > 5 then
                params.px = math.floor( k )
            end
        end
        if space then
            if space == "0"  or
               space:match( "^[1-9]%.?%d*%l%l+" ) then
                params.space = space
            end
        end
        if subject then
            subject = mw.text.trim( subject )
            if subject ~= "" then
                params.subject = subject
            end
        end
        r = BadgesQuery.features( params, frame )
    end
    return r or ""
end    -- p.features



p.fulfils = function ( frame )
    local subject = frame.args[ 1 ]
    local s       = frame.args.match
    local site    = frame.args.site
    local r
    if s then
        local want = mw.text.split( s, "%s+" )
        local m
        for i = 1, #want do
            m = tonumber( want[ i ] )
            if m  and  m > 0 then
                r = r  or  { }
                table.insert( r, m )
            end
        end    -- for i
    end
    if r then
        if subject then
            subject = mw.text.trim( subject )
            if subject == "" then
                subject = false
            end
        end
        r = BadgesQuery.fulfils( subject, r, site )
    end
    return r and "1"  or  ""
end    -- p.fulfils



p.failsafe = function ( frame )
    -- Versioning interface
    local s = type( frame )
    local since
    if s == "table" then
        since = frame.args[ 1 ]
    elseif s == "string" then
        since = frame
    end
    if since then
        since = mw.text.trim( since )
        if since == "" then
            since = false
        end
    end
    return Failsafe.failsafe( since )  or  ""
end -- p.failsafe



setmetatable( p,  { __call = function ( func, ... )
                                 setmetatable( p, nil )
                                 return Failsafe
                             end } )

return p    -- BadgesQuery