BryghtShadow (talk | contribs) m (we already made a sort key in SQL, use that.) |
BryghtShadow (talk | contribs) ([ST] Split each course into its own section) |
||
Line 74: | Line 74: | ||
for i, row in ipairs(rows) do |
for i, row in ipairs(rows) do |
||
if row['F_MaterialCost'] then |
if row['F_MaterialCost'] then |
||
− | string.gsub(row['F_MaterialCost'], '<br/><br/>', '<br/>') |
+ | row['F_MaterialCost'] = string.gsub(row['F_MaterialCost'], '<br/><br/>', '<br/>') |
end |
end |
||
Line 100: | Line 100: | ||
} |
} |
||
end |
end |
||
+ | -- Group by courses |
||
− | local |
+ | local courses = {} |
for k, v in pairs(t1) do |
for k, v in pairs(t1) do |
||
+ | local course_class = mw.text.split(v.class, '-', true) |
||
− | t2[#t2+1] = v |
||
+ | local course = tonumber(course_class[1]) |
||
+ | local class = tonumber(course_class[2]) |
||
+ | courses[course] = courses[course] or { |
||
+ | id = course, |
||
+ | classes = {}, |
||
+ | } |
||
+ | courses[course].classes[class] = courses[course].classes[class] or v |
||
end |
end |
||
− | table.sort(t2, function(a, b) return a.sortKey < b.sortKey end) |
+ | -- table.sort(t2, function(a, b) return a.sortKey < b.sortKey end) |
⚫ | |||
+ | |||
⚫ | |||
+ | h.printCourse(root, courseData) |
||
+ | end |
||
⚫ | |||
+ | end |
||
+ | |||
+ | function h.printCourse(root, courseData) |
||
+ | root:tag('h2'):wikitext('Course '..courseData.id) |
||
+ | local tbl = root:tag('table'):addClass('wikitable') |
||
local headers = { |
local headers = { |
||
'Course Name', |
'Course Name', |
||
Line 115: | Line 134: | ||
'How to Unlock', |
'How to Unlock', |
||
} |
} |
||
⚫ | |||
− | |||
+ | for i, classData in ipairs(courseData.classes) do |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
end |
end |
||
⚫ | |||
end |
end |
||
− | function h.printHeaders( |
+ | function h.printHeaders(tbl, headers) |
− | local tr = |
+ | local tr = tbl:tag('tr') |
for i, txt in ipairs(headers) do |
for i, txt in ipairs(headers) do |
||
tr:tag('th'):wikitext(txt) |
tr:tag('th'):wikitext(txt) |
||
Line 131: | Line 147: | ||
end |
end |
||
− | function h.printClass( |
+ | function h.printClass(tbl, data) |
local rowspan = #data.furnitures |
local rowspan = #data.furnitures |
||
for i, furniture in ipairs(data.furnitures) do |
for i, furniture in ipairs(data.furnitures) do |
||
− | local tr = |
+ | local tr = tbl:tag('tr') |
local td |
local td |
||
if i == 1 then |
if i == 1 then |
Revision as of 07:15, 13 February 2021
Documentation for this module may be created at Module:Happy Homeroom Normal Courses Table/doc
-- TODO: Use a module!
local cargo = {}
function cargo.query(args)
for k, v in ipairs({'tables', 'fields', 'join'}) do
if type(args[v]) == 'table' then
args[v] = table.concat(args[v], ',')
end
end
if type(args.where) == 'table' then
local t = {}
for i, v in pairs(args.where) do
t[#t+1] = '('..v..')'
end
args.where = table.concat(t, ' AND ')
end
args.limit = args.limit or 5000
local rows = mw.ext.cargo.query(
args.tables,
args.fields,
args
)
for i, row in ipairs(rows) do
for k, v in pairs(row) do
if v == '' then
row[k] = nil
end
end
end
return rows
end
local p = {}
local h = {}
local LANG = mw.getContentLanguage()
function p.main(frame)
local rows = cargo.query{
tables = {
'Class=C','Class__FurnReqAll=CFRA','Entities=E',
'Furniture=F1',
'Clothing=F2',
},
join = {
'C._ID=CFRA._rowID','CFRA._value=E.Name',
'E.Name=F1.Name',
'E.Name=F2.Name',
},
fields = {
'C._pageName=C_PAGENAME',
'C.Image=C_Image',
'C.Name=C_Name',
'C.Class=C_Class',
'C.NumFurnReq=C_NumFurnReq',
'E.EntityType=EntityType',
'CFRA._position=F_position',
'COALESCE(F1._pageName,F2._pageName)=F_PAGENAME',
'COALESCE(F1.Name, F2.Name)=F_Name',
'COALESCE(F1.Image, F2.Image)=F_Image',
'COALESCE(F1.MaterialCost, F2.MaterialCost)=F_MaterialCost',
'COALESCE(F1.NumBells, F2.NumBells)=F_NumBells',
'COALESCE(F1.CraftTimeSec, F2.CraftTimeSec)=F_CraftTimeSec',
'COALESCE(F1.UnlockReq, F2.UnlockReq)=F_UnlockReq',
'COALESCE(F1.Obtain, F2.Obtain)=F_Obtain',
'SUBSTRING(CONCAT("0", Class), -4, 4)=ClassCourseSortKey',
},
where = {
'C.type="Normal"',
'(C.Class LIKE "%-%")',
},
orderBy = 'ClassCourseSortKey',
}
local t1 = {}
for i, row in ipairs(rows) do
if row['F_MaterialCost'] then
row['F_MaterialCost'] = string.gsub(row['F_MaterialCost'], '<br/><br/>', '<br/>')
end
local classKey = row['C_Class']
t1[classKey] = t1[classKey] or {
pagename = row['C_PAGENAME'],
image = row['C_Image'],
name = row['C_Name'],
class = row['C_Class'],
sortKey = row['ClassCourseSortKey'],
numFurnReq = row['C_NumFurnReq'],
furnitures = {},
}
local furnitures = t1[classKey].furnitures
local furnitureKey = tonumber(row['F_position'])
furnitures[furnitureKey] = furnitures[furnitureKey] or {
pagename = row['F_PAGENAME'],
name = row['F_Name'] or row['F_PAGENAME'],
image = row['F_Image'],
materialCost = row['F_MaterialCost'],
numBells = row['F_NumBells'],
craftTimeSec = row['F_CraftTimeSec'],
unlockReq = row['F_UnlockReq'],
obtain = row['F_Obtain'],
}
end
-- Group by courses
local courses = {}
for k, v in pairs(t1) do
local course_class = mw.text.split(v.class, '-', true)
local course = tonumber(course_class[1])
local class = tonumber(course_class[2])
courses[course] = courses[course] or {
id = course,
classes = {},
}
courses[course].classes[class] = courses[course].classes[class] or v
end
-- table.sort(t2, function(a, b) return a.sortKey < b.sortKey end)
local root = mw.html.create()
for _, courseData in ipairs(courses) do
h.printCourse(root, courseData)
end
return tostring(root)
end
function h.printCourse(root, courseData)
root:tag('h2'):wikitext('Course '..courseData.id)
local tbl = root:tag('table'):addClass('wikitable')
local headers = {
'Course Name',
'Class',
'On-Point Item',
'Material Cost',
'Bell Cost',
'Craft Time',
'How to Unlock',
}
h.printHeaders(tbl, headers)
for i, classData in ipairs(courseData.classes) do
h.printClass(tbl, classData)
end
end
function h.printHeaders(tbl, headers)
local tr = tbl:tag('tr')
for i, txt in ipairs(headers) do
tr:tag('th'):wikitext(txt)
end
end
function h.printClass(tbl, data)
local rowspan = #data.furnitures
for i, furniture in ipairs(data.furnitures) do
local tr = tbl:tag('tr')
local td
if i == 1 then
local classIcon = string.format(
'[[File:%s.png|60px|alt=%s|link=%s]]<br>[[%s%s]]',
data.image,
data.name,
data.pagename,
data.pagename,
data.pagename ~= data.name and '|'..data.name or ''
)
tr:css('border-top', '2px solid #c1b695')
tr:tag('td')
:attr('rowspan', rowspan)
:css('text-align', 'center')
:wikitext(classIcon)
tr:tag('td')
:attr('rowspan', rowspan)
:attr('data-sort-value', data.sortKey)
:wikitext(data.class)
end
local furnitureIcon = string.format(
'[[File:%s.png|24px|alt=%s|link=]] %s',
furniture.image or '???',
furniture.name,
furniture.name
)
tr:tag('td'):wikitext(furnitureIcon)
if furniture.materialCost == 'N/A' or not furniture.numBells then
tr:tag('td'):attr('colspan', 4):wikitext(furniture.obtain)
else
tr:tag('td'):wikitext(furniture.materialCost)
tr:tag('td'):wikitext(h.bells(furniture.numBells))
tr:tag('td'):wikitext(h.duration(furniture.craftTimeSec) or '-')
tr:tag('td'):wikitext(furniture.unlockReq)
end
end
end
function h.bells(n)
return ('%s [[File:Bells.png|24px|Bells|alt=Bells|link=]]'):format(n)
end
function h.duration(seconds)
local seconds = tonumber(seconds)
if not seconds then return end
local hh = math.floor(seconds / 60 / 60)
local mm = math.floor(seconds / 60 % 60)
local ss = (seconds % 60)
local t = {}
if hh > 0 then
t[#t+1] = LANG:plural(hh, '%d hour', '%d hours'):format(hh)
end
if mm > 0 then
t[#t+1] = LANG:plural(mm, '%d minute', '%d minutes'):format(mm)
end
if hh == 0 and mm == 0 or ss > 0 then
t[#t+1] = LANG:plural(ss, '%d second', '%d seconds'):format(ss)
end
return table.concat(t, ' ')
end
return p