Skip to content

Commit 7ca6063

Browse files
committed
Migrate schedule.json to TOML
This helps readability and maintainability considerably. Some changes have been made to the frontend to work with native JavaScript Date objects instead of numbers.
1 parent fea11c8 commit 7ca6063

File tree

7 files changed

+384
-371
lines changed

7 files changed

+384
-371
lines changed

build-lite.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const readline = require("readline");
66
const util = require("util");
77
const exec = util.promisify(require("child_process").exec);
88
const marked = require("marked");
9+
const TOML = require("@iarna/toml");
910

1011
const dep_mappings = require('./frontend-dependencies');
1112

@@ -127,6 +128,13 @@ async function processJS(file) {
127128
await out.write(JSON.stringify(changelog) + "\n");
128129
continue;
129130
}
131+
if (line === "//#include SCHEDULE") {
132+
const schedule = TOML.parse(
133+
await fsp.readFile(__dirname + '/public/schedule.toml')
134+
);
135+
await out.write(JSON.stringify(schedule) + "\n");
136+
continue;
137+
}
130138
// All other include directives
131139
let match;
132140
if ((match = line.match(/^\/\/#include (.*)/))) {

package-lock.json

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
},
3131
"dependencies": {
3232
"@fortawesome/fontawesome-free": "^5.15.2",
33+
"@iarna/toml": "^3.0.0",
3334
"animate.css": "^4.1.1",
3435
"body-parser": "^1.19.0",
3536
"commander": "^6.2.1",

public/js/clock.js

Lines changed: 52 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@ let date_override = undefined;
2929

3030
function schedulesCallback(response) {
3131
schedules = response;
32+
// Convert all start and end times to JavaScript Date objects
33+
for (const [, schedule] of Object.entries(schedules)) {
34+
for (entry of schedule) {
35+
// Convert each entry to a JavaScript Date object
36+
let [, hours, minutes, seconds, ms]
37+
= /(\d+):(\d+):(\d+)\.(\d+)/.exec(entry.start);
38+
entry.start = new Date(2000, 0, 1, hours, minutes, seconds, ms);
39+
[, hours, minutes, seconds, ms]
40+
= /(\d+):(\d+):(\d+)\.(\d+)/.exec(entry.end);
41+
entry.end = new Date(2000, 0, 1, hours, minutes, seconds, ms);
42+
}
43+
}
3244

3345
let last_interval = 0;
3446
const redraw_clock_with_timestamp = timestamp => {
@@ -43,16 +55,6 @@ function schedulesCallback(response) {
4355
redraw_clock_with_timestamp();
4456
}
4557

46-
// Takes a time from schedule.json and formats it as a string
47-
function formatTime(time) {
48-
const hours = Math.floor(time / 1000 / 60 / 60);
49-
const minutes = time / 1000 / 60 % 60;
50-
return new Date(2000, 1, 1, hours, minutes).toLocaleTimeString([], {
51-
hour: "numeric",
52-
minute: "numeric",
53-
});
54-
}
55-
5658
function update_formattedSchedule() {
5759
if (selected_day_of_week < 0) {
5860
const now = date_override ? new Date(date_override) : new Date();
@@ -74,9 +76,16 @@ function update_formattedSchedule() {
7476
}
7577
}
7678

77-
let time = formatTime(start);
78-
if (name !== "After School")
79-
time += "–" + formatTime(end);
79+
let timeString = start.toLocaleTimeString([], {
80+
hour: "numeric",
81+
minute: "numeric",
82+
});
83+
if (name !== "After School") {
84+
timeString += "–" + end.toLocaleTimeString([], {
85+
hour: "numeric",
86+
minute: "numeric",
87+
});
88+
}
8089

8190
// The index (1 to 8) of the color to use for this class
8291
const color_number = i < 8 ? i + 1 : 8;
@@ -90,7 +99,7 @@ function update_formattedSchedule() {
9099
return {
91100
period: name,
92101
room: room,
93-
time: time,
102+
time: timeString,
94103
class: class_name,
95104
color: color,
96105
};
@@ -106,7 +115,7 @@ $.ajax({
106115
//#ifdef lite
107116
/*
108117
schedulesCallback(
109-
//#include public/schedule.json
118+
//#include SCHEDULE
110119
);
111120
*/
112121
//#endif
@@ -129,33 +138,23 @@ function drawFace(ctx, radius) {
129138
ctx.drawImage(logo, -radius, -radius, 2 * radius, 2 * radius);
130139
}
131140

132-
function drawNumber(ctx, radius, pos, number) {
141+
function drawTime(ctx, radius, pos, time) {
133142
ctx.fillStyle = 'white';
134143
ctx.textBaseline = "middle";
135144
ctx.textAlign = "center";
136145
ctx.font = "85px arial";
137-
// Get time in seconds
138-
let time = number / 1000;
139-
// Get first and second digit
140-
141-
// hours
142-
let d1 = Math.floor(time / 60 / 60);
143-
// minutes
144-
let d2 = Math.floor(time / 60 % 60);
145-
// seconds
146-
let d3 = Math.floor(time % 60);
147-
148-
if(d1 < 10) {
149-
d1 = `0${d1}`;
150-
}
151-
if(d2 < 10) {
152-
d2 = `0${d2}`;
153-
}
154-
if(d3 < 10) {
155-
d3 = `0${d3}`;
156-
}
157146

158-
ctx.fillText(`${d1}:${d2}:${d3}`, 0, 0);
147+
// Use 12-hour time without AM/PM
148+
const hours = String.prototype.padStart.call(
149+
time.getHours() % 12, 2, "0"
150+
);
151+
const minutes = String.prototype.padStart.call(
152+
time.getMinutes(), 2, "0"
153+
);
154+
const seconds = String.prototype.padStart.call(
155+
time.getSeconds(), 2, "0"
156+
);
157+
ctx.fillText(`${hours}:${minutes}:${seconds}`, 0, 0);
159158
}
160159

161160
function drawName(name) {
@@ -297,13 +296,12 @@ function redraw_clock() {
297296
}
298297
// Fake call to get_period_name to set current_schedule
299298
get_period_name("Period 1", day_of_week);
300-
let number = 0;
299+
// Time to show on clock
300+
let time = new Date(2000, 0, 1, 0, 0, 0, 0);
301301
let period_name = "";
302302
// Time of day
303-
const tod = now.getHours() * 60 * 60 * 1000
304-
+ now.getMinutes() * 60 * 1000
305-
+ now.getSeconds() * 1000
306-
+ now.getMilliseconds();
303+
const tod = new Date(2000, 0, 1, now.getHours(), now.getMinutes(),
304+
now.getSeconds(), now.getMilliseconds());
307305
let pos;
308306
if (![0, 6].includes(now.getDay())) {
309307
// School day
@@ -321,30 +319,26 @@ function redraw_clock() {
321319
// Realtime
322320
period_name = "";
323321
pos = tod % (12 * 60 * 60 * 1000) / (12 * 60 * 60 * 1000);
324-
number = tod % (12 * 60 * 60 * 1000);
325-
if (number < 1 * 60 * 60 * 1000) {
326-
number += 12 * 60 * 60 * 1000;
327-
}
328-
}
329-
else if (tod > current_period.end) { // Between classes
322+
time = tod;
323+
} else if (tod > current_period.end) { // Between classes
330324
period_name = get_period_name(current_period.name, day_of_week) +
331325
" ➡ " + get_period_name(next_period.name, day_of_week);
332326
pos = (tod - current_period.end) / (next_period.start - current_period.end);
333-
number = next_period.start - tod;
334-
}
335-
else { // In class
327+
time = new Date(
328+
time.getTime() + next_period.start.getTime() - tod.getTime()
329+
);
330+
} else { // In class
336331
period_name = get_period_name(current_period.name, day_of_week);
337332
pos = (tod - current_period.start) / (current_period.end - current_period.start);
338-
number = current_period.end - tod;
333+
time = new Date(
334+
time.getTime() + current_period.end.getTime() - tod.getTime()
335+
);
339336
}
340337
} else {
341338
// Realtime
342339
period_name = "";
343340
pos = tod % (12 * 60 * 60 * 1000) / (12 * 60 * 60 * 1000);
344-
number = tod % (12 * 60 * 60 * 1000);
345-
if(number < 1 * 60 * 60 * 1000) {
346-
number += 12 * 60 * 60 * 1000;
347-
}
341+
time = tod;
348342
}
349343

350344
// conver 0-1 to 0-2pi
@@ -353,10 +347,10 @@ function redraw_clock() {
353347
drawFace(small_ctx, small_radius);
354348
drawName(period_name);
355349
drawHand(small_ctx, small_radius, pos, small_radius * .94, small_radius * .095);
356-
drawNumber(small_ctx, small_radius, pos, number);
350+
drawTime(small_ctx, small_radius, pos, time);
357351

358352
drawFace(large_ctx, large_radius);
359353
drawName(period_name);
360354
drawHand(large_ctx, large_radius, pos, large_radius * .94, large_radius * .095);
361-
drawNumber(large_ctx, large_radius, pos, number);
355+
drawTime(large_ctx, large_radius, pos, time);
362356
}

0 commit comments

Comments
 (0)