FANDOM


--[[ LoU - List of Untergangers lua module 
     to improve parsing speed of the List of Untergangers page
     by mfaizsyahmi, 2017
  ]]
 
local libCtry = require("Dev:Country")
--local libFlag = require("Module:iconflags")
local lang = mw.language.new("en")
local p = {}
 
-- constants
local ytPlFmt = '[http://www.youtube.com/playlist?list=%s pl]'
local ytUserFmt = '[http://www.youtube.com/user/%s yt]'
local ytUcFmt = '[http://www.youtube.com/channel/%s yt]'
local statusTbl = {
    ['a'] = '<span class="active">Active</span>',
    ['h'] = '<span class="hiatus">Hiatus</span>',
    ['d'] = '<span class="dormant">Dormant</span>',
    ['r'] = '<span class="retired">Retired</span>',
    ['s'] = '<span class="suicide">Suicide</span>',
    ['t'] = '<span class="terminated">Terminated</span>',
    ['x'] = '<span class="resurrected">Resurrected</span>',
    ['na']= '<span class="doubtful">Not Unterganger?</span>',
    ['a?']= '<span class="active">Active (?)</span>',
    ['h?']= '<span class="hiatus">Hiatus (?)</span>',
    ['d?']= '<span class="dormant">Dormant (?)</span>',
    ['r?']= '<span class="retired">Retired (?)</span>',
    ['s?']= '<span class="suicide">Suicide (?)</span>',
    ['t?']= '<span class="terminated">Terminated (?)</span>',
    ['x?']= '<span class="resurrected">Resurrected (?)</span>',
}
-- column mapping
local colMap = {
    {head="#", class="index unsortable"},
    {head="Name", class="name", text="namenote"},
    {head="Reg", class="region", text="reg", title="regTitle"},
    {head="Ctry", class="country", text="ctryText", title="countryName"},
    {head="Vids", class="vids", text="vids"},
    {head="Views", class="views", text="views"},
    {head="Subs", class="subs", text="subs"},
    {head="Status", class="status", text="status"},
    {head="YT", class="yt", text="ytlink"}
}
 
-- implementing or assignments
-- basically go through given list, iterate until non-nil value found
local function eqOr(list)
    for _,v in pairs(list) do
        if v~=nil then return v end
    end
end
function p.eqor(frame) return eqOr(frame) end
 
-- come on, lua doesn't have this built in?
local function trim(str)
    return mw.text.trim(str)
end
 
-- if string has parsable number, formats it, otherwise just return
----for vids, views and subs col, which sometimes has "N/A"
local function formatNumCol(str)
    local n = tonumber(str)
    if n~=nil then
        return lang:formatNum(n)
    else
        return str
    end
end
 
local function buildTableRow(el, map, tbl, header)
    -- create the row builder
    local row= mw.html.create('tr')
    if tbl.noajax~= nil then row:addClass('noAJAX') end
    local cellTag = 'td'
    if header ~= nil then cellTag = 'th' end
 
    -- go through every item in the column map
    for i, attr in pairs(map) do
        -- the cell text
        -- pulls from tbl variable as defined in attr.text
        local text = eqOr{tbl[attr.text], ""}
        -- if building header take the maptext instead
        if header ~= nil then text = attr.head end
        -- create cell builder; apply text, class, title
        local cell = mw.html.create(cellTag)
        cell:wikitext(text)
            :attr("class", eqOr{attr.class, ""})
            :attr("title", eqOr{tbl[attr.title], ""})
        -- append cell to row
        row:node(cell)
    end
    -- append row to el
    el:node(row)
end
 
local function readRecordPage(pgName, pgNS, RS, FS, shift, pop)
    mw.log(os.time())
    local dataPage = mw.title.new(pgName,pgNS)
    local dataStr = dataPage:getContent()
 
    local recordTbl={}
    local i=1 
    for recordStr in mw.ustring.gmatch(dataStr, "([^"..RS.."]+)") do
        if not mw.ustring.find(recordStr, '=', 1) then
            recordTbl[i] = mw.text.split(recordStr,FS,1)
        else
            local fieldTbl = {}
            local j=1
            for fieldStr in mw.ustring.gmatch(recordStr, "([^"..FS.."]+)") do
                -- try and match key=value pair
                local fn = mw.ustring.gmatch(fieldStr, '[^=]+')
                local s1, s2 = trim(fn()), trim(fn())
                if s2~=nil then -- k/v match found
                    fieldTbl[s1] = s2
                else --unnamed value
                    fieldTbl[j] = trim(fieldStr)
                end
                j = j + 1
            end
            recordTbl[i] = fieldTbl
        end
        i = i + 1
    end
    --mw.log(#recordTbl)
    if shift == true then table.remove(recordTbl,1) end
    if pop == true then table.remove(recordTbl) end
    --mw.log(#recordTbl)
    --mw.log(recordTbl[1][1])
    mw.log(os.time())
    return recordTbl
end
 
function p.main(frame)
    -- retrieve arguments
    local fArgs = frame.args--.getParent()
    local LoUNS = eqOr{fArgs.ns, "User"}
    local LoUPage = eqOr{fArgs.name, "Mfaizsyahmi/testdata"}
    local RS = eqOr{fArgs.rs, "§"} -- record separator
    local FS = eqOr{fArgs.fs, "‖"} -- field separator
 
    -- read the record file and extract record table
    local recordTbl = readRecordPage(LoUPage,LoUNS,RS,FS,true,true)
 
    -- create the table builder
    local tableEl = mw.html.create('table')
    tableEl:attr("class", "wikitable sortable fullwidth hilight untergangers")
    -- build the header
    buildTableRow(tableEl, colMap, {}, true)
 
    -- iterate each record to build the table entry rows
    for _, record in pairs(recordTbl) do
        -- extract record fields into table
        local t = {
            name = eqOr{record.name, record[1], ""},
            reg  = eqOr{record.region, record[2], ""},
            ctry = eqOr{record.ctry, record[3], ""},
            vids = eqOr{record.vids, record[4], ""},
            views= eqOr{record.views, record[5], ""},
            subs = eqOr{record.subs, record[6], ""},
            status = eqOr{record.status, record[7], ""},
            yt = eqOr{record.yt, record[8], ""},
            pl = eqOr{record.pl, ""},
            noajax = eqOr{record.noAjax, ""},
            note = eqOr{record.note, record[9], ""}
        }
        --mw.log(t.name)
 
        --deriving values from the variables
        ----name and note
        if t.note ~= "" then
            t.namenote = t.name ..' <small>('.. t.note ..')</small>'
        else
            t.namenote = t.name
        end
 
        ----country and region
        t.countryCode = mw.ustring.lower(t.ctry)
        ----HPW accepts uk as synonym for gb
        if t.countryCode == 'uk' then t.countryCode = 'gb' end
        t.countryName = ""
        t.region = ""
        t.subregion = ""
        t.flag = ""
        if t.countryCode ~= "" then
            --mw.log(libCtry.main{t.countryCode,'name'})
            t.countryName = libCtry.main{t.countryCode,'name'}
            t.region = libCtry.main{t.countryCode,'region'}
            t.subregion = libCtry.main{t.countryCode,'sub-region'}
            --t.flag = libFlag.flag{t.countryCode, useemoji='om'}
            if t.reg == "" then
                t.reg = ".."
            end
        end
        --mw.log(t.countryName, t.region, t.subregion, t.flag)
        ----the title for region cell
        t.regTitle = t.region .." – ".. t.subregion
        ----text for ctry cell
        t.ctryText = t.ctry .."&nbsp;".. t.flag
 
        -- numbers
        t.vids = formatNumCol(t.vids)
        t.views = formatNumCol(t.views)
        t.subs = formatNumCol(t.subs)
 
        -- status
        t.status = eqOr{statusTbl[t.status], t.status}
 
        -- yt link
        t.ytlink = ''
        -- tilde means take the name argument
        if t.yt == '~' then
            _, _, t.yt = mw.ustring.find(t.name,'%[?%[?([^%]]*)%]?%]?')
        end
        if t.pl ~= "" then -- playlist defined
            t.ytlink = mw.ustring.format(ytPlFmt, t.pl)
        elseif mw.ustring.len(t.yt)==24 
            and mw.ustring.sub(t.yt,1,2)=='UC' then
            -- yt matches channel ID (string of 24 char length begin w/ UC)
            t.ytlink = mw.ustring.format(ytUcFmt, t.yt)
        else -- old username
            t.ytlink = mw.ustring.format(ytUserFmt, t.yt)
        end
 
        -- finally build the row given the table of variables
        buildTableRow(tableEl, colMap, t)
    end
    mw.log(os.time())
    -- return the text returned by the html builder
    return tableEl:done()
end
 
function avg(t)
    local sum = 0
    local count = #t
    for _, n in pairs(t) do
        sum = sum + n
    end
    return sum/count
end
 
-- benchmarking
-- how to:
function p.test(frame)
    local fArgs = frame.args--.getParent()
    local LoUNS = fArgs.ns or "User"
    local LoUPage = fArgs.name or "Mfaizsyahmi/testdata"
    local RS = fArgs.rs or "§" -- record separator
    local FS = fArgs.fs or "‖" -- field separator
    local dataPage = mw.title.new(LoUPage,LoUNS)
    local dataStr = dataPage:getContent()
 
    local benchmarkType = tonumber(fArgs[1])
    local iterations = tonumber(fArgs[2]) or 10
 
    -- timing the difference between two methods
    local t1 = os.time()
    if benchmarkType==1 then
        for i = 1, 20 do
            local recordTbl={}
            for recordStr in mw.ustring.gmatch(dataStr, "([^"..RS.."]+)") do
                table.insert(recordTbl, mw.text.split(recordStr,FS,true) )
            end
        end
 
    elseif benchmarkType==2 then
        for i = 1, 20 do
            local recordTbl={}
            for recordStr in mw.ustring.gmatch(dataStr, "([^"..RS.."]+)") do
                local fieldTbl = {}
                local j=1
                for fieldStr in mw.ustring.gmatch(recordStr, "([^"..FS.."]+)") do
                    -- try and match key=value pair
                    local fn = mw.ustring.gmatch(fieldStr, '[^=]+')
                    local s1, s2 = fn(), fn()
                    if s2~=nil then -- k/v match found
                        fieldTbl[trim(s1)] = trim(s2)
                    else --unnamed value
                        fieldTbl[j] = trim(fieldStr)
                    end
                    j = j + 1
                end
                table.insert(recordTbl, fieldTbl)
            end
        end
    end
    local t2 = os.time()
    return (t2-t1)/iterations
 
end
 
return p

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.