Modul:Shipregister

Fra Wikipedia, den frie encyklopedi
Moduldokumentasjon
local p = {}

--[[
National ship registers
Format: Wikidata entity = URI prefix, Automatic search
--]]
local localreg = {
    -- Japan. Nippon Kaiji Kyokai. ClassNK.
    Q17  = { 'https://www.classnk.or.jp/register/regships/regships.aspx', false },
    -- Norway. Sjøfartsdirektoratets skipsregister (NOR/NIS).
    Q20  = { 'https://www.sdir.no/shipsearch/#/?q=', true },
    -- United States. American Bureau of Shipping. (ABS)
    Q30  = { 'https://www.eagle.org/portal/#/absrecord/search', false },
    -- Denmark. Søfartsstyrelsens skipsregister (DIS).
    Q35  = { 'http://skibsregister.dma.dk/Main.asp?A=1&D=1', false },
    -- People's Republic of China. China Classification Society.
    Q148 = { 'https://www.ccs.org.cn/ccswzen/internationalShipsList?columnid=201900002000000123&imono=', true },
    -- Russia. Russian Maritime Register of Shipping.
    Q159 = { 'https://lk.rs-class.org/regbook/regbookVessel?ln=en&namer=', true },
    -- Ucraine. The shipping register of Ucraine.
    Q212 = { 'http://en.shipregister.ua/ships/search.html?search=', true },
    -- Croatia. Croatian register of shipping.
    Q224 = { 'http://report.crs.hr/HRBWebReports/default.aspx', false },
    -- Australia. Australian Maritime Safety Authority.
    Q408 = { 'https://www.amsa.gov.au/vessels-operators/ship-registration/list-registered-ships?ship_search=', true },
    -- India. Indian Register of Shipping. IRClass.
    Q668 = { 'https://www.irclass.org/shipsearch', false },
    -- Marshall Islands. International maritime register.
    Q709 = { 'https://resources.register-iri.com/VesselDB/Vessel/Search', false },
    -- South Korea. Korean Register of Shipping.
    Q884 = { 'https://www.krs.co.kr/eng/ship_as_address/regist_search.aspx?s_code=0103040500', false },
    -- Hong Kong. Hong Kong Shipping Registry.
    Q8646 = { 'https://ebs.mardep.gov.hk/eBS3/enquiryRegStatus?lang=en', false }
}

--[[
Global ship databases
Format: URI prefix, Automatic search
--]]
local globaldb = {
    -- Lloyd's register of ships
    { 'https://classdirect.lr.org/lros?lrno=', true },
    -- DNV vessel register
    { 'https://vesselregister.dnvgl.com/VesselRegister/vesseldetails.html?imo=', true }
}

-- template entry point
function p._getlink(frame)
    local args = frame:getParent().args
    return p.getlink(args)
end

-- invoke entry point
function p.__getlink(frame)
    local args = frame.args
    return p.getlink(args)
end

function singleval(snak)
    local ret = nil

    if snak.datavalue.type == 'wikibase-entityid' then
        ret = snak.datavalue.value.id
    elseif snak.datavalue.type == 'time' then
        ret = snak.datavalue.value.time
    elseif snak.datavalue.type == 'string' then
        ret = snak.datavalue.value
    end

    return ret
end

--[[
getlink: Returnerer en lenke til det lokale skipsregisteret eller en tom tekst-streng.

For at en lenke skal returneres så må skipet finnes på Wikidata og
følgende kriterier må være møtt:
* siste flaggstat (P8047) har et lokalt skipsregister som er tilgjengelig online
* har et gyldig IMO nummer (P458)
* kan ikke være utfaset (P730)

Hvis parameteret 'fallback' er gitt, vil det returneres lenker til globale
databaser over skip, dersom det ikke finnes et lokalt skipsregister.
--]]
function p.getlink (args)
    local qid = args.qid or nil
    local fallback = args.fallback or nil

    -- Get data from Wikidata
    local entity = mw.wikibase.getEntity(qid)
    local label = ''
    if entity then
        label = entity:getLabel()
        mw.log('Using data for: ' .. label .. ' (' .. entity.id .. ')')
    else
        local curtitle = mw.title.getCurrentTitle()
        if curtitle.namespace == 0 then
            error('Failed to fetch data from Wikidata')
        else
            return ''
        end
    end

    -- Check if country of registry has a local registry and that given start time
    -- qualifiers that it is listed as the last one
    local annodomino = '+0000-00-00T00:00:00Z'
    local countries = entity:getBestStatements('P8047')
    local last_date = annodomino
    local last_idx = 0
    local matches = {}
    for k, v in pairs(countries) do
        local country = singleval(v.mainsnak)
        local countrylbl = mw.wikibase.getLabel(country)
        if v.qualifiers then
            local sstart = v.qualifiers.P580 and singleval(v.qualifiers.P580[1]) or annodomino
            local send   = v.qualifiers.P582 and singleval(v.qualifiers.P582[1]) or annodomino
            mw.log('country of reg.: ' .. countrylbl .. ', start: ' .. sstart .. ', end: ' .. send)
            if sstart > last_date then
                last_date = sstart
                last_idx = k
            end
        end
        if localreg[country] then
            local match = {
                idx     = k,
                country = country
            }
            if v.qualifiers then
                match.date = v.qualifiers.P580 and singleval(v.qualifiers.P580[1]) or annodomino
            else
                match.date = annodomino
            end
            table.insert(matches, match)
        end
    end

    -- Do we have a last one?
    local country_idx = 0
    local match_country = nil
    if last_idx == 0 then
        if #matches > 0 then
            country_idx = matches[1].idx
            match_country = matches[1].country
        end
    else
        for k, v in pairs(matches) do
            if v.idx == last_idx then
                country_idx = v.idx
                match_country = v.country
                break
            end
        end
    end
    --mw.log(last_idx)
    --mw.log(country_idx)

    -- Check if item has an IMO number
    local imonumbers = entity:getBestStatements('P458')
    local imonr = #imonumbers > 0 and singleval(imonumbers[1].mainsnak) or nil

    -- Check if item has a service retirement date
    local retirements = entity:getBestStatements('P730')
    local isactive = true
    if #retirements > 0 then
        isactive = false
    end

    -- Format link
    local ret = ''
    if isactive and imonr then
        if country_idx > 0 then
            local uriprefix = localreg[match_country][1]

            if localreg[match_country][2] then
                ret = '[' .. uriprefix .. imonr .. ' ' .. label .. ']'
            else
                ret = '[' .. uriprefix .. ' ' .. label .. ']'
            end
        else
            if fallback then
                local glinks = {}
                for k, v in pairs(globaldb) do
                    local glink = '[' .. v[1] .. imonr .. ']'
                    table.insert(glinks, glink)
                end

                ret = label .. ': ' .. table.concat(glinks, ' ')
            end
        end
    end

    return ret
end

function p.testcases()
    local testqid = {
        'Q11987429',  -- norwegian roro ferry, no qualifiers
        'Q107014152', -- norwegian ship without imo
        'Q32427857',  -- sold to new zealand, former norwegian
        'Q56199419',  -- dutch ship
        'Q19380767',  -- retired with imo
        'Q3439800',   -- retired without imo
        'Q1465479',   -- danish ship
        'Q212016',    -- russian ship
        'Q83637237',  -- ship without country of registry
        'Q1853117'    -- norwegian and german ship, no qualifiers
    }

    for k, v in pairs(testqid) do
        mw.log(p.getlink({qid=v}))
    end
    mw.log(p.getlink({qid='Q83650793', fallback=true})) -- panama ship using fallback
end

return p