This commit is contained in:
Daniel Bulant 2021-10-23 16:19:56 +02:00
parent 1e6f7a7303
commit 0f0e5debef
19 changed files with 592 additions and 1 deletions

View file

@ -10,6 +10,9 @@ luxon.Settings.defaultLocale = "cs";
luxon.Settings.defaultZone = new luxon.IANAZone("Europe/Prague");
const config = yaml.load(fs.readFileSync("./config.yml", { encoding: "utf-8" }));
global.config = config;
require("./utils/sequelize");
const client = new Commando.Client({
owner: '820696421912412191',
@ -17,7 +20,7 @@ const client = new Commando.Client({
presence: {
activity: {
type: "WATCHING",
name: "Prestiž"
name: "prestiž"
}
}
});

View file

@ -5,7 +5,9 @@
"fs-extra": "^10.0.0",
"js-yaml": "^4.1.0",
"luxon": "^2.0.2",
"mariadb": "^2.5.5",
"node-fetch": "2",
"sequelize": "^6.7.0",
"sqlite": "^4.0.23",
"sqlite3": "^5.0.2",
"turndown": "^7.1.1"

View file

@ -141,6 +141,9 @@ class API {
return new Supplementations(res);
}
/**
* @returns {Promise<Schedule>}
*/
async getSchedule(className) {
const res = await request(`wp-content/themes/ssps-wordpress-theme/schedule.php/?class=${className}`);

74
utils/db/import.js Normal file
View file

@ -0,0 +1,74 @@
const isMain = require.main === module;
if(isMain) {
const yaml = require("js-yaml");
const fs = require("fs-extra");
const config = yaml.load(fs.readFileSync("./config.yml", { encoding: "utf-8" }));
global.config = config;
}
const sequelize = require("../sequelize");
const api = require("../api");
const server = require("../ssps-server");
const Class = require("../models/class");
const Group = require("../models/group");
const Subject = require("../models/subject");
const Teacher = require("../models/teacher");
const Room = require("../models/room");
const Timetable = require("../models/timetable");
sequelize.afterBulkSync(async () => {
console.log("Sync in progress");
if(isMain) {
console.log("Syncing timetable");
const classes = Object.values(api.map);
await Promise.all(classes.map(async id => {
const name = api.demap[id];
await Class.create({
id,
year: (2021 - parseInt(name[0]-1)),
type: name[1],
discord: server.reverseRoles[name]
}).catch(console.error);
const timetable = await api.getSchedule(id);
for(const day in timetable.schedule) {
for(let hour in timetable.schedule[day]) {
let lessons = timetable.schedule[day][hour];
if(!Array.isArray(lessons)) lessons = [lessons];
for(const item of lessons) {
await Group.create({
id: item.Group.Id,
abbrev: item.Group.Abbrev,
name: item.Group.Name,
class: id
}).catch(console.error);
await Subject.create({
id: item.Subject.Id,
abrev: item.Subject.Abbrev,
name: item.Subject.Name
}).catch(console.error);
await Teacher.create({
id: item.Teacher.Id,
abbrev: item.Teacher.Abbrev,
name: item.Teacher.Name
});
await Room.create({ id: item.Room.Abbrev });
const cycle = item.Cycles[0].Id === "1" && item.Cycles[1].Id === "2" ? "always" : item.Cycles[0].Id === "1" ? "even" : item.Cycles[0].Id === "2" ? "odd" : null;
await Timetable.create({
day,
hour,
class: id,
group: item.Group.Id,
subject: item.Subject.Id,
teacher: item.Teacher.Id,
room: item.Room.Abbrev,
cycles: cycle
});
console.log("Done", day, hour, item.Subject.Id);
}
}
}
}));
console.log("Sync done");
}
});

33
utils/models/class.js Normal file
View file

@ -0,0 +1,33 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Class = sequelize.define(
"classes",
{
id: {
type: DataTypes.CHAR(2),
allowNull: false,
primaryKey: true
},
year: {
type: DataTypes.INTEGER,
allowNull: false
},
type: {
type: DataTypes.ENUM,
allowNull: false,
values: ["A", "B", "C", "K", "G", "L"]
},
discord: {
type: DataTypes.STRING
},
displayName: {
type: "CHAR(2) GENERATED ALWAYS AS concat(`year` - year(curdate()) + 1,`type`) STORED",
set() {
throw new Error('displayName is read-only')
}
}
}
);
module.exports = Class;

31
utils/models/event.js Normal file
View file

@ -0,0 +1,31 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Event = sequelize.define(
"events",
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
date: {
type: DataTypes.DATE,
defaultValue: "CURRENT_TIMESTAMP()",
allowNull: false
},
type: {
type: DataTypes.ENUM,
values: ["test", "homework", "action"]
},
title: {
type: DataTypes.STRING(255),
allowNull: false
},
description: {
type: DataTypes.TEXT
}
}
);
module.exports = Event;

View file

@ -0,0 +1,36 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Event = require("./event");
const Group = require("./group");
const EventGroup = sequelize.define(
"event_groups",
{
event: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: Event,
key: "id"
}
},
group: {
type: DataTypes.STRING(16),
allowNull: false,
references: {
model: Group,
key: "id"
}
}
},
{
indexes: [{
fields: ["event", "group"],
type: "UNIQUE"
}]
}
);
EventGroup.belongsTo(Event, { as: "event" });
EventGroup.belongsTo(Group, { as: "group" });
module.exports = EventGroup;

View file

@ -0,0 +1,36 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Event = require("./event");
const Student = require("./student");
const EventStudent = sequelize.define(
"event_students",
{
event: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: Event,
key: "id"
}
},
student: {
type: DataTypes.STRING(45),
allowNull: false,
references: {
model: Student,
key: "id"
}
}
},
{
indexes: [{
fields: ["event", "student"],
type: "UNIQUE"
}]
}
);
EventStudent.belongsTo(Event, { as: "event" });
EventStudent.belongsTo(Student, { as: "student" });
module.exports = EventStudent;

29
utils/models/group.js Normal file
View file

@ -0,0 +1,29 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Class = require("./class");
const Group = sequelize.define(
"groups",
{
id: {
type: DataTypes.STRING(16),
primaryKey: true
},
abbrev: {
type: DataTypes.STRING
},
name: {
type: DataTypes.STRING
},
class: {
type: DataTypes.CHAR(2),
references: {
model: Class,
key: "id"
}
}
}
);
Group.belongsTo(Class, { as: "class" });
module.exports = Group;

View file

@ -0,0 +1,36 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Group = require("./group");
const Student = require("./student");
const GroupStudent = sequelize.define(
"group_students",
{
group: {
type: DataTypes.STRING(16),
allowNull: false,
references: {
model: Group,
key: "id"
}
},
student: {
type: DataTypes.STRING(45),
allowNull: false,
references: {
model: Student,
key: "id"
}
}
},
{
indexes: [{
fields: ["group", "student"],
type: "UNIQUE"
}]
}
);
EventStudent.belongsTo(Student, { as: "student" });
EventStudent.belongsTo(Group, { as: "group" });
module.exports = GroupStudent;

42
utils/models/rickroll.js Normal file
View file

@ -0,0 +1,42 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Student = require("./student");
const Rickroll = sequelize.define(
"rickrolls",
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
source: {
type: DataTypes.STRING(45),
allowNull: false,
references: {
key: "id",
model: Student
}
},
target: {
type: DataTypes.STRING(45),
allowNull: false,
references: {
key: "id",
model: Student
}
},
date: {
type: DataTypes.DATE,
defaultValue: "CURRENT_TIMESTAMP()"
},
link: {
type: DataTypes.STRING(255),
defaultValue: "'https://www.youtube.com/watch?v=dQw4w9WgXcQ'"
}
}
);
EventGroup.belongsTo(Student, { as: "source" });
EventGroup.belongsTo(Student, { as: "target" });
module.exports = Rickroll;

14
utils/models/room.js Normal file
View file

@ -0,0 +1,14 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Room = sequelize.define(
"rooms",
{
id: {
type: DataTypes.INTEGER,
primaryKey: true
}
}
);
module.exports = Room;

37
utils/models/student.js Normal file
View file

@ -0,0 +1,37 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Class = require("./class");
const Student = sequelize.define(
"students",
{
id: {
type: DataTypes.STRING(45),
primaryKey: true,
allowNull: false
},
class: {
type: DataTypes.CHAR(2),
allowNull: false,
references: {
model: Class,
key: "id"
}
},
name: {
type: DataTypes.STRING(45),
allowNull: false
},
born: {
type: DataTypes.DATEONLY
},
discord: {
type: DataTypes.BIGINT
},
flags: {
type: DataTypes.INTEGER
}
}
);
module.exports = Student;

25
utils/models/subject.js Normal file
View file

@ -0,0 +1,25 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Subject = sequelize.define(
"subjects",
{
id: {
type: DataTypes.CHAR(3),
primaryKey: true
},
abbrev: {
type: DataTypes.STRING,
},
name: {
type: DataTypes.STRING
}
}, {
indexes: [{
fields: ["abbrev"],
type: "UNIQUE"
}]
}
);
module.exports = Subject;

View file

@ -0,0 +1,69 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Class = require("./class");
const Group = require("./group");
const Room = require("./room");
const Subject = require("./subject");
const Teacher = require("./teacher");
const Supplementation = sequelize.define(
"supplementations",
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
date: {
type: DataTypes.DATEONLY,
allowNull: false
},
class: {
type: DataTypes.CHAR(2),
references: {
model: Class,
key: "id"
}
},
type: {
type: DataTypes.ENUM,
values: ["substitutes", "move-src", "move-target", "join"]
},
hour: {
type: DataTypes.TINYINT
},
subject: {
type: DataTypes.CHAR(3),
references: {
model: Subject,
key: "id"
}
},
group: {
type: DataTypes.STRING(16),
references: {
model: Group,
key: "id"
}
},
room: {
type: DataTypes.INTEGER,
references: {
model: Room,
key: "id"
}
},
teacher: {
type: DataTypes.STRING(16),
references: {
model: Teacher,
key: "abbrev"
}
},
notes: {
type: DataTypes.STRING(255)
}
}
);
module.exports = Supplementation;

25
utils/models/teacher.js Normal file
View file

@ -0,0 +1,25 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Teacher = sequelize.define(
"teachers",
{
id: {
type: DataTypes.STRING(16),
primaryKey: true
},
abbrev: {
type: DataTypes.STRING,
},
name: {
type: DataTypes.STRING
}
}, {
indexes: [{
fields: ["abbrev"],
type: "UNIQUE"
}]
}
);
module.exports = Teacher;

72
utils/models/timetable.js Normal file
View file

@ -0,0 +1,72 @@
const { Sequelize, Op, Model, DataTypes } = require("sequelize");
const sequelize = require("../sequelize");
const Class = require("./class");
const Group = require("./group");
const Room = require("./room");
const Subject = require("./subject");
const Teacher = require("./teacher");
const Timetable = sequelize.define(
"timetable",
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
day: {
type: DataTypes.TINYINT,
allowNull: false
},
hour: {
type: DataTypes.TINYINT,
allowNull: false
},
class: {
type: DataTypes.CHAR(2),
references: {
model: Class,
key: "id"
},
allowNull: false
},
group: {
type: DataTypes.STRING(16),
references: {
model: Group,
key: "id"
},
allowNull: false
},
subject: {
type: DataTypes.CHAR(3),
references: {
model: Subject,
key: "id"
},
allowNull: false
},
teacher: {
type: DataTypes.STRING(16),
references: {
model: Teacher,
key: "id"
},
allowNull: false
},
room: {
type: DataTypes.INTEGER,
references: {
models: Room,
key: "id"
},
allowNull: false
},
cycles: {
type: DataTypes.ENUM,
values: ["always", "odd", "even"]
}
}
);
module.exports = Timetable;

22
utils/sequelize.js Normal file
View file

@ -0,0 +1,22 @@
const { Sequelize } = require("sequelize");
const sequelize = new Sequelize("prestiz", config.user, config.password, {
host: config.host,
dialect: "mariadb",
define: {
freezeTableName: true
}
});
module.exports = sequelize;
require("./models/class");
require("./models/student");
require("./models/room");
require("./models/group");
require("./models/teacher");
require("./models/subject");
require("./models/timetable");
require("./models/rickroll");
require("./models/supplementation");
sequelize.sync();

View file

@ -21,6 +21,7 @@ const roles = {
"887339039533957151": "4C",
"887339044961406996": "4L"
};
const reverseRoles = Object.fromEntries(Object.entries(roles).map(([t1,t2]) => [t2,t1]));
/**
*
@ -38,6 +39,7 @@ const server = "882560404167995443";
module.exports = {
roles,
reverseRoles,
server,
getClass
}