FANDOM


--[[<pre> Creates an automatically sorted Incubator course table & shows statistics related to it
Debug console code
local frame = {args = { '1',['src']=8, 5 },getParent = function () local pArgs = {'1',['src']=8, 5 }  return { args = pArgs } end } mw.log('')
]]--
local p = {}
local u = require('Module:Utility')
local l = require('Module:Lang')
local tableBuilder = require('Module:Tablebuilder')
local chart = require('Module:Chart')
local mFileLink = require('Module:File link')
local tOrigCourse ={["fren"]=1,["enfr"]=1,["iten"]=1,["enit"]=1,["pten"]=1,["enpt"]=1,["esen"]=1,["enes"]=1,["deen"]=1,["ende"]=1}
local tCourses,tSrcCourses,tFastest,tCrowPrint = {},{},{},{}
local tCrowData = mw.loadData('Module:Crow/data')
local mJsonParser = require("Module:Crow/jsondata")
local tJsonCrow = mJsonParser.getJsonData("Module:Crow/json")
 
-- Adds a new row to the language course table
function p.showcourses(frame)
    local tIncRows      ={}
    local tSortedRows   ={}
    local textsplit  = mw.text.split
    local tCourseCode,sFrom,sTo = "", "",""
    local sP1date, sP2date, sP3date = "", "",""
    local iPhase, phaselink = 0,""
    local hStatRow 
 
    if next(tJsonCrow) then 
       tCrowData = tJsonCrow 
    end
 
    for sCourse,sTableData  in pairs(tCrowData) do
        tCourseCode = textsplit(sCourse,"#") -- find #
        sFrom = tCourseCode[1] -- get L1
        sTo = tCourseCode[2]   -- get L2
        sP1date = sTableData.P1date 
        sP2date = sTableData.P2date 
        sP3date = sTableData.P3date
 
        iPhase, phaselink = p.getcurrphase(sP1date ,sP2date ,sP3date ,sFrom,sTo)
        tIncRows = { l.getLang(sFrom), sFrom,sTo,sP1date, sP2date , sP3date,iPhase
                    ,sTableData.P1ref or "",sTableData.P2ref or "",sTableData.P3ref or "" }
        tSortedRows  = sortedAdd (tIncRows,tSortedRows,7,"desc" )
    end
 
    local hTableCourses =  tableBuilder.createTable("List of courses", "background-color:white",{"wikitable","sortable","crowtable"})
    local hStatRow = tableBuilder.createRow ({["style"]="background-color:white"})
    local mPhase1Link = p.getFileLink('phase1.png','25x30px','Incubator#Phase_1', 'Phase 1')
    local mPhase2Link = p.getFileLink('phase2.png','25x30px','Incubator#Phase_2', 'Phase 2')
    local mPhase3Link = p.getFileLink('phase3.png','25x30px','Incubator#Phase_3', 'Phase 3')
    local mPhasesLink = "" --p.getFileLink('','25x30px',Incubator,"Phases")
    --Adding header columns
    local tSortNumber = {["data-sort-type"]="number"}
    local tSortText = {["data-sort-type"]="text"}
    local tCourseRow = {
    [1]={[1]=tableBuilder.createCol("Languages",{["colspan"]="2"},true),
        [2]=tableBuilder.createCol("Phase",{},true),
        [3]=tableBuilder.createCol("Date♠ entering phase",{["colspan"]="3"},true),
        [4]=tableBuilder.createCol("Days in phase",{["colspan"]="3"},true)
        },
    [2]={
        [1]=tableBuilder.createCol("For (L1)",tSortText,true),
        [2]=tableBuilder.createCol("Teaching",tSortText,true),
        [3]=tableBuilder.createCol(mPhasesLink,tSortNumber,true),
        [4]=tableBuilder.createCol(mPhase1Link,tSortText,true),
        [5]=tableBuilder.createCol(mPhase2Link,tSortText,true),
        [6]=tableBuilder.createCol(mPhase3Link,tSortText,true),
        [7]=tableBuilder.createCol(mPhase1Link,tSortNumber,true),
        [8]=tableBuilder.createCol(mPhase2Link,tSortNumber,true),
        [9]=tableBuilder.createCol(mPhase1Link ..'+'.. mPhase2Link,tSortNumber,true)}
        }
    -- Header columns 
    for iRow, tCells in pairs(tCourseRow) do
        hStatRow = tableBuilder.createRow ({["style"]="background-color:white"})
        hStatRow =tableBuilder.appendColumns(hStatRow,tCells)
        hTableCourses = tableBuilder.appendRow(hTableCourses,hStatRow) 
    end
    for i=1,#tSortedRows  do 
       hStatRow =  p.addrow(tSortedRows[i][2],tSortedRows[i][3],tSortedRows[i][4],tSortedRows[i][5],tSortedRows[i][6],tSortedRows[i][8],tSortedRows[i][9],tSortedRows[i][10]) 
       hTableCourses = tableBuilder.appendRow(hTableCourses,hStatRow) 
    end
    return hTableCourses 
end
 
function p.addrow( sFrom,sTo, sP1Date,sP2Date,sP3Date,sP1ref,sP2ref,sP3ref)
    local tBackColor = {[1] = "#E9E9E9", [2] = "#CCFFCC", [3] = "#AAFFAA"}
    local bisOrig = p.isOrigCourse(sFrom,sTo)   
    local iPhase, sPhaselink = p.getcurrphase(sP1Date,sP2Date,sP3Date,sFrom,sTo)
    local sBackColor = tBackColor[tonumber(iPhase)]
    local sStyle =  'background-color:' .. sBackColor ..'; text-align:center'
    local tCourseRow = {
    [1]=p.flagheader( sFrom)   , -- From flag
    [2]=p.flagheader( sTo) ,       -- to flag
    [3]=tableBuilder.createCol(sPhaselink,{["data-sort-value"]=iPhase}) , 
    [4]=p.frmtdate(sP1Date,sP1ref),
    [5]=p.frmtdate(sP2Date,sP2ref),
    [6]=p.frmtdate(sP3Date,sP3ref),
    [7]=p.days(sP1Date, sP2Date,bisOrig,iPhase),                                         
    [8]=p.days(sP2Date, sP3Date,bisOrig,iPhase), 
    [9]=p.days(sP1Date, sP3Date,bisOrig,iPhase)}
    local hStatRow = tableBuilder.createRow ({["style"]=sStyle})
    tableBuilder.appendColumns(hStatRow,tCourseRow)
 
    return hStatRow
end
 
function p.getcurrphase(p1,p2,p3,fromlangcode,tolangcode)
    local iPhase = 1
    if fromlangcode and tolangcode and (tOrigCourse[fromlangcode..tolangcode]==1) then 
        iPhase = 3  
    elseif u.checkDate(p1) then
        iPhase = 1
        if u.checkDate(p2) then
            iPhase = 2
            if u.checkDate(p3) then
	            iPhase = 3
            end
        end
    end
    if not(p1) and not(p2) and not(p3) and not(fromlangcode) and not(tolangcode) then
        return iPhase 
    end
    local phaselink = '['..'http://incubator.duolingo.com/courses/'..tolangcode..'/'..fromlangcode..'/status'..' '..iPhase..']'
 
    return iPhase, phaselink
end
 
--Shows the actual stats
function p.showstats(frame)
    local tArgs= u.getArgs(frame)
    if not(tArgs) then 
        return
    end
    local sStats= tArgs[1]
    local sStatInfo = p.createStats(sStats) 
    return sStatInfo 
end
 
--Creates stats, can be used by other scripts.
function p.createStats(sStat)
    local tCoursesPhase = {[1]=0,[2]=0,[3]=0}
    local tCrow ={}
    local tRows = {}
    local tTotDays = {["iDaysP1_2"]=0,["iDaysP2_3"]=0,["iDaysP1_3"]=0,
                      ["iCoursesP1_2"]=0,["iCoursesP2_3"] =0,["iCoursesP1_3"] =0}
    local tLang ={["to"]={},["from"]={},["toP23"]={},["fromP23"]={},["toP1"]={},["fromP1"]={}, ["toLIST"]={},["fromLIST"]={},["toP23LIST"]={},["fromP23LIST"]={},["toP1LIST"]={},["fromP1LIST"]={}}
    local textsplit  = mw.text.split
    local tCourseCode,sFrom,sTo = "", "",""
    local sP1date, sP2date, sP3date = "", "",""
    local iPhase, phaselink = 0,""
    local hStatRow 
 
    if next(tJsonCrow) then 
       tCrowData = tJsonCrow 
    end
 
    for sCourse,sTableData  in pairs(tCrowData) do
        tCourseCode = textsplit(sCourse,"#") -- find #
        sFrom = tCourseCode[1] -- get L1
        sTo = tCourseCode[2]     -- get L2
        sP1date = sTableData.P1date 
        sP2date = sTableData.P2date 
        sP3date = sTableData.P3date
        tRows = {sFrom,sTo,"","","",sP1date ,sP2date ,sP3date }
        iPhase, sLink = p.getcurrphase(sP1date ,sP2date,sP3date ,sFrom,sTo)
 
        p.addLangRow(tRows ,tCrow) -- ← IMPORTANT
        if(iPhase) then
	        tCoursesPhase[iPhase]  = tCoursesPhase[iPhase] + 1
        end
        tLang = p.addLang( tLang,sFrom,sTo, iPhase)
    end
    -- CREATE fastest rows
    local tNewestCourses = {["recent"]={["P1"]={},["P2"]={},["P3"]={}},
                            ["new"]={["P1"]={["name"]="",["date"]="0000-00-00"},["P2"]={["name"]=""
                           ,["date"]="0000-00-00"},["P3"]={["name"]="",["date"]="0000-00-00"}}}
    local tAddedOrder = {["p1"]={},["p2"]={},["p3"]={}}
 
    for sCourse,tCourseTable in pairs(tCrow) do
        p.getFastest(tCrow[sCourse],tFastest)    
        for i=1,3 do
            tAddedOrder = addReleasedDate(tCrow[sCourse],i,tAddedOrder,sCourse)
        end
    end
 
    --Gets newest course
    for sCourse,tCourseTable in pairs(tCrowData) do
        p.getNewestCourse(sCourse,tCrowData,tNewestCourses,1)
        p.getNewestCourse(sCourse,tCrowData,tNewestCourses,2)
        p.getNewestCourse(sCourse,tCrowData,tNewestCourses,3)
    end
 
    local iTotCourses = tCoursesPhase[1] + tCoursesPhase[2] + tCoursesPhase[3] 
    local tGraphVals = {["to"]={},["from"]={}, ["toP1"]={},["fromP1"]={}, ["toP23"]={},["fromP23"]={}}
    local _,_ = createLangList(tLang["from"], tLang["fromLIST"],"from",tGraphVals)
    local _,_ = createLangList(tLang["to"], tLang["toLIST"],"to",tGraphVals) -- creates info for graph
    local sLearningP23a, iLearningP23 = createLangList(tLang["toP23"], tLang["toP23LIST"],"toP23",tGraphVals)
    local sLearningP1a, iLearningP1  = createLangList(tLang["toP1"], tLang["toP1LIST"],"toP1",tGraphVals)
    local sTeachingP23a, iTeachingP23 = createLangList(tLang["fromP23"], tLang["fromP23LIST"],"fromP23",tGraphVals)
    local sTeachingP1a, iTeachingP1  = createLangList(tLang["fromP1"], tLang["fromP1LIST"],"fromP1",tGraphVals)
 
    if (sStat== "statmonthlycoursehist") then   
       local sCourseChart =  p.createBarChart(tFastest["Stat"])
       return sCourseChart
    end
 
    if (sStat== "statpietotcourses") then
        return p.createPieChart(tGraphVals["to"], "order=yes")
    end
 
    if (sStat== "2from") then
        return p.createPieChart(tGraphVals["from"], "order=yes")
    end
 
    if (sStat== "2P1to") then
        return p.createPieChart(tGraphVals["toP1"], "order=yes")
    end
 
    if (sStat== "2P1from") then
        return p.createPieChart(tGraphVals["fromP1"], "order=yes")
    end
 
    if (sStat== "2P23to") then
        return p.createPieChart(tGraphVals["toP23"], "order=yes")
    end
 
    if (sStat== "2P23from") then
        return p.createPieChart(tGraphVals["fromP23"], "order=yes")
    end
 
    if (sStat== "statnoofcourses") then
        local hTableCourses =  tableBuilder.createTable("", "background-color:gray;width:100%",{"duotable"})
        local hStatRow = tableBuilder.createRow ({["style"]="background-color:green"})
        local tCourseRow = {
        [1]={[1]=tableBuilder.createCol ("Available",{["style"]="text-align: center; background-color:MediumSeaGreen;",["rowspan"]="2"},true),
            [2]=tableBuilder.createCol ("To learn <br>(".. iLearningP23 .. " languages)",{["style"]="text-align: center; background-color:PaleGreen;font-size:13px;"},true),
            [3]=tableBuilder.createCol (sLearningP23a,{["style"]="text-align: left; background-color:PaleGreen;font-size:11px;"},false)},
        [2]={[1]=tableBuilder.createCol ("For speakers of <br> (".. iTeachingP23 .. " languages)",{["style"]="text-align: center; background-color:LightGreen;font-size:13px;"},true),
            [2]=tableBuilder.createCol (sTeachingP23a,{["style"]="text-align: left; background-color:LightGreen;font-size:11px;"},false)},
        [3]={[1]=tableBuilder.createCol ("Being<br>built",{["style"]="text-align: center; background-color:Gray;",["rowspan"]="2"},true),
            [2]=tableBuilder.createCol ("To learn <br>(".. iLearningP1 .. " languages)",{["style"]="text-align: center; background-color:LightGray;font-size:13px;"},true),
            [3]=tableBuilder.createCol (sLearningP1a,{["style"]="text-align: left; background-color:LightGray;font-size:11px;"},false)},
        [4]={[1]=tableBuilder.createCol ("For speakers of <br>(".. iTeachingP1 .. " languages)",{["style"]="text-align: center; background-color:Silver;font-size:13px;"},true),
            [2]=tableBuilder.createCol (sTeachingP1a,{["style"]="text-align: left; background-color:Silver;font-size:11px;"},false)}}
        local hColHeader =tableBuilder.createCol ("Number of courses per language",{["data-sort-type"]="text",["colspan"]="3"},true)
 
        tableBuilder.appendCol(hStatRow,hColHeader) 
        hTableCourses = tableBuilder.appendRow(hTableCourses,hStatRow) 
 
        for iKey,tColumns in ipairs(tCourseRow) do
            hStatRow = tableBuilder.createRow ({["style"]="text-align:center"})
            for iKey,hCol in ipairs(tColumns) do 
                tableBuilder.appendCol(hStatRow,hCol) 
            end
            hTableCourses = tableBuilder.appendRow(hTableCourses,hStatRow) 
        end
 
        return (hTableCourses)
    end
 
    if (sStat== "statvolcourses") then
        local sTrophy1 =  p.getFileLink('Trophy1.png','20x20px', '','Fastest Course Phase')
        local tCourseRow = {
            {"","Phase 1","Phase 2","Phase 3"},
            {"No. of Courses (".. iTotCourses .. ")",tCoursesPhase[1],tCoursesPhase[2],tCoursesPhase[3]},
            {"Duration in days","in Phase 1","in Phase 2","To Phase 3"},
            {"Average per phase",tFastest["1_2"]["tAvg"]["iAvg"],tFastest["2_3"]["tAvg"]["iAvg"],tFastest["1_3"]["tAvg"]["iAvg"]},
            {"Course moved to phase (average days)",calcAvgReleaseInterval(1,tAddedOrder),calcAvgReleaseInterval(2,tAddedOrder),calcAvgReleaseInterval(3,tAddedOrder)},
            {"Fastest",sTrophy1,sTrophy1,sTrophy1},
            {"Original Course",p.createFastRow(tFastest,"tOrig","1_2"),p.createFastRow(tFastest,"tOrig","2_3"),p.createFastRow(tFastest,"tOrig","1_3")},
            {"Reverse Course",p.createFastRow(tFastest,"tRev","1_2"),p.createFastRow(tFastest,"tRev","2_3"),p.createFastRow(tFastest,"tRev","1_3")},
            {"New tree",p.createFastRow(tFastest,"tNew","1_2"),p.createFastRow(tFastest,"tNew","2_3"),p.createFastRow(tFastest,"tNew","1_3")},
            {"New source language",p.createFastRow(tFastest,"tNewSrc","1_2"),p.createFastRow(tFastest,"tNewSrc","2_3"),p.createFastRow(tFastest,"tNewSrc","1_3")}
        }
        local hTableCourses = tableBuilder.new(tCourseRow,"Volunteer Courses Statistics", "width:100%",{"duotable"}) 
 
        for iRow=1,#tCourseRow do
            hTableCourses:setCellHeader(iRow,1,true)
            for i=1,4 do
                if iRow==3 or iRow==6  then
                    hTableCourses:setCellHeader(iRow,i,true)
                end
                hTableCourses:setCellAttr(iRow,i,{["style"]="text-align: center"})
            end
        end
 
        return hTableCourses:getTable()
    end
 
    if (sStat == "getnewbeta") then
        local sCurrDate =os.date('%Y-%m-%d')
        local tNewData = {  [1] ={"P2","Newest Duolingo course(s): ",''},
                            [2] ={"P1","Recently added to the Incubator:",""},
                            [3] ={"P3","Recently graduated from beta:",""}}
        local sTmp =""
        local sPdate, sPrefix, sSuffix 
        local tCurrNew = {}
        local sTotDays = ""
        for i=1,3 do
            sPdate  = tNewData[i][1]
            sPrefix = tNewData[i][2]
            sSuffix = tNewData[i][3]
            tCurrNew = tNewestCourses["recent"][sPdate]
 
            if next(tCurrNew) then
                sTmp =sTmp..sPrefix .."\r\n"
                for i=0,#tCurrNew do
                    if (tCurrNew[i] and tCurrNew[i].date and calcDaysBetween(tCurrNew[i].date,sCurrDate)<8) then
                        if (tCurrNew[i].iDaysTaken and tCurrNew[i].iDaysTaken > 0 and i>1) then
                            sTotDays = '('..tCurrNew[i].date..', Days:'..tCurrNew[i].iDaysTaken..')'
                        end
 
                        sTmp = sTmp.."*"..' '..tCurrNew[i].sDesc..' '.. sSuffix ..sTotDays.."\r\n"
                    end
                end
            end
        end
        return p.preprocess(sTmp)
    end
 
    if (sStat == "yearstats") then
        local hTable = mw.html.create("table"):addClass("duotable"):css("width","100%")
        local year, rowNode
        local currentYear = tonumber(os.date("%Y"))
        local courses = {[currentYear] ={},[currentYear-1] = {}}
        local tmpCourses
 
        hTable:tag("caption"):wikitext("Courses added per year")
        hTable:tag("th"):wikitext("Year")
        hTable:tag("th"):wikitext("Courses")
 
        for courseName,v in pairs(tCourses) do
            year = string.match(tCourses[courseName].P2date,"(%d%d%d%d)-")
            year = tonumber(year)
            if courses[year]  then
                table.insert(courses[year],getFlag(courseName))
            end
        end
 
        for year,courses in pairs(courses) do
            tmpCourses = table.concat(courses, " • ")
            rowNode = mw.html.create("tr")
            rowNode:tag("td")
                :wikitext(year)
                    :css("text-align","center")
            rowNode:tag("td")
                :wikitext(tmpCourses)
                    :css("text-align","center")
            hTable:node(rowNode)
        end
 
        return hTable
    end
end
 
function addReleasedDate(tCourse,iPhase,tAddedOrder,sCourse)
    if (tCourse["P"..iPhase .."date"]) then
        local sPDate = tCourse["P"..iPhase .."date"]
        local sCourse = string.gsub(sCourse,"#","")
        if not(tOrigCourse[sCourse]) then
            if (sPDate) then
                local sYearMon = string.sub(sPDate,1,10) 
                table.insert(tAddedOrder["p"..iPhase],{[sYearMon] = sCourse})
            end
        end
    end
    return tAddedOrder
end
 
function calcAvgReleaseInterval(iPhase,tAddedOrder)
    tAddedOrder = tAddedOrder["p"..iPhase]
 
    if (tAddedOrder[1]) then
        table.sort(tAddedOrder, function(a,b) 
            local sDate,sCourse= next(a); sDate2,sCourse2 =next(b) 
            return sDate < sDate2 
        end)
 
    local sCurrDate = next(tAddedOrder[1])
    local iDays = 0
    local iTotCourses = #(tAddedOrder)
    local nextDate
 
    for i=2,iTotCourses do
        nextDate = next(tAddedOrder[i])
        iDays = iDays + calcDaysBetween(sCurrDate,nextDate)
        sCurrDate = next(tAddedOrder[i])
    end
 
    return  u.round( iDays / iTotCourses)
    end
end
 
function createLangList(tLangList, tLangListdetail, sKey,tGraphVals)
    local sCourse,iCountCourse = "",0
    local Counter_added_lang=0
    local add_v=""
    local start_line="" 
    local sortedLangList = u.spairs(tLangList, function(t,a,b) return t[b] < t[a] end)
 
    for sLangCode,iCourses in sortedLangList do
        iCountCourse = iCountCourse + 1
        table.sort(tLangListdetail[sLangCode], function(a,b) return string.lower(a) < string.lower(b) end)
        add_v='<span title="'..table.concat(tLangListdetail[sLangCode], ", ")..'">('
        if (iCourses<10) then add_v=add_v..'0' end
        add_v=add_v..iCourses..')</span>'
	    if sCourse=="" then
            start_line = ""
            Counter_added_lang=1
	    elseif(Counter_added_lang<10) then
            start_line = "  •  "
            Counter_added_lang=Counter_added_lang+1
	    else
            start_line = "<br/>"
            Counter_added_lang=1
	    end
        sCourse = sCourse..start_line..getFlag(sLangCode)..add_v
 
--      ##For each language to have one color unique in four pie charts.
        local sLang = l.getLang(sLangCode)
        if(not(tGraphVals["from"][sLang])) then tGraphVals["from"][sLang]=0 end
        if(not(tGraphVals["to"][sLang])) then tGraphVals["to"][sLang]=0 end
        if(not(tGraphVals["fromP23"][sLang])) then tGraphVals["fromP23"][sLang]=0 end
        if(not(tGraphVals["toP23"][sLang])) then tGraphVals["toP23"][sLang]=0 end
        if(not(tGraphVals["fromP1"][sLang])) then tGraphVals["fromP1"][sLang]=0 end
        if(not(tGraphVals["toP1"][sLang])) then tGraphVals["toP1"][sLang]=0 end
        tGraphVals[sKey][sLang] = iCourses
    end
    return sCourse,iCountCourse
end
 
--ADD a new languagerow to a Course table
function p.addLangRow(t,tCrow)
    local from, to = t[1], t[2]
    local sKey     = from .. to --→ Original Course
    local sRev = to..from       --→ Reverse Course
    local bIsRev,bHasRev = false,false
 
    tCrow[sKey] = {["from"]=t[1],["to"]=t[2],["web"]=t[3],["android"]=t[4], ["ios"]=t[5],
                   ["P1date"]=p.Date(t[6]),["P2date"]=p.Date(t[7]),["P3date"]=p.Date(t[8]), ["bIsRev"] = bIsRev,
                   ["bHasRev"]= bHasRev, ["bStaff"]=p.isOrigCourse(from,to)}
    local sP1  = tCrow[sKey]["P1date"]
    local sP2  = tCrow[sKey]["P2date"]
    local sP3  = tCrow[sKey]["P3date"]
    local tNewTreeDetails = {["P1date"]=sP1,["P2date"]=sP2,["P3date"]=sP3,["sName"]=from..to}
    local bOldestCourse 
 
    if not(tCourses[to]) and sP2 then 
        tCourses[to] = tNewTreeDetails 
    end
 
    if not(tSrcCourses[from]) and sP2 then 
        tSrcCourses[from] = tNewTreeDetails 
    end
 
    if sP2 and tCourses[to] and tCourses[to]["P2date"] then
       bOldestCourse = u.getdate(tCourses[to]["P2date"]) > u.getdate(sP2)-- Check which tree was created first
       if (bOldestCourse)  then 
          tCourses[to] = tNewTreeDetails
       end
    end
 
    if sP2 and tSrcCourses[from] and tSrcCourses[from]["P2date"] then
       bOldestCourse = u.getdate(tSrcCourses[from]["P2date"]) > u.getdate(sP2)-- Check which tree was created first
       if (bOldestCourse)  then 
          tSrcCourses[from] = tNewTreeDetails
       end
    end
 
    if (tCrow[sRev])   then 
        if (u.checkDate(tCrow[sRev]["P1date"]) and u.checkDate(t[6])) then
            local sDate1 = u.getdate(tCrow[sRev]["P1date"])
            local sDate2 = u.getdate(sP1)
 
            if sDate1 and sDate2 then
                if sDate2 > sDate1 then
                    tCrow[sKey]["bIsRev"] = true       
                else
                    tCrow[sRev]["bIsRev"]= true   
                end
            end
        end
        tCrow[sRev]["bHasRev"] = true  
        tCrow[sKey]["bHasRev"] = true    
    end 
end
 
function p.getNewestCourse(sCourse,tCrow,tNewestCourses,iPhase) 
    local sPhase= "P"..iPhase
    local sDate = "P"..iPhase.."date"
    local s,e  = string.find(sCourse,"#") -- find 
    local sFrom = string.sub(sCourse,1,s-1) -- get L1
    local sTo = string.sub(sCourse,s+1)     -- get L2
    local sCurrDate =os.date('%Y-%m-%d')
 
    if u.getdate(tCrow[sCourse][sDate]) and calcDaysBetween(tCrow[sCourse][sDate],sCurrDate) < 8 then
        local sCourseDesc =  l.getLang(sTo).. ' for '..l.getLang(sFrom).." speakers"
        local sLink = '['..'http://incubator.duolingo.com/courses/'..sTo..'/'..sFrom..'/status '..sCourseDesc..']'
        local sDate1 = "P"..(iPhase).."date"
        if iPhase >1 then
            sDate1 = "P"..(iPhase-1).."date"
        end
        local iTotDays = calcDaysBetween(tCrow[sCourse][sDate1],tCrow[sCourse][sDate])
        if iPhase==1 then
            iTotDays =0
        end
        table.insert(tNewestCourses ["recent"][sPhase],{["date"] = tCrow[sCourse][sDate] , name=sCourse, sDesc = sLink, iDaysTaken =iTotDays })
    end
 
    if u.getdate(tCrow[sCourse][sDate ]) and tCrow[sCourse][sDate] > tNewestCourses ["new"][sPhase]["date"] then
        tNewestCourses ["new"][sPhase] = {["date"] = tCrow[sCourse][sDate], name=sCourse }
    end
end
 
function p.getFastCourse(iPhaseA,iPhaseB,tRows,tFastest)
    local sFrom= tRows["from"]
    local sTo= tRows["to"]
    local sLaunch = tRows["P1date"]
    local bIsOrig = p.isOrigCourse(sFrom,sTo)
    local sFromFlag = getFlag(sFrom)
    local sToFlag =   getFlag(sTo)
    local sPhase = iPhaseA.."_"..iPhaseB
    local sP1  = p.Date(tRows["P"..iPhaseA.."date"])
    local sP2  = p.Date(tRows["P"..iPhaseB.."date"])
    local iDays =calcDaysBetween(sP1,sP2) -- Date1 - Date2
 
    if not(tFastest[sPhase]) then 
        tFastest[sPhase] ={tNewSrc ={["iDays"]=9999},tNew ={["iDays"]=9999}, tAvg={["iDays"] =0,["iCourses"]=0},tOrig={["iDays"] = 9999},tRev={["iDays"] = 9999}}  
    end
 
    if iDays then
        local tDetails ={["sName"]=sFrom..sTo,["iDays"]=u.round(iDays), ["sFlags"] = sFromFlag..""..sToFlag, ["sLaunch"] = sLaunch,[sFrom..sTo] = 1, ["bIsRev"]=tRows["bIsRev"]} 
 
        if not(tRows["bStaff"]) then ---← ←  don't add staff courses    
            local iCalcNewDays = tFastest[sPhase]["tNew"]["iDays"] or 9999
 
            if (tCourses[sTo]["sName"]==sFrom..sTo) and iCalcNewDays > iDays then
                local tOrigLang ={["fr"]=1,["en"]=1,["it"]=1,["pt"]=1,["es"]=1,["de"]=1}
                if not(tOrigLang[sTo]) then
                    tFastest[sPhase]["tNew"]=tDetails
                end
            end
            local iCalcSrcDays = tFastest[sPhase]["tNewSrc"]["iDays"] or 9999
 
            if (tSrcCourses[sFrom]["sName"]==sFrom..sTo) and iCalcSrcDays > iDays then
                local tOrigLang ={["fr"]=1,["en"]=1,["it"]=1,["pt"]=1,["es"]=1,["de"]=1}
                if not(tOrigLang[sFrom]) then
                    tFastest[sPhase]["tNewSrc"]=tDetails
                end
            end
            local iTotDays = calcDaysBetween(sP1,sP2)
 
            if (tFastest[sPhase]["tAvg"] and iTotDays) then 
                local iCDays = tFastest[sPhase]["tAvg"]["iDays"]  + iTotDays
                local iCourses = tFastest[sPhase]["tAvg"]["iCourses"] + 1
                tFastest[sPhase]["tAvg"]["iDays"] =  iCDays
                tFastest[sPhase]["tAvg"]["iCourses"] =  iCourses 
                tFastest[sPhase]["tAvg"]["iAvg"] = u.round(iCDays/ iCourses)
            end
 
            if (tRows["bIsRev"]) then 
                if tFastest[sPhase]["tRev"]["iDays"] > iDays then
                    tFastest[sPhase]["tRev"]= tDetails      
                end
            end
 
            if  not(tRows["bIsRev"]) and tFastest[sPhase]["tOrig"]["iDays"] > iDays then
                tFastest[sPhase]["tOrig"]= tDetails
            end
        end
    end
end
 
function p.addMonthStat(tFastest,sDate,iPhase)
    local sYearMon =""
    if( u.checkDate(sDate) ) then   
        local tTmp = tFastest["Stat"]
        sYearMon = string.sub(sDate,1,7) 
        if not(tFastest["Stat"]) then 
            tFastest["Stat"] = {} tTmp =tFastest["Stat"]   
        end
        if not(tTmp[sYearMon]) then  
            tTmp[sYearMon]={[iPhase]= 0}  
        end
        if not(tTmp[sYearMon][iPhase]) then  
            tTmp[sYearMon][iPhase]= 0  
        end
        tTmp[sYearMon][iPhase] = tTmp[sYearMon][iPhase] + 1
    end
end
 
function p.createFastRow(tFast,sType,sPhases)
    local tOrder = {["1_2"]="",["2_3"]="",["1_3"]=""}
 
    if tFast[sPhases] and tFast[sPhases][sType] and tFast[sPhases][sType]["iDays"] then 
        tOrder[sPhases] =tFast[sPhases][sType]["sFlags"].." ("..tFast[sPhases][sType]["iDays"]..")"
    end
 
    return tOrder[sPhases]
end
 
function p.createBarChart(tPhases )
    local sPhase1,sPhase2,sPhase3,sLegend,sSep="","","","",""
    local sCurrDate =os.date('%Y-%m-%d')
    local sPhaseDate =""
    for sKey,sVal in  u.spairs(tPhases) do
        sPhaseDate = sKey ..'-01'
        if(calcDaysBetween(sCurrDate,sPhaseDate)<180) then 
            sPhase1 = sPhase1..sSep ..(tPhases[sKey][1] or 0)
            sPhase2 = sPhase2..sSep ..(tPhases[sKey][2] or 0)
            sPhase3 = sPhase3..sSep ..(tPhases[sKey][3] or 0)
            sLegend = sLegend..sSep ..sKey
            if sSep == "" then
                sSep = ' : '
            end
        end
    end
    local tChartOptions = {args = {
        ["height"]="300",["width"]="600",
        ["group 1"]=sPhase1,["group 2"]=sPhase2,["group 3"]=sPhase3,
        ["units suffix"] ="_Courses",["x legends"]=sLegend,
        ["colors"]="red : yellow : green",
        ["group names"]="Phase 1 : Phase 2 : Phase 3"}}
    local sChart = chart["bar chart"](tChartOptions)
 
    return sChart
end
 
function p.createPieChart(tSlices, order )
    -- Sort tGraphVals alphabetically with rspect to indexes (which are the language names)
    local tSlicesLOCAL = {}
 
    for sKey,sVal in pairs(tSlices) do
        table.insert(tSlicesLOCAL,{name=sKey, value=sVal})
    end
 
    if(order) then
        table.sort(tSlicesLOCAL,function(a,b) return string.lower(a.name) < string.lower(b.name) end)
    end
    local sSlices = ""
    local k, j, u= 0,0,0
 
    for i=1,#tSlicesLOCAL do
        sSlices = sSlices..'('..tSlicesLOCAL[i].value..':'..tSlicesLOCAL[i].name
        if(i>26) then
            if(k==0) then
                sSlices = sSlices..':#DD'
            elseif(k==1) then
                sSlices = sSlices..':#99'
            elseif(k==2) then
                sSlices = sSlices..':#66'
            elseif(k==3) then
                sSlices = sSlices..':#22'
            end
            if(j<10) then
                sSlices = sSlices..j..j
            elseif(j==10) then
                sSlices = sSlices..'AA'
            elseif(j==11) then
                sSlices = sSlices..'BB'
            elseif(j==12) then
                sSlices = sSlices..'CC'
            elseif(j==13) then
                sSlices = sSlices..'DD'
            elseif(j==14) then
                sSlices = sSlices..'EE'
            elseif(j==15) then
                sSlices = sSlices..'FF'
            end
            if(k==3) then
                k=-1
                j=j+1
            end
            k=k+1
            u=i
            while(u>99)do u=u-100 end
            sSlices = sSlices..u
        end
        sSlices = sSlices .. ')'
    end
    local tChartOptions = {args = {["radius"]="145",["hide group legends"]="true",
        ["slices"]=sSlices,["units suffix"] ="_Courses",["percent"]="true"}}
    local sChart = chart["pie chart"](tChartOptions)
 
    return sChart
end
 
--Adds values in sorted order using a column for comparison
--Params (tTable - Original table, tSortedRows - sorted table,iSortField - column/field to sort (num),order- "asc" or "desc" 
 
function sortedAdd (tTable, tSortedRows,iSortField,order)
    local bAddedFlag = false
 
    local function sortedInsert(i)
        table.insert(tSortedRows,i,tTable)
        bAddedFlag = true
    end 
 
    for i=1,#tSortedRows  do 
        if (tSortedRows[i] and tSortedRows[i][iSortField] and tTable[iSortField]) then
            if  (tSortedRows[i][iSortField] > tTable[iSortField]) and order == "asc" then
                sortedInsert(i)
            break
            elseif (tSortedRows[i] and (tSortedRows[i][iSortField] < tTable[iSortField])) and order == "desc" then
                sortedInsert(i)
            break
            elseif (tSortedRows[i] and (tSortedRows[i][iSortField] == tTable[iSortField]))  then
                if tSortedRows[i][1] > tTable[1] then
                    sortedInsert(i)
                break
                end
            end
        end
    end
 
    if not(bAddedFlag) then 
        table.insert(tSortedRows,tTable)
    end
    return tSortedRows
end
 
function p.flagheader( sLangCode)
    local sLangName = l.getLang(sLangCode)
    local sLangName =string.gsub(sLangName,"(%b())","")
    local sHeader= getFlag(sLangCode,'15x15px')..sLangName
 
    return tableBuilder.createCol(sHeader,{["data-sort-value"]=string.lower(sLangName),["style"]="text-align:left"})
end
 
function p.getFileLink(sFileName,sSize,sLink,sCaption,sAlt)
    local sFileLink = mFileLink.main{	file = sFileName,size = sSize,link = sLink,caption = sCaption,alt=sAlt}
 
    return sFileLink
end
 
function p.frmtdate( sDate1,sRef)
    if not(sDate1) then 
        sDate1 =""
    end
    local frmDate = sDate1
 
    if not(u.checkDate(sDate1)) then
        frmDate='0000-01-01'
    end
 
    local _,_,bEst,z = string.find(sDate1,"(%(%est%.%))")
    local _,_,bBef,z = string.find(sDate1,"(%(%bef%.%))")
 
    if bEst or bBef then 
        sDate1 = p.preprocess("''"..sDate1.."''")  
    end
 
    if (sDate1 =="0000-00-00") then
        sDate1 = "(Pre-incubator)"
    end
    sDate1 = p.preprocess(sDate1 .. ""..sRef)
 
    return tableBuilder.createCol(sDate1,{["style"]="font-size:70%",["data-sort-value"]=string.sub(frmDate,0,10)})
end
 
function p.days( sDate1, sDate2,bOrig,iPhase) 
 
    local iDays,iDaysSORT = 0,0
    local sEstimate, sSuffixEstimate, sSortValue ="", "", ""
 
    if (sDate1) and (sDate2) then 
        if bOrig then
            sSuffixEstimate = p.preprocess("<span title='estimate'>ˠ</span>") 
        end 
    end
    local sDate1LEN, sDate2LEN = 1,1
 
    if (sDate1) then 
        sDate1LEN = math.min(string.len(sDate1),10) 
    end
 
    if (sDate2) then 
        sDate2LEN = math.min(string.len(sDate2),10) 
    end
 
    if not(sDate1) or (sDate1=="") then
        iDaysSORT=0
    else
        if not(sDate2) or (sDate2 =="") then
            sDate2 = os.date('%Y-%m-%d')
            sSuffixEstimate="<span title='Elapsed days (Phase not yet reached)'>*</span>"
            iDaysSORT=999
 
        elseif string.sub(sDate2,1,sDate2LEN)=='2013-05' then
        -- So it's (original) EN<-PT course
            sDate2=p.Date('(2013-05-01)')
        end
 
        if string.sub(sDate1,1,sDate1LEN)=='2011' then
            sDate1=p.Date('(2011-12-01)')
        elseif string.sub(sDate1,1,sDate1LEN)=='2012' then
            sDate1=p.Date('(2012-06-01)')
        end
 
        if string.sub(sDate1,1,sDate1LEN)=='0000-00-00' or string.sub(sDate2,1,sDate2LEN)=='0000-00-00' then
            iDays=""
            sSuffixEstimate = ""
        else 
            iDays = (u.datediff(sDate1,sDate2))
            iDaysSORT=iDaysSORT..iDays
        end
    end
 
    if iDays == 0 then 
        iDays ="" 
        sSuffixEstimate = ""
    end
    local sDateString = iDays..sSuffixEstimate
 
    return tableBuilder.createCol(sDateString,{["data-sort-value"]=iDaysSORT})
end
 
function p.getFastest(tRows,tFastest)
    p.getFastCourse(1,2,tRows,tFastest)
    p.getFastCourse(2,3,tRows,tFastest)
    p.getFastCourse(1,3,tRows,tFastest)
    -- Add monthly chart
    p.addMonthStat(tFastest,tRows["P1date"],1)
    p.addMonthStat(tFastest,tRows["P2date"],2)
    p.addMonthStat(tFastest,tRows["P3date"],3)
    --end
    return tFastest
end
 
function getFlag(sLangCode,sSize)
    local sLangName = l.getLang(sLangCode)
    sSize = sSize  or '20x20px'
    local sHeaderFlagLink = p.getFileLink('Flag-'.. sLangCode..'.png',sSize,sLangName,sLangName,sLangCode)
    return sHeaderFlagLink
end
 
function p.addLang( tLang,sFrom,sTo, iPhase)
    if not(tLang) then 
       return 
    end
 
    local loc_index=0
    local sFromUppered, sToUppered=sFrom,sTo
 
    if(string.len(sFrom)==2) then 
        sFromUppered=string.upper(sFrom) 
    end
 
    if(string.len(sTo)==2) then 
        sToUppered=string.upper(sTo) 
    end
 
    tLang["to"][sTo] = (tLang["to"][sTo] or 0) + 1
    if(tLang["toLIST"][sTo]) then
        tLang["toLIST"][sTo][(#tLang["toLIST"][sTo] or 0)+1]=sFromUppered
    else
        tLang["toLIST"][sTo]={}
        tLang["toLIST"][sTo][1]=sFromUppered
    end
    tLang["from"][sFrom] = (tLang["from"][sFrom] or 0) + 1
 
    if(tLang["fromLIST"][sFrom]) then
        tLang["fromLIST"][sFrom][(#tLang["fromLIST"][sFrom] or 0)+1]=sToUppered
    else
        tLang["fromLIST"][sFrom]={}
        tLang["fromLIST"][sFrom][1]=sToUppered
    end
 
    if (iPhase==1) then
        tLang["toP1"][sTo] = (tLang["toP1"][sTo] or 0) + 1
        if(tLang["toP1LIST"][sTo]) then
            tLang["toP1LIST"][sTo][(#tLang["toP1LIST"][sTo] or 0)+1]=sFromUppered
        else
            tLang["toP1LIST"][sTo]={}
            tLang["toP1LIST"][sTo][1]= sFromUppered
        end
 
        tLang["fromP1"][sFrom] = (tLang["fromP1"][sFrom] or 0) + 1
        if(tLang["fromP1LIST"][sFrom]) then
            tLang["fromP1LIST"][sFrom][(#tLang["fromP1LIST"][sFrom] or 0)+1]=sToUppered
        else
            tLang["fromP1LIST"][sFrom]={}
            tLang["fromP1LIST"][sFrom][1]=sToUppered
        end
    else
        tLang["toP23"][sTo] = (tLang["toP23"][sTo] or 0) + 1
        if(tLang["toP23LIST"][sTo]) then
            tLang["toP23LIST"][sTo][(#tLang["toP23LIST"][sTo] or 0)+1]=sFromUppered
        else
            tLang["toP23LIST"][sTo]={}
            tLang["toP23LIST"][sTo][1]=sFromUppered
        end
 
        tLang["fromP23"][sFrom] = (tLang["fromP23"][sFrom] or 0) + 1
        if(tLang["fromP23LIST"][sFrom]) then
            tLang["fromP23LIST"][sFrom][(#tLang["fromP23LIST"][sFrom] or 0)+1]=sToUppered
        else
            tLang["fromP23LIST"][sFrom]={}
            tLang["fromP23LIST"][sFrom][1]=sToUppered
        end
    end 
    return tLang
end
 
function calcDaysBetween(date1,date2,bNeg)
    local days = nil
    if u.checkDate(date1) and u.checkDate(date2) then 
        days  =  u.datediff(date1,date2,bNeg)
    end 
    return days
end
 
function p.isOrigCourse(from,to)
    local bOrigCourse = (tOrigCourse[from..to]==1)
    return bOrigCourse
end
 
function p.preprocess(sString)
    if (mw.getCurrentFrame()) then 
        return mw.getCurrentFrame():preprocess(sString)
    end
    return sString
end
 
function p.Date(sDate)
    if not(sDate) then 
        return 
    end
    return sDate:match("(%d%d%d%d%-%d%d%-%d%d)")
end
 
return p
--</nowiki>

Interférence d'un bloqueur de publicité détectée !


Wikia est un site gratuit qui compte sur les revenus de la publicité. L'expérience des lecteurs utilisant des bloqueurs de publicité est différente

Wikia n'est pas accessible si vous avez fait d'autres modifications. Supprimez les règles personnalisées de votre bloqueur de publicité, et la page se chargera comme prévu.