Skip to content
Snippets Groups Projects
Unverified Commit 63335482 authored by Maxime FRIESS's avatar Maxime FRIESS :blue_heart:
Browse files

[commands/menu] Added others university restaurents

parent afe7ad45
No related merge requests found
Pipeline #87442 failed with stage
......@@ -19,6 +19,7 @@
import { Api } from '../base/Api';
import { SoftConfig } from '../config/SoftConfig';
import { Cache } from '../utils/Cache';
class CrousApiManager extends Api {
constructor() {
......@@ -26,8 +27,19 @@ class CrousApiManager extends Api {
SoftConfig.registerConfig('crous.menu.url');
}
async menu() {
return await this.request('GET', SoftConfig.get('crous.menu.url', ''));
async load_menu(region: number, restaurant: number) {
return await this.request('GET', `https://webservices-v2.crous-mobile.fr:8443/ws/v1/regions/${region}/restaurants/${restaurant}/menus/`);
}
async menu(region: number, restaurant: number) {
return await Cache.cache(`crous.menu.${region}.${restaurant}`, 3600, async () => {
const menu = await this.load_menu(region, restaurant);
if (!menu.good) {
Promise.reject();
} else {
return menu.data;
}
});
}
}
......
......@@ -18,7 +18,7 @@
*/
import { APIApplicationCommandOption, ApplicationCommandOptionType } from 'discord-api-types/v9';
import { ButtonInteraction, CommandInteraction, InteractionReplyOptions, MessageActionRow, MessageButton, MessageEmbed } from 'discord.js';
import { ButtonInteraction, CommandInteraction, InteractionReplyOptions, MessageActionRow, MessageButton, MessageEmbed, MessageSelectMenu, SelectMenuInteraction } from 'discord.js';
import moment from 'moment';
import { CrousApi } from '../api/CrousApi';
import { Command } from '../base/Command';
......@@ -26,15 +26,18 @@ import { Bot } from '../Bot';
import { SoftConfig } from '../config/SoftConfig';
import { Cache } from '../utils/Cache';
import { I18n } from '../utils/I18n';
import { RU } from '../utils/RU';
import { StringUtils } from '../utils/String';
const DATE_FORMAT = 'DD/MM/YYYY';
const DEFAULT_RU = "25,1392";
type FilterValues = 'ETU' | 'PER' | 'ALL';
export class MenuCommand extends Command {
constructor() {
super();
Bot.registerButton('menu_date', this.buttonDate.bind(this));
Bot.registerSelect('menu_switch', this.selectRestaurent.bind(this))
}
getName() {
......@@ -47,9 +50,9 @@ export class MenuCommand extends Command {
type: ApplicationCommandOptionType.String,
...I18n.argumentI18n(this, "group"),
choices: [
{ ...I18n.choiceI18n(this, "group", "professor"), value: "PERS"},
{ ...I18n.choiceI18n(this, "group", "student"), value: "ETU"},
{ ...I18n.choiceI18n(this, "group", "all"), value: "ALL"},
{ ...I18n.choiceI18n(this, "group", "professor"), value: "PERS" },
{ ...I18n.choiceI18n(this, "group", "student"), value: "ETU" },
{ ...I18n.choiceI18n(this, "group", "all"), value: "ALL" },
],
required: false,
},
......@@ -58,38 +61,57 @@ export class MenuCommand extends Command {
...I18n.argumentI18n(this, "date"),
required: false,
},
{
type: ApplicationCommandOptionType.String,
...I18n.argumentI18n(this, "restaurent"),
choices: RU.getRUArguments(),
required: false,
}
];
}
async buttonDate(interaction: ButtonInteraction) {
const [,d,f] = interaction.customId.split(',');
const [, d, f, re, ra] = interaction.customId.split(',');
const date = moment(d, DATE_FORMAT).toDate();
const filter = f as FilterValues;
await interaction.deferUpdate();
await interaction.editReply(await this.getMessageContent(date, filter, interaction.locale));
await interaction.editReply(await this.getMessageContent(date, filter, parseInt(re), parseInt(ra), interaction.locale));
}
async selectRestaurent(interaction: SelectMenuInteraction) {
const [, d, f] = interaction.customId.split(",");
const [region, restaurant] = interaction.values[0].split(",").map(x => parseInt(x));
const date = moment(d, DATE_FORMAT).toDate();
const filter = f as FilterValues;
await interaction.deferUpdate();
await interaction.editReply(await this.getMessageContent(date, filter, region, restaurant, interaction.locale));
}
async execute(interaction: CommandInteraction) {
const date = interaction.options.getString('date') === null ? new Date() : moment(interaction.options.getString('date'), DATE_FORMAT).toDate();
let filter = (interaction.options.getString('groupe') ?? 'ETU') as FilterValues;
const [region, restaurent] = (interaction.options.getString('restaurent') ?? DEFAULT_RU).split(',').map(x => parseInt(x));
if (isNaN(date.getTime())) {
await interaction.reply({ content: I18n.getI18n("bot.error.date", interaction.locale), ephemeral: true });
return;
}
await interaction.deferReply();
await interaction.editReply(await this.getMessageContent(date, filter, interaction.locale));
await interaction.editReply(await this.getMessageContent(date, filter, region, restaurent, interaction.locale));
}
async getMessageContent(date: Date, filter: FilterValues, lang: string): Promise<InteractionReplyOptions> {
const menu = (await Cache.cache('crous.menu', 3600, () => CrousApi.menu())).data;
async getMessageContent(date: Date, filter: FilterValues, region: number, restaurant: number, lang: string): Promise<InteractionReplyOptions> {
const menu = await CrousApi.menu(region, restaurant);
const row = new MessageActionRow().addComponents(
new MessageButton().setCustomId(`menu_date,${moment(date).subtract(1, 'd').format(DATE_FORMAT)},${filter}`).setLabel(I18n.getI18n("command.menu.reply.day.previous", lang)).setStyle('PRIMARY'),
new MessageButton().setCustomId(`menu_date,${moment(date).add(1, 'd').format(DATE_FORMAT)},${filter}`).setLabel(I18n.getI18n("command.menu.reply.day.next", lang)).setStyle('PRIMARY')
);
const rows = [new MessageActionRow().addComponents(
new MessageSelectMenu().setCustomId(`menu_switch,${moment(date).format(DATE_FORMAT)},${filter}`).setOptions(RU.getRUSelect(region, restaurant))
), new MessageActionRow().addComponents(
new MessageButton().setCustomId(`menu_date,${moment(date).subtract(1, 'd').format(DATE_FORMAT)},${filter},${region},${restaurant}`).setLabel(I18n.getI18n("command.menu.reply.day.previous", lang)).setStyle('PRIMARY'),
new MessageButton().setCustomId(`menu_date,${moment(date).add(1, 'd').format(DATE_FORMAT)},${filter},${region},${restaurant}`).setLabel(I18n.getI18n("command.menu.reply.day.next", lang)).setStyle('PRIMARY')
)];
for (const m of menu) {
if (moment(m.date).isSame(date, 'day')) {
......@@ -97,20 +119,22 @@ export class MenuCommand extends Command {
if (meal.name == 'midi') {
const embed = new MessageEmbed().setColor(SoftConfig.get('bot.color', '#fb963a')).setTimestamp(Cache.modified_date('crous.menu'));
for (const cat of meal.foodcategory.sort(this.__sortfunc)) {
if (cat.name.includes(filter))
// Filter is only needed for restaurent 1392 (Illkirch)
// TODO: Clean this a bit.
if (cat.name.includes(filter) || restaurant !== 1392)
embed.addField(
StringUtils.capitalize(cat.name),
cat.dishes.filter((x: any) => x.name !== "").map((x: { name: string }) => '> ' + StringUtils.capitalize(x.name)).join('\n'),
false
);
}
return { embeds: [embed], content: I18n.formatI18n("command.menu.reply.title", lang, {filter, date: moment(date).format(DATE_FORMAT)}), components: [row] };
return { embeds: [embed], content: I18n.formatI18n("command.menu.reply.title", lang, { filter, date: moment(date).format(DATE_FORMAT) }), components: rows };
}
}
return { content: I18n.formatI18n("command.menu.reply.error", lang, {filter, date: moment(date).format(DATE_FORMAT)}), components: [row], embeds: [] };
return { content: I18n.formatI18n("command.menu.reply.error", lang, { filter, date: moment(date).format(DATE_FORMAT) }), components: rows, embeds: [] };
}
}
return { content: I18n.formatI18n("command.menu.reply.error", lang, {filter, date: moment(date).format(DATE_FORMAT)}), components: [row], embeds: [] };
return { content: I18n.formatI18n("command.menu.reply.error", lang, { filter, date: moment(date).format(DATE_FORMAT) }), components: rows, embeds: [] };
}
__sortfunc(a: { name: string }, b: { name: string }) {
......
......@@ -51,10 +51,12 @@ command.menu.description,Récupère le menu du RU.,Get the menu of the Universit
command.menu.option.group.name,groupe,group
command.menu.option.group.description,Groupe,Group
command.menu.option.group.professor.name,Professeurs,Professors
command.menu.option.group.qtudent.name,Étudiants,Students
command.menu.option.group.student.name,Étudiants,Students
command.menu.option.group.all.name,Tous,All
command.menu.option.date.name,date,date
command.menu.option.date.description,Date (JJ/MM/AAAA),Date (DD/MM/YYYY)
command.menu.option.restaurent.name,restaurent,restaurent
command.menu.option.restaurent.description,Restaurent Universitaire,University Restaurent
command.menu.reply.day.next,Jour suivant,Next day
command.menu.reply.day.previous,Jour précédent,Previous day
command.menu.reply.title,Menu {filter} du {date},{filter} menu for the {date}
......
/**
* Copyright © 2022 Maxime Friess <M4x1me@pm.me>
*
* This file is part of Seb-BOT.
*
* Seb-BOT is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Seb-BOT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Seb-BOT. If not, see <https://www.gnu.org/licenses/>.
*/
class RUManager {
private ru;
constructor() {
this.ru = [
{ name: "Illkirch", value: "25,1392" },
{ name: "Paul Appell", value: "25,1386" },
{ name: "Galia", value: "25,1382" },
{ name: "Esplanade", value: "25,1387" },
{ name: "Cronenbourg", value: "25,1391" },
];
}
public getRUArguments() {
return this.ru;
}
public getRUSelect(region: number, restaurent: number) {
return this.ru.map((x) => ({
label: x.name,
value: x.value,
default: x.value === `${region},${restaurent}`
}))
}
}
export const RU = new RUManager();
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment