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   = '[https://www.youtube.com/playlist?list=%s ▶️️]'
local ytUserFmt = '[https://www.youtube.com/user/%s ▶️️]'
local ytUcFmt   = '[https://www.youtube.com/channel/%s ▶️️]'
local sbUserFmt = '[https://socialblade.com/youtube/user/%s 📈]'
local sbUcFmt   = '[https://socialblade.com/youtube/channel/%s 📈]'
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>',
}
local sbSortKey = {
    ['A+']= 'A1',
    ['A' ]= 'A2',
    ['A-']= 'A3',
    ['B+']= 'B1',
    ['B' ]= 'B2',
    ['B-']= 'B3',
    ['C+']= 'C1',
    ['C' ]= 'C2',
    ['C-']= 'C3',
    ['D+']= 'D1',
    ['D' ]= 'D2',
    ['D-']= 'D3',
    ['TBD']='TBD'
}
-- maps field position to variable
local colMap = {'name','reg','ctry','vids','views','subs','sbgrade','status','yt','note'}
 
-- column definition
   -- direct text: head, class
   -- property names: text, title, sortkey
local colDef = {
    {head="#", class="index unsortable"},
    {head="Name", class="name", text="namenote"},
    {head="Reg", class="region reg", text="reg", title="regTitle"},
    {head="Ctry", class="country ctry", text="ctryText", title="countryName"},
    {head="Vids", class="vids", text="vids"},
    --{head="Views", class="views", text="views"},
    --{head="Subs", class="subs", text="subs"},
    {head="SB", class="sbgrade sb", text="sbgrade", sortkey="sbkey"},
    {head="Status", class="status", text="status"},
    {head="Links", class="links plainlinks", text="links"}
    --{head="Links", class="yt", text="ytlink"}
}
 
-- shorthands
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 empty(a)
	return a==nil or a==""
end
function p.empty(a) return empty(a) end
 
--[=[ 
Table row builder 
el: the table element
map: the column definition table
tbl: table containing properties to map
header: if not nil build the headers
--]=]
local function buildTableRow(el, map, tbl, header)
    -- create the row builder
    local row= mw.html.create('tr')
    if empty(header) and not empty(tbl.noajax) then
        row:addClass('noAJAX')
    end
    local cellTag = 'td'
    if not empty(header) then cellTag = 'th' end
 
    -- go through every item in the column map
    -- attr: the individual map item
    for i, attr in pairs(map) do
        -- the cell text
        -- pulls from tbl variable as defined in attr.text
        local text = tbl[attr.text] or ""
        -- if building header take the header instead
        if not empty(header)  then text = attr.head end
        -- create cell builder; apply text, class, title
        local cell = mw.html.create(cellTag)
        cell:wikitext(text)
            :attr("class", attr.class or "")
            :attr("title", tbl[attr.title] or "")
        if not empty(attr.sortkey) then
            cell:attr("data-sort-value", tbl[attr.sortkey] or "")
        end
        -- append cell to row
        row:node(cell)
    end
    -- append row to el
    el:node(row)
end
 
local function readRecordPage(pgName, pgNS, RS, FS, colMap, shift, pop)
    local dataPage = mw.title.new(pgName,pgNS)
    local dataStr = dataPage:getContent()
    -- rmv newlines
    dataStr = mw.ustring.gsub(dataStr,'\n', '')
 
    local recordTbl={}
    for recordStr in mw.ustring.gmatch(dataStr, "([^"..RS.."]+)") do
        -- dropped split method because we want to map the vars immediately
        -- split record fields manually
        local fieldTbl = {}
        local j=1
        --for fieldStr in mw.ustring.gmatch(recordStr, "([^"..FS.."]*)") do
        -- have to use gsplit to get empty fields (those actually exists!)
        for fieldStr in mw.text.gsplit(recordStr, FS) do
            if empty(fieldStr) then mw.log('found empty field') end
            -- 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)
            elseif colMap~= nil then --unnamed but mappable value
                fieldTbl[colMap[j]] = trim(fieldStr)
            else -- unnamed value
                fieldTbl[j] = trim(fieldStr)
            end
            j = j + 1
        end
        table.insert(recordTbl, fieldTbl)
    end
    if shift == true then table.remove(recordTbl,1) end
    if pop == true then table.remove(recordTbl) end
    return recordTbl
end
 
function p.main(frame)
    -- retrieve arguments
    local fArgs = frame.args--.getParent()
    local LoUNS = fArgs.ns or 0
    local LoUPage = fArgs.name or "List of Untergangers/data"
    local RS = fArgs.rs or "§" -- record separator
    local FS = fArgs.fs or "‖" -- field separator
 
    -- read the record file and extract record table
    local recordTbl = readRecordPage(LoUPage,LoUNS,RS,FS,colMap,true,true)
 
    -- create the table builder
    local tableEl = mw.html.create('table')
    tableEl:attr("class", "untergangers wikitable fullwidth sortable hilight floatheader")
    -- build the header
    buildTableRow(tableEl, colDef, {}, true)
 
    -- iterate each record to build the table entry rows
    --for _, record in pairs(recordTbl) do
    for _, t in pairs(recordTbl) do
        -- extract record fields into table
        --[[now that we mapped arrays to vars in readRecordPage the whole
            block below is skipped. hopefully this would speed up parsing.]]
        --[[local t = {
            name = record.name or record[1] or "",
            reg  = record.reg or record[2] or "",
            ctry = trim(record.ctry or record[3] or ""),
            vids = record.vids or record[4] or "",
            views= record.views or record[5] or "",
            subs = record.subs or record[6] or "",
            sbgrade = trim(record.rank or record[7] or ""),
            status = record.status or record[8] or "",
            yt = record.yt or record[9] or "",
            pl = record.pl or "",
            noajax = record.noAjax or "",
            note = record.note or record[10] or "",
            -- initialize other vars
            namenote = "",
            regTitle = "",
            ctryText = "",
            sbkey = "",
            ytlink = "",
            sblink = "",
            links  = ""
        }
        ]]
        --mw.log(t.name)
 
        --deriving values from the variables
        ----name and note
        if not empty(t.note) then
            t.namenote = t.name ..' <small>('.. t.note ..')</small>'
        else
            t.namenote = t.name
        end
 
        ----country and region
        t.ctry = t.ctry or '' --fix nil
        t.countryCode = mw.ustring.lower(t.ctry)
        ----HPW accepts uk as synonym for gb
        if t.countryCode == 'uk' then t.countryCode = 'gb' end
 
        if not empty(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 empty(t.reg) then
                t.reg = ".."
            end
            ----the title for region cell
            t.regTitle = t.region .." – ".. t.subregion
            ----text for ctry cell
            t.ctryText = t.flag .. t.ctry
        --else
            --t.countryName = ""
            --t.region = ""
            --t.subregion = ""
            --t.flag = ""
        end
 
        -- numbers
        t.vids = formatNumCol(t.vids)
        t.views = formatNumCol(t.views)
        t.subs = formatNumCol(t.subs)
 
        -- status and grade
        t.status = statusTbl[t.status] or t.status
        t.sbkey = sbSortKey[t.sbgrade] or 'Z'
 
        -- yt link
        t.yt = t.yt or '' -- fix nil
        -- tilde means take the name argument
        if t.yt == '~' then
            _, _, t.yt = mw.ustring.find(t.name,'%[?%[?([^%]]*)%]?%]?')
        end
        if not empty(t.pl) then -- playlist defined
            t.ytlink = mw.ustring.format(ytPlFmt, t.pl)
            t.sblink = ''
        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)
            t.sblink = mw.ustring.format(sbUcFmt, t.yt)
        elseif not empty(t.yt) then -- old username
            t.ytlink = mw.ustring.format(ytUserFmt, t.yt)
            t.sblink = mw.ustring.format(sbUserFmt, t.yt)
        else -- absent
            t.ytlink = ''
            t.sblink = ''
        end
        t.links = t.ytlink..' '..t.sblink
 
        -- finally build the row given the table of variables
        buildTableRow(tableEl, colDef, t)
    end
 
    -- return the text returned by the html builder
    return tableEl:done()
end
 
--WIP
function p.item(frame)
    -- retrieve arguments
    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()
    dataStr = mw.ustring.gsub(dataStr,'\n', '')
 
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.