shit
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
const { readFile } = require("node:fs/promises")
|
||||
|
||||
const FILES = [
|
||||
"01.json",
|
||||
"06.json",
|
||||
"10.json"
|
||||
]
|
||||
|
||||
// just some asumption, usually if there's a class in a certain day, the room is open for the entire day
|
||||
const OPEN_TIME = "08:00"
|
||||
const CLOSE_TIME = "17:00"
|
||||
|
||||
const DAY_ORDER = {
|
||||
"Senin": 1,
|
||||
"Selasa": 2,
|
||||
"Rabu": 3,
|
||||
"Kamis": 4,
|
||||
"Jumat": 5,
|
||||
"Sabtu": 6,
|
||||
"Minggu": 7
|
||||
}
|
||||
|
||||
|
||||
async function loadFiles()
|
||||
{
|
||||
const results = await Promise.all(FILES.map(async file =>
|
||||
{
|
||||
const content = await readFile(file, "utf8")
|
||||
const json = JSON.parse(content)
|
||||
|
||||
return json.data
|
||||
}))
|
||||
|
||||
return results.flat()
|
||||
}
|
||||
|
||||
function parseDateRoom(value)
|
||||
{
|
||||
/*
|
||||
* Senin, 10:00-11:40 (A1.51 (Ged Baru))
|
||||
* Selasa, 10.00-11.50 (A6.12 (Ged Baru))
|
||||
*
|
||||
* some entries is malformed (top 1 uni btw)
|
||||
* so why even bother to match the closing ")" lolol
|
||||
*/
|
||||
|
||||
const match = value.match(/^([^,]+),\s*(\d{2}[:.]\d{2})-(\d{2}[:.]\d{2})\s+\((.*)$/)
|
||||
|
||||
if (!match) return null
|
||||
|
||||
const [ , day, rawStart, rawEnd, rawRoom] = match
|
||||
|
||||
const start = rawStart.replace(".", ":")
|
||||
const end = rawEnd.replace(".", ":")
|
||||
|
||||
/*
|
||||
* Remove the outer ')' from normal entries.
|
||||
*
|
||||
* "(A1.51 (Ged Baru))"
|
||||
* ^ remove only the final ')'
|
||||
*
|
||||
* For malformed entries:
|
||||
* "(Lab A1.04+Lab A3.02 - Gabungan (Gd. Baru)"
|
||||
* the final ')' is also removed.
|
||||
*/
|
||||
|
||||
const room = rawRoom.endsWith(")") ? rawRoom.slice(0, -1) : rawRoom
|
||||
|
||||
return { day, start, end, room }
|
||||
}
|
||||
|
||||
|
||||
function timeToMinutes(time)
|
||||
{
|
||||
const [hours, minutes] = time.split(":").map(Number)
|
||||
|
||||
return hours * 60 + minutes
|
||||
}
|
||||
|
||||
|
||||
function buildSchedule(classes)
|
||||
{
|
||||
/*
|
||||
* Map
|
||||
* room
|
||||
* -> day
|
||||
* -> classes
|
||||
*/
|
||||
|
||||
const schedule = new Map()
|
||||
|
||||
for (const classInfo of classes)
|
||||
{
|
||||
if (!Array.isArray(classInfo.dates_rooms))
|
||||
{
|
||||
console.warn(`Skipping ${classInfo.classname}: invalid dates_rooms`)
|
||||
continue
|
||||
}
|
||||
|
||||
for (const dateRoom of classInfo.dates_rooms)
|
||||
{
|
||||
const parsed = parseDateRoom(dateRoom)
|
||||
|
||||
if (!parsed)
|
||||
{
|
||||
console.warn(`Could not parse: ${dateRoom}`)
|
||||
continue
|
||||
}
|
||||
|
||||
const { day, start, end, room } = parsed
|
||||
|
||||
if (!schedule.has(room))
|
||||
{
|
||||
schedule.set(room, new Map())
|
||||
}
|
||||
|
||||
const roomSchedule = schedule.get(room)
|
||||
|
||||
if (!roomSchedule.has(day))
|
||||
{
|
||||
roomSchedule.set(day, [])
|
||||
}
|
||||
|
||||
roomSchedule.get(day).push({
|
||||
start,
|
||||
end,
|
||||
className: classInfo.classname
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return schedule
|
||||
}
|
||||
|
||||
|
||||
function formatSchedule(schedule)
|
||||
{
|
||||
const lines = []
|
||||
|
||||
const rooms = [...schedule.keys()].sort((a, b) => a.localeCompare(b))
|
||||
|
||||
for (const room of rooms)
|
||||
{
|
||||
const roomSchedule = schedule.get(room)
|
||||
|
||||
lines.push(`- ${room} :: ${OPEN_TIME}-${CLOSE_TIME}`)
|
||||
|
||||
const days = [...roomSchedule.keys()].sort((a, b) => DAY_ORDER[a] - DAY_ORDER[b])
|
||||
|
||||
for (const day of days)
|
||||
{
|
||||
const classes = roomSchedule.get(day).sort((a, b) => timeToMinutes(a.start) - timeToMinutes(b.start))
|
||||
|
||||
lines.push(` - ${day}:`)
|
||||
|
||||
for (const classInfo of classes)
|
||||
{
|
||||
lines.push(` - ${classInfo.start} - ${classInfo.end}: ${classInfo.className}`)
|
||||
}
|
||||
}
|
||||
|
||||
lines.push("\n")
|
||||
}
|
||||
|
||||
return lines.join("\n")
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
|
||||
async function main()
|
||||
{
|
||||
const cl = await loadFiles()
|
||||
const sc = buildSchedule(cl)
|
||||
|
||||
console.log(formatSchedule(sc))
|
||||
}
|
||||
|
||||
|
||||
main().catch(error =>
|
||||
{
|
||||
console.error(error)
|
||||
process.exitCode = 1
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user