Files
Timetable-V2/server/api/index.js
2022-08-21 00:53:24 +02:00

190 lines
5.3 KiB
JavaScript

import Prisma from "@prisma/client";
const prisma = new Prisma.PrismaClient();
// Get timetable API endpoint (/api/timetable)
// Returns timetable data for requested class if available
export async function getTimetable(req, res) {
if (!req.query.class) {
res.status(400).send({
success: false,
error: "missing_parameter",
message: "No class parameter provided",
});
return;
}
const requestedClass = req.query.class.toLowerCase();
const timetable = await prisma.timetable.findFirst({
where: {
class: requestedClass,
},
orderBy: {
updatedAt: "desc",
},
});
if (!timetable) {
res.status(400).send({
success: false,
error: "no_timetable",
message: "No timetable was found for this class",
});
return;
}
res.send({
trusted: timetable.trusted,
source: timetable.source,
data: timetable.data,
});
}
// Helper function for converting a date string
// (eg. "2022-06-02" or "1654128000000") to a
// unix timestamp
function convertToDate(dateQuery) {
var date;
if (dateQuery.match(/^[0-9]+$/) != null) date = parseInt(dateQuery);
else date = dateQuery;
date = new Date(date).setUTCHours(0, 0, 0, 0);
return date;
}
// Get substitutions API endpoint (/api/substitutions)
// Returns all known substitutions for requested date / class
// If no class is supplied, all substitutions are returned
export async function getSubstitutions(req, res) {
const requestedClass = (req.query.class || "").toLowerCase();
var from, to, date;
// Check if from or to date is set in request
if (req.query.from && req.query.to) {
from = convertToDate(req.query.from);
to = convertToDate(req.query.to);
} else if (req.query.date) {
date = convertToDate(req.query.date);
}
const prismaOptions = {
where: {
removed: false,
},
orderBy: {
lesson: "asc",
},
};
if (requestedClass) {
prismaOptions.where.class = { has: requestedClass };
}
// Choose which date to use in database query
if (from && to) {
prismaOptions.where.date = {
gte: new Date(from),
lte: new Date(to),
};
} else if (date) {
prismaOptions.where.date = new Date(date);
} else {
// Default to all substitutions for today and in the future
prismaOptions.where.date = {
gte: new Date(new Date().setUTCHours(0, 0, 0, 0)),
};
}
const rawSubstitutions = await prisma.substitution.findMany(prismaOptions);
const substitutions = rawSubstitutions.map((element) => {
const substitution = {
id: element.id,
class: element.class,
type: element.type,
lesson: element.lesson,
date: new Date(element.date).getTime(),
notes: element.notes,
teacher: element.teacher,
change: {},
};
if (element.changedRoom) substitution.change.room = element.changedRoom;
if (element.changedTeacher)
substitution.change.teacher = element.changedTeacher;
if (element.changedSubject)
substitution.change.subject = element.changedSubject;
return substitution;
});
res.send(substitutions);
}
// Get history API endpoint (/api/history)
// Returns history of changes for all substituions in the date range
// for the requested class if supplied
export async function getHistory(req, res) {
const requestedClass = (req.query.class || "").toLowerCase();
var from, to, date;
// Check if from or to date is set in request
if (req.query.from && req.query.to) {
from = convertToDate(req.query.from);
to = convertToDate(req.query.to);
} else if (req.query.date) {
date = convertToDate(req.query.date);
}
const prismaOptions = {
where: {
substitution: {},
},
include: {
substitution: true,
},
orderBy: {
createdAt: "desc",
},
};
if (requestedClass) {
prismaOptions.where.substitution.class = { has: requestedClass };
}
// Choose which date to use in database query
if (from && to) {
prismaOptions.where.substitution.date = {
gte: new Date(from),
lte: new Date(to),
};
} else if (date) {
prismaOptions.where.substitution.date = new Date(date);
} else {
// Default to history of all substitutions for today and in the future
prismaOptions.where.substitution.date = {
gte: new Date(new Date().setUTCHours(0, 0, 0, 0)),
};
}
const rawChanges = await prisma.substitutionChange.findMany(prismaOptions);
const changes = rawChanges.map((element) => {
return {
id: element.id,
type: element.type,
substitutionId: element.substitutionId,
lesson: element.substitution.lesson,
updatedAt: new Date(element.createdAt).getTime(),
date: new Date(element.substitution.date).getTime(),
teacher: element.teacher,
change: element.changes,
notes: element.notes,
parseEventId: element.parseEventId,
};
});
res.send(changes);
}
// Get classes API endpoints (/api/classes)
// Get all available classes where timetable and
// substitutions can be requested for
export async function getClasses(req, res) {
const classes = await prisma.class.findMany({
select: {
name: true,
regex: false,
},
orderBy: {
name: "asc",
},
});
// Only return the name of the class
const classList = classes.map((element) => element.name);
res.send(classList);
}