mirror of
https://github.com/danbulant/ssps-bot
synced 2026-06-16 04:41:16 +00:00
Initial commit
This commit is contained in:
commit
db3f0dbca5
7 changed files with 250 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
node_modules
|
||||
config.yml
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
settings.sqlite
|
||||
64
commands/ssps/rozvrh.js
Normal file
64
commands/ssps/rozvrh.js
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
const commando = require("@iceprod/discord.js-commando");
|
||||
const { MessageEmbed } = require("discord.js");
|
||||
const api = require("../../utils/api");
|
||||
|
||||
/**
|
||||
* @typedef {T extends PromiseLike<infer U> ? U : T} Depromise
|
||||
* @template T
|
||||
*/
|
||||
/** @type {Record<string, Depromise<ReturnType<api["getSchedule"]>>>} */
|
||||
var cache = {};
|
||||
|
||||
var map = {
|
||||
"1K": "1Y"
|
||||
}
|
||||
|
||||
module.exports = class rozvrh extends commando.Command {
|
||||
constructor(client) {
|
||||
super(client, {
|
||||
name: "rozvrh",
|
||||
memberName: "rozvrh",
|
||||
group: "ssps",
|
||||
description: "Zobrazí rozvrh hodin pro danou třídu",
|
||||
args: [{
|
||||
key: "className",
|
||||
type: "string",
|
||||
prompt: "Jakou třídu chcete zvolit?",
|
||||
validate(val) {
|
||||
return /^[1-4]\.?[ABCKGL]$/i.test(val);
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
async run(msg, { className }) {
|
||||
className = className.replace(".", "").toUpperCase();
|
||||
className = map[className];
|
||||
if(!className) return msg.reply("Třída není podporovaná.");
|
||||
if(!cache[className]) {
|
||||
cache[className] = await api.getSchedule(className);
|
||||
}
|
||||
|
||||
const date = new Date;
|
||||
const dayOfWeek = (date.getDay() > 1 && date.getDay() < 6 ? date.getDay() : 1) - 1;
|
||||
const schedule = cache[className].schedule[dayOfWeek];
|
||||
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle("Rozvrh");
|
||||
|
||||
for(const cellI in schedule) {
|
||||
const cell = schedule[cellI];
|
||||
if(!cell) {
|
||||
console.log("Wut?", cellI, cell);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
embed.addField(cell.Subject.Abbrev, `${cell.Room.Abbrev} - ${cell.Teacher.Name}`);
|
||||
} catch(e) {
|
||||
console.warn(e, cellI, cell);
|
||||
}
|
||||
}
|
||||
|
||||
return msg.reply(embed);
|
||||
}
|
||||
};
|
||||
17
commands/ssps/suplovani.js
Normal file
17
commands/ssps/suplovani.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
const commando = require("@iceprod/discord.js-commando");
|
||||
|
||||
module.exports = class suplovani extends commando.Command {
|
||||
constructor(client) {
|
||||
super(client, {
|
||||
name: "suplovani",
|
||||
memberName: "suplovani",
|
||||
group: "ssps",
|
||||
description: "Zobrazí stav suplování",
|
||||
args: []
|
||||
});
|
||||
}
|
||||
|
||||
run(msg) {
|
||||
return msg.reply("TBD");
|
||||
}
|
||||
};
|
||||
38
index.js
Normal file
38
index.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
const Commando = require('@iceprod/discord.js-commando');
|
||||
const sqlite = require('sqlite');
|
||||
const sqlite3 = require("sqlite3");
|
||||
const yaml = require("js-yaml");
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
|
||||
const config = yaml.load(fs.readFileSync("./config.yml", { encoding: "utf-8" }));
|
||||
|
||||
const client = new Commando.Client({
|
||||
owner: '820696421912412191',
|
||||
commandPrefix: "ssps!"
|
||||
});
|
||||
|
||||
client.on("commandError", (c, e) => {
|
||||
console.error(e);
|
||||
});
|
||||
|
||||
client.on("ready", () => {
|
||||
console.log("Ready");
|
||||
});
|
||||
|
||||
client.registry
|
||||
.registerGroups([
|
||||
["ssps", "Příkazy pro SSPŠ"],
|
||||
["nastaveni", "Nastavení bota"]
|
||||
])
|
||||
.registerDefaults()
|
||||
.registerCommandsIn(path.join(__dirname, 'commands'));
|
||||
|
||||
client.setProvider(
|
||||
sqlite.open({
|
||||
driver: sqlite3.Database,
|
||||
filename: path.join(__dirname, 'settings.sqlite3')
|
||||
}).then(db => new Commando.SQLiteProvider(db))
|
||||
).catch(console.error);
|
||||
|
||||
client.login(config.token);
|
||||
11
package.json
Normal file
11
package.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"@iceprod/discord.js-commando": "^0.14.4",
|
||||
"discord.js": "12",
|
||||
"fs-extra": "^10.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"node-fetch": "2",
|
||||
"sqlite": "^4.0.23",
|
||||
"sqlite3": "^5.0.2"
|
||||
}
|
||||
}
|
||||
BIN
settings.sqlite3
Normal file
BIN
settings.sqlite3
Normal file
Binary file not shown.
115
utils/api.js
Normal file
115
utils/api.js
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
const fetch = require("node-fetch");
|
||||
|
||||
async function request(endpoint, body) {
|
||||
const res = await fetch("https://www.ssps.cz/" + endpoint, {
|
||||
method: body ? "POST" : "GET",
|
||||
body,
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
"user-agent": "Discord Bot (https://danbulant.eu Daniel Bulant bulant.da.2021@ssps.cz)",
|
||||
"x-notes": "Zobrazeni informaci o skole v ramci Discordu"
|
||||
}
|
||||
});
|
||||
return await res.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef AbsentClass
|
||||
* @property {ClassEntity} Entity
|
||||
* @property {(null | "ODP")[]} Reasons
|
||||
*/
|
||||
/**
|
||||
* @typedef ClassEntity
|
||||
* @property {string} Id
|
||||
* @property {string} Abbrev
|
||||
*/
|
||||
/**
|
||||
* @typedef ChangedClass
|
||||
* @property {ClassEntity} Class
|
||||
* @property {ChangedLesson[]} ChangedLessons
|
||||
* @property {ChangedLesson[]} CancelledLessons
|
||||
* @property {string[]} ChangedGroups
|
||||
*/
|
||||
/**
|
||||
* @typedef ChangedLesson
|
||||
* @property {"supluje" | "přesun >>" | "přesun <<" | "spojí"} ChgType1
|
||||
* @property {string} ChgType2
|
||||
* @property {string} Hour Číslo ale ve stringu
|
||||
* @property {string} Subject 3 letter code in uppercase
|
||||
* @property {string} Group Empty if all
|
||||
* @property {string} [Room] Room number
|
||||
* @property {string} [Teacher] Teacher code (Abbrev)
|
||||
*/
|
||||
|
||||
class Supplementations {
|
||||
constructor(data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
getByClassName(name) {
|
||||
/** @type {AbsentClass[]} */
|
||||
const absent = this.data.AbsentClasses.filter(t => t.Entity.Abbrev === name);
|
||||
/** @type {ChangedClass[]} */
|
||||
const changed = this.data.ChangesForClasses.filter(t => t.Class.Abbrev === name);
|
||||
return { absent, changed };
|
||||
}
|
||||
|
||||
getByTeacher(abbrev) {
|
||||
return this.data.ChangesForTeachers.filter(t => t.Teacher.Abbrev === abbrev || t.Teacher.Name === abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef Atom
|
||||
* @property {string} Id
|
||||
* @property {string} Abbrev
|
||||
* @property {string} Name
|
||||
*/
|
||||
/**
|
||||
* @typedef CellAtom
|
||||
* @property {Atom} Class
|
||||
* @property {Atom} Group
|
||||
* @property {Atom} Subject
|
||||
* @property {Atom} Teacher
|
||||
* @property {Atom} Room
|
||||
* @property {Atom[]} Cycles
|
||||
* @property {Atom[]} Stamps
|
||||
*/
|
||||
|
||||
class Schedule {
|
||||
/** @type {CellAtom[][]} */
|
||||
schedule = [];
|
||||
constructor(data) {
|
||||
this.data = data;
|
||||
for(var cell of data.Cells) {
|
||||
if(!this.schedule[cell.DayIndex]) this.schedule[cell.DayIndex] = [];
|
||||
this.schedule[cell.DayIndex][cell.HourIndex] = cell.Atoms;
|
||||
}
|
||||
}
|
||||
|
||||
get type() {
|
||||
return this.data.Type;
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this.data.TargetId;
|
||||
}
|
||||
}
|
||||
|
||||
class API {
|
||||
request = request;
|
||||
|
||||
async getSupplementations(date = new Date) {
|
||||
const res = await request(`wp-content/themes/ssps-wordpress-theme/supplementation.php/?date=${date.getFullYear()}${date.getMonth().toString().padStart(2, "0")}${date.getDate().toString().padStart(2, "0")}`);
|
||||
|
||||
return new Supplementations(res);
|
||||
}
|
||||
|
||||
async getSchedule(className) {
|
||||
const res = await request(`wp-content/themes/ssps-wordpress-theme/schedule.php/?class=${className}`);
|
||||
|
||||
return new Schedule(res);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new API;
|
||||
Loading…
Reference in a new issue