Browse Source

style: prevent ESLint from clashing with Prettier

dependabot/npm_and_yarn/semver-5.7.2
Abheek Dhawan 2 years ago
parent
commit
196f0dc6f1
Signed by: abheekd GPG Key ID: 7BE81B8C14475B67
  1. 28
      .eslintrc.json
  2. 3
      .prettierrc
  3. 36
      src/commands/about.ts
  4. 12
      src/commands/help.ts
  5. 80
      src/commands/rounds.ts
  6. 26
      src/commands/score.ts
  7. 170
      src/commands/settings.ts
  8. 26
      src/commands/top.ts
  9. 194
      src/commands/train.ts
  10. 10
      src/events/interactionCreate.ts
  11. 20
      src/events/messageCreate.ts
  12. 14
      src/events/ready.ts
  13. 22
      src/helpers/db.ts
  14. 10
      src/helpers/env.ts
  15. 16
      src/helpers/log.ts
  16. 42
      src/helpers/util/pagination.ts
  17. 24
      src/index.ts
  18. 4
      src/models/generatedRound.ts
  19. 4
      src/models/userConfig.ts
  20. 4
      src/models/userScore.ts

28
.eslintrc.json

@ -21,33 +21,17 @@
"after": true
}
],
"brace-style": [
"error",
"stroustrup",
{
"allowSingleLine": true
}
],
"comma-dangle": [
"error",
"always-multiline"
],
"comma-spacing": "error",
"comma-style": "error",
"curly": [
"error",
"multi-line",
"consistent"
],
"dot-location": [
"error",
"property"
],
"handle-callback-err": "off",
"indent": [
"error",
"tab"
],
"keyword-spacing": "error",
"max-nested-callbacks": [
"error",
@ -93,23 +77,11 @@
"always"
],
"prefer-const": "error",
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
],
"space-before-blocks": "error",
"space-before-function-paren": [
"error",
{
"anonymous": "never",
"named": "never",
"asyncArrow": "always"
}
],
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",

3
.prettierrc

@ -1,6 +1,7 @@
{
"singleQuote": false,
"singleQuote": true,
"semi": true,
"useTabs": true,
"endOfLine": "lf",
"trailingComma": "es5"
}

36
src/commands/about.ts

@ -1,15 +1,15 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import { MessageEmbed, CommandInteraction } from "discord.js";
import { SlashCommandBuilder } from '@discordjs/builders';
import { MessageEmbed, CommandInteraction } from 'discord.js';
import gitlog from "gitlog";
import gitlog from 'gitlog';
import userScore from "../models/userScore";
import userScore from '../models/userScore';
import { paginateInteraction } from "../helpers/util/pagination";
import { paginateInteraction } from '../helpers/util/pagination';
export const data = new SlashCommandBuilder()
.setName("about")
.setDescription("Commands regarding the creation/development of the bot");
.setName('about')
.setDescription('Commands regarding the creation/development of the bot');
export async function execute(interaction: CommandInteraction) {
await interaction.deferReply();
@ -18,15 +18,15 @@ export async function execute(interaction: CommandInteraction) {
const embeds: MessageEmbed[] = [];
const contributorEmbed = new MessageEmbed()
.setTitle("Contributors")
.addField("Creator", "<@745063586422063214> [ADawesomeguy#3602]", true)
.setTitle('Contributors')
.addField('Creator', '<@745063586422063214> [ADawesomeguy#3602]', true)
.addField(
"Contributors",
"<@650525101048987649> [tEjAs#8127]\n<@426864344463048705> [tetrident#9396]",
'Contributors',
'<@650525101048987649> [tEjAs#8127]\n<@426864344463048705> [tetrident#9396]',
true
) // Add more contributors here, first one is Abheek, second one is Tejas
.setTimestamp()
.setColor("#ffffff");
.setColor('#ffffff');
embeds.push(contributorEmbed);
const gitRepoLocation = __dirname;
@ -34,7 +34,7 @@ export async function execute(interaction: CommandInteraction) {
const commits = gitlog({
repo: gitRepoLocation,
number: 5,
fields: ["hash", "abbrevHash", "subject", "authorName", "authorDateRel"],
fields: ['hash', 'abbrevHash', 'subject', 'authorName', 'authorDateRel'],
});
const changelogEmbed = new MessageEmbed()
@ -42,8 +42,8 @@ export async function execute(interaction: CommandInteraction) {
name: interaction.user.tag,
iconURL: interaction.user.displayAvatarURL(),
})
.setTitle("Changelog")
.setColor("#ffffff")
.setTitle('Changelog')
.setColor('#ffffff')
.setTimestamp();
commits.forEach((commit) => {
@ -61,9 +61,9 @@ export async function execute(interaction: CommandInteraction) {
name: interaction.user.tag,
iconURL: interaction.user.displayAvatarURL(),
})
.setTitle("About AwesomeSciBo")
.addField("Servers", `${client.guilds.cache.size}`, true)
.addField("Training Users", `${trainingDocuments}`, true)
.setTitle('About AwesomeSciBo')
.addField('Servers', `${client.guilds.cache.size}`, true)
.addField('Training Users', `${trainingDocuments}`, true)
.setTimestamp();
embeds.push(aboutBotEmbed);

12
src/commands/help.ts

@ -1,9 +1,9 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import { MessageEmbed, CommandInteraction } from "discord.js";
import { SlashCommandBuilder } from '@discordjs/builders';
import { MessageEmbed, CommandInteraction } from 'discord.js';
export const data = new SlashCommandBuilder()
.setName("help")
.setDescription("Replies with a help message explaining what the bot can do");
.setName('help')
.setDescription('Replies with a help message explaining what the bot can do');
export async function execute(interaction: CommandInteraction) {
await interaction.deferReply();
@ -11,8 +11,8 @@ export async function execute(interaction: CommandInteraction) {
const helpEmbed = new MessageEmbed()
.setDescription(
"AwesomeSciBo has migrated to using slash commands! You can take a look at the different commands by typing `/` and clicking on the AwesomeSciBo icon."
'AwesomeSciBo has migrated to using slash commands! You can take a look at the different commands by typing `/` and clicking on the AwesomeSciBo icon.'
)
.setColor("#ffffff");
.setColor('#ffffff');
interaction.followUp({ embeds: [helpEmbed] });
}

80
src/commands/rounds.ts

@ -1,33 +1,33 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import { MessageEmbed, CommandInteraction } from "discord.js";
import { SlashCommandBuilder } from '@discordjs/builders';
import { MessageEmbed, CommandInteraction } from 'discord.js';
import axios from "axios";
import axios from 'axios';
import log from "../helpers/log";
import generatedRound from "../models/generatedRound";
import log from '../helpers/log';
import generatedRound from '../models/generatedRound';
export const data = new SlashCommandBuilder()
.setName("rounds")
.setDescription("Commands regarding the generation of rounds")
.setName('rounds')
.setDescription('Commands regarding the generation of rounds')
.addSubcommand((subcommand) => {
subcommand
.setName("generate")
.setName('generate')
.setDescription(
"Generates a round with randomized questions from https://scibowldb.com/"
'Generates a round with randomized questions from https://scibowldb.com/'
);
return subcommand;
})
.addSubcommand((subcommand) => {
subcommand
.setName("list")
.setDescription("Lists your 5 most recently generated rounds with links");
.setName('list')
.setDescription('Lists your 5 most recently generated rounds with links');
return subcommand;
})
.addSubcommand((subcommand) => {
subcommand
.setName("hit")
.setName('hit')
.setDescription(
"Shows the total number of rounds hit as well as the number for the specific user"
'Shows the total number of rounds hit as well as the number for the specific user'
);
return subcommand;
});
@ -35,7 +35,7 @@ export const data = new SlashCommandBuilder()
export async function execute(interaction: CommandInteraction) {
const action = interaction.options.getSubcommand();
switch (action) {
case "generate": {
case 'generate': {
interaction.deferReply({ ephemeral: true });
let finalizedHTML =
@ -47,16 +47,16 @@ export async function execute(interaction: CommandInteraction) {
let bonus_question: string;
let bonus_format: string;
let bonus_answer: string;
let htmlContent = "";
let htmlContent = '';
await axios
.post("https://scibowldb.com/api/questions", {
.post('https://scibowldb.com/api/questions', {
categories: [
"BIOLOGY",
"PHYSICS",
"CHEMISTRY",
"EARTH AND SPACE",
"ASTRONOMY",
"MATH",
'BIOLOGY',
'PHYSICS',
'CHEMISTRY',
'EARTH AND SPACE',
'ASTRONOMY',
'MATH',
],
})
.then((response) => {
@ -75,26 +75,26 @@ export async function execute(interaction: CommandInteraction) {
htmlContent =
"<br><br><h3 style='text-align: center;'><strong>TOSS-UP</strong></h3>\n<br>" +
`${i}) <strong>${question_category}</strong>` +
" " +
' ' +
`<em>${tossup_format}</em>` +
" " +
' ' +
tossup_question +
"<br><br>" +
"<strong>ANSWER:</strong> " +
'<br><br>' +
'<strong>ANSWER:</strong> ' +
tossup_answer +
"<br>";
'<br>';
htmlContent +=
"<br><br><h3 style='text-align: center;'><strong>BONUS</strong></h3>\n<br>" +
`${i}) <strong>${question_category}</strong>` +
" " +
' ' +
`<em>${bonus_format}</em>` +
" " +
' ' +
bonus_question +
"<br><br>" +
"<strong>ANSWER:</strong> " +
'<br><br>' +
'<strong>ANSWER:</strong> ' +
bonus_answer +
"<br><br><hr><br>";
htmlContent = htmlContent.replace(/\n/g, "<br>");
'<br><br><hr><br>';
htmlContent = htmlContent.replace(/\n/g, '<br>');
finalizedHTML += htmlContent;
}
@ -108,9 +108,9 @@ export async function execute(interaction: CommandInteraction) {
newGeneratedRound.save((err, round) => {
if (err) {
log({
logger: "rounds",
logger: 'rounds',
content: `Saving round to DB failed: ${err}`,
level: "error",
level: 'error',
});
return;
}
@ -123,13 +123,13 @@ export async function execute(interaction: CommandInteraction) {
break;
}
case "list": {
case 'list': {
interaction.deferReply({ ephemeral: true });
let roundsList = await generatedRound
.find({ requestedBy: interaction.user.id })
.sort({ timestamp: -1 });
let finalMessage = "";
let finalMessage = '';
if (!roundsList) {
interaction.followUp("You haven't requested any rounds!");
return;
@ -141,7 +141,7 @@ export async function execute(interaction: CommandInteraction) {
roundsList.forEach(async (item, index) => {
finalMessage += `${index + 1}. [${
item.timestamp.split("T")[0]
item.timestamp.split('T')[0]
}](https://api.adawesome.tech/round/${item._id.toString()})\n`;
});
@ -150,7 +150,7 @@ export async function execute(interaction: CommandInteraction) {
name: interaction.user.tag,
iconURL: interaction.user.displayAvatarURL(),
})
.setTitle("Last 5 rounds requested")
.setTitle('Last 5 rounds requested')
.setDescription(finalMessage)
.setTimestamp();
@ -161,7 +161,7 @@ export async function execute(interaction: CommandInteraction) {
break;
}
case "hit": {
case 'hit': {
await interaction.deferReply();
const totalCount = await generatedRound.countDocuments({});

26
src/commands/score.ts

@ -1,38 +1,38 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction, MessageEmbed } from "discord.js";
import { SlashCommandBuilder } from '@discordjs/builders';
import { CommandInteraction, MessageEmbed } from 'discord.js';
import log from "../helpers/log";
import userScore from "../models/userScore";
import log from '../helpers/log';
import userScore from '../models/userScore';
export const data = new SlashCommandBuilder()
.setName("score")
.setDescription("Returns the score of the current user or another")
.setName('score')
.setDescription('Returns the score of the current user or another')
.addUserOption((option) => {
option
.setName("user")
.setDescription("The user to find the score for")
.setName('user')
.setDescription('The user to find the score for')
.setRequired(false);
return option;
});
export async function execute(interaction: CommandInteraction) {
const scoreEmbed = new MessageEmbed().setColor("#ffffff");
const scoreEmbed = new MessageEmbed().setColor('#ffffff');
const user = interaction.options.getUser("user") || interaction.user;
const user = interaction.options.getUser('user') || interaction.user;
userScore.findOne({ authorID: user.id }, async (err, score) => {
if (err) {
log({
logger: "db",
logger: 'db',
content: `Unable to obtain user: ${err}`,
level: "info",
level: 'info',
});
}
if (!score) {
await interaction.reply({
content:
"Unfortunately, that user does not seem to have used AwesomeSciBo yet.",
'Unfortunately, that user does not seem to have used AwesomeSciBo yet.',
ephemeral: true,
});
return;

170
src/commands/settings.ts

@ -1,53 +1,53 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import { Message, MessageActionRow, MessageSelectMenu } from "discord.js";
import { CommandInteraction, MessageEmbed } from "discord.js";
import log from "../helpers/log";
import userConfig from "../models/userConfig";
import { SlashCommandBuilder } from '@discordjs/builders';
import { Message, MessageActionRow, MessageSelectMenu } from 'discord.js';
import { CommandInteraction, MessageEmbed } from 'discord.js';
import log from '../helpers/log';
import userConfig from '../models/userConfig';
export const data = new SlashCommandBuilder()
.setName("settings")
.setDescription("BETA - settings configuration")
.setName('settings')
.setDescription('BETA - settings configuration')
.addSubcommand((subcommand) => {
subcommand.setName("subject").setDescription("Changes subject of problems");
subcommand.setName('subject').setDescription('Changes subject of problems');
return subcommand;
})
.addSubcommand((subcommand) => {
subcommand.setName("display").setDescription("Displays current settings");
subcommand.setName('display').setDescription('Displays current settings');
return subcommand;
})
.addSubcommand((subcommand) => {
subcommand
.setName("gradelevels")
.setDescription("Changes grade level of problems");
.setName('gradelevels')
.setDescription('Changes grade level of problems');
return subcommand;
});
export async function execute(interaction: CommandInteraction) {
const action = interaction.options.getSubcommand();
switch (action) {
case "display": {
case 'display': {
await interaction.deferReply();
const settingsEmbed = new MessageEmbed().setColor("#ffffff");
const settingsEmbed = new MessageEmbed().setColor('#ffffff');
const user = interaction.options.getUser("user") || interaction.user;
const user = interaction.options.getUser('user') || interaction.user;
settingsEmbed
.setAuthor({ name: user.tag, iconURL: user.displayAvatarURL() })
.setDescription("Current selections: ");
.setDescription('Current selections: ');
const menu = new MessageActionRow().addComponents(
new MessageSelectMenu()
.setCustomId("selectdisp")
.setPlaceholder("Nothing selected")
.setCustomId('selectdisp')
.setPlaceholder('Nothing selected')
.addOptions([
{
label: "subjects",
description: "subjects",
value: "subjects",
label: 'subjects',
description: 'subjects',
value: 'subjects',
},
{
label: "gradelevels",
description: "grade levels",
value: "gradelevels",
label: 'gradelevels',
description: 'grade levels',
value: 'gradelevels',
},
])
);
@ -62,11 +62,11 @@ export async function execute(interaction: CommandInteraction) {
.then((dispMsg) => {
const w = dispMsg as Message;
const dispFilter = (i) =>
["selectdisp"].includes(i.customId) &&
['selectdisp'].includes(i.customId) &&
i.user.id == interaction.user.id; // <== ATTENTION! First argument...
w.awaitMessageComponent({
filter: dispFilter,
componentType: "SELECT_MENU",
componentType: 'SELECT_MENU',
}).then(async (dispChoice) => {
const vals = dispChoice.values;
const config = await userConfig.findById(interaction.user.id);
@ -76,20 +76,20 @@ export async function execute(interaction: CommandInteraction) {
embeds: [],
components: [],
});
} else if (vals.length === 1 && vals.at(0) === "subjects") {
} else if (vals.length === 1 && vals.at(0) === 'subjects') {
await interaction.editReply({
content: `Current subjects setting: ${config.subjects
.toString()
.split(",")
.join(", ")}`,
.split(',')
.join(', ')}`,
components: [],
});
} else if (vals.length === 1 && vals.at(0) === "gradelevels") {
} else if (vals.length === 1 && vals.at(0) === 'gradelevels') {
await interaction.editReply({
content: `Current grade level setting: ${config.gradeLevels
.toString()
.split(",")
.join(", ")}`,
.split(',')
.join(', ')}`,
components: [],
});
} else {
@ -98,39 +98,39 @@ export async function execute(interaction: CommandInteraction) {
logger:
"'Error occurred: /settings:display did not equal subjects or gradelevels.'",
content: `${err}`,
level: "error",
level: 'error',
});
}
});
});
break;
}
case "gradelevels": {
case 'gradelevels': {
await interaction.deferReply();
const settingsEmbed = new MessageEmbed().setColor("#ffffff");
const settingsEmbed = new MessageEmbed().setColor('#ffffff');
const user = interaction.options.getUser("user") || interaction.user;
const user = interaction.options.getUser('user') || interaction.user;
settingsEmbed
.setAuthor({ name: user.tag, iconURL: user.displayAvatarURL() })
.setDescription("Current level settings: ");
.setDescription('Current level settings: ');
const menu = new MessageActionRow().addComponents(
new MessageSelectMenu()
.setCustomId("selectlvl")
.setPlaceholder("Nothing selected")
.setCustomId('selectlvl')
.setPlaceholder('Nothing selected')
.setMinValues(1)
.setMaxValues(2)
.addOptions([
{
label: "Middle School",
description: "Middle school level problems",
value: "MS",
label: 'Middle School',
description: 'Middle school level problems',
value: 'MS',
},
{
label: "High School",
description: "High school level problems",
value: "HS",
label: 'High School',
description: 'High school level problems',
value: 'HS',
},
])
);
@ -145,11 +145,11 @@ export async function execute(interaction: CommandInteraction) {
.then((lvlMsg) => {
const w = lvlMsg as Message;
const lvlFilter = (i) =>
["selectlvl"].includes(i.customId) &&
['selectlvl'].includes(i.customId) &&
i.user.id == interaction.user.id; // <== ATTENTION! First argument...
w.awaitMessageComponent({
filter: lvlFilter,
componentType: "SELECT_MENU",
componentType: 'SELECT_MENU',
}).then(async (lvlChoice) => {
const vals = lvlChoice.values;
const levels = new Array<string>();
@ -163,18 +163,18 @@ export async function execute(interaction: CommandInteraction) {
);
await vals.forEach((v) => {
switch (v) {
case "MS":
levels.push("Middle School");
case 'MS':
levels.push('Middle School');
break;
case "HS":
levels.push("High School");
case 'HS':
levels.push('High School');
}
});
await interaction.editReply({
content: `Level set to: ${levels
.toString()
.split(",")
.join(", ")}`,
.split(',')
.join(', ')}`,
embeds: [],
components: [],
});
@ -182,57 +182,57 @@ export async function execute(interaction: CommandInteraction) {
});
break;
}
case "subject": {
case 'subject': {
await interaction.deferReply();
const settingsEmbed = new MessageEmbed().setColor("#ffffff");
const settingsEmbed = new MessageEmbed().setColor('#ffffff');
const user = interaction.options.getUser("user") || interaction.user;
const user = interaction.options.getUser('user') || interaction.user;
settingsEmbed
.setAuthor({ name: user.tag, iconURL: user.displayAvatarURL() })
.setDescription("Current subject settings: ");
.setDescription('Current subject settings: ');
const menu = new MessageActionRow().addComponents(
new MessageSelectMenu()
.setCustomId("selectsubject")
.setPlaceholder("Nothing selected")
.setCustomId('selectsubject')
.setPlaceholder('Nothing selected')
.setMinValues(1)
.setMaxValues(7)
.addOptions([
{
label: "Astronomy",
description: "Astronomy",
value: "ASTRONOMY",
label: 'Astronomy',
description: 'Astronomy',
value: 'ASTRONOMY',
},
{
label: "Biology",
description: "Biology",
value: "BIOLOGY",
label: 'Biology',
description: 'Biology',
value: 'BIOLOGY',
},
{
label: "Earth Science",
description: "Earth Science",
value: "EARTH SCIENCE",
label: 'Earth Science',
description: 'Earth Science',
value: 'EARTH SCIENCE',
},
{
label: "Chemistry",
description: "Chemistry",
value: "CHEMISTRY",
label: 'Chemistry',
description: 'Chemistry',
value: 'CHEMISTRY',
},
{
label: "Physics",
description: "Physics",
value: "PHYSICS",
label: 'Physics',
description: 'Physics',
value: 'PHYSICS',
},
{
label: "Mathematics",
description: "Mathematics",
value: "MATH",
label: 'Mathematics',
description: 'Mathematics',
value: 'MATH',
},
{
label: "Energy",
description: "Energy",
value: "ENERGY",
label: 'Energy',
description: 'Energy',
value: 'ENERGY',
},
])
);
@ -246,12 +246,12 @@ export async function execute(interaction: CommandInteraction) {
})
.then((subjectMsg) => {
const subjectFilter = (i) =>
["selectsubject"].includes(i.customId) &&
['selectsubject'].includes(i.customId) &&
i.user.id == interaction.user.id; // <== ATTENTION! First argument...
(subjectMsg as Message)
.awaitMessageComponent({
filter: subjectFilter,
componentType: "SELECT_MENU",
componentType: 'SELECT_MENU',
})
.then(async (subjectChoice) => {
const vals = subjectChoice.values;
@ -268,16 +268,16 @@ export async function execute(interaction: CommandInteraction) {
subjects.push(
v
.toLowerCase()
.split(" ")
.split(' ')
.map((w) => w[0].toUpperCase() + w.substring(1))
.join(" ")
.join(' ')
);
});
await interaction.editReply({
content: `Subjects set to: ${subjects
.toString()
.split(",")
.join(", ")}`,
.split(',')
.join(', ')}`,
components: [],
embeds: [],
});

26
src/commands/top.ts

@ -1,13 +1,13 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction, MessageEmbed } from "discord.js";
import { SlashCommandBuilder } from '@discordjs/builders';
import { CommandInteraction, MessageEmbed } from 'discord.js';
import log from "../helpers/log";
import userScore from "../models/userScore";
import log from '../helpers/log';
import userScore from '../models/userScore';
export const data = new SlashCommandBuilder()
.setName("top")
.setName('top')
.setDescription(
"Lists top ten scores across servers and in the current server"
'Lists top ten scores across servers and in the current server'
);
export async function execute(interaction: CommandInteraction) {
@ -19,9 +19,9 @@ export async function execute(interaction: CommandInteraction) {
.exec(async (err, obj) => {
if (err) {
log({
logger: "top",
logger: 'top',
content: `Getting top players failed: ${err}`,
level: "error",
level: 'error',
});
console.log(err);
}
@ -34,7 +34,7 @@ export async function execute(interaction: CommandInteraction) {
}
const embeds: MessageEmbed[] = [];
let lbMessageContent = "";
let lbMessageContent = '';
for (let i = 0; i < 10; i++) {
lbMessageContent += `${i + 1}: <@${obj[i].authorID}>: ${
@ -43,13 +43,13 @@ export async function execute(interaction: CommandInteraction) {
}
const leaderboardEmbed = new MessageEmbed()
.setTitle("Top Ten!")
.setTitle('Top Ten!')
.setDescription(lbMessageContent)
.setColor("#ffffff");
.setColor('#ffffff');
embeds.push(leaderboardEmbed);
let sMessageContent = "";
let sMessageContent = '';
const members = await interaction.guild?.members.fetch();
const serverLeaderBoardArray = await obj.filter((o) =>
@ -65,7 +65,7 @@ export async function execute(interaction: CommandInteraction) {
const sLeaderboardEmbed = new MessageEmbed()
.setTitle(`Top Ten in ${interaction.guild?.name}!`)
.setDescription(sMessageContent)
.setColor("#ffffff");
.setColor('#ffffff');
embeds.push(sLeaderboardEmbed);
}

194
src/commands/train.ts

@ -1,37 +1,37 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import { SlashCommandBuilder } from '@discordjs/builders';
import {
MessageEmbed,
MessageActionRow,
MessageButton,
CommandInteraction,
Message,
} from "discord.js";
} from 'discord.js';
import { decode } from "html-entities";
import axios from "axios";
import { decode } from 'html-entities';
import axios from 'axios';
import userScore from "../models/userScore";
import userConfig from "../models/userConfig";
import userScore from '../models/userScore';
import userConfig from '../models/userConfig';
import log from "../helpers/log.js";
import { updateScore } from "../helpers/db.js";
import log from '../helpers/log.js';
import { updateScore } from '../helpers/db.js';
export const data = new SlashCommandBuilder()
.setName("train")
.setDescription("Sends a training question to be answered")
.setName('train')
.setDescription('Sends a training question to be answered')
.addStringOption((option) => {
option
.setName("subject")
.setDescription("Optional subject to be used as a filter")
.setName('subject')
.setDescription('Optional subject to be used as a filter')
.setRequired(false)
.addChoices(
{ name: "astro", value: "astro" },
{ name: "bio", value: "bio" },
{ name: "chem", value: "chem" },
{ name: "ess", value: "ess" },
{ name: "phys", value: "phys" },
{ name: "math", value: "math" },
{ name: "energy", value: "energy" }
{ name: 'astro', value: 'astro' },
{ name: 'bio', value: 'bio' },
{ name: 'chem', value: 'chem' },
{ name: 'ess', value: 'ess' },
{ name: 'phys', value: 'phys' },
{ name: 'math', value: 'math' },
{ name: 'energy', value: 'energy' }
)
.setRequired(false);
return option;
@ -40,8 +40,8 @@ export const data = new SlashCommandBuilder()
export async function execute(interaction: CommandInteraction) {
await interaction.deferReply();
const subject = interaction.options.get("subject")
? interaction.options.get("subject")?.value
const subject = interaction.options.get('subject')
? interaction.options.get('subject')?.value
: null;
const authorId = interaction.user.id;
let score: number;
@ -55,43 +55,43 @@ export async function execute(interaction: CommandInteraction) {
.setAuthor({
name: interaction.client.user?.tag
? interaction.client.user?.tag
: "",
: '',
iconURL: interaction.client.user?.displayAvatarURL(),
})
.setDescription(
"Hey! It seems like it's your first time using AwesomeSciBo. Here's some information regarding the bot if you need it (for issues, contributions, etc.):"
)
.addField("Creator", "<@745063586422063214> [@abheekd#3602]")
.addField('Creator', '<@745063586422063214> [@abheekd#3602]')
.addField(
"GitHub",
'GitHub',
"[Link](https://github.com/ADawesomeguy/AwesomeSciBo) (a star couldn't hurt...)"
)
.setColor("#ffffff")
.setColor('#ffffff')
.setTimestamp();
interaction.user
.send({ embeds: [firstTimeEmbed] })
.catch((err) =>
log({ logger: "train", content: `${err}`, level: "error" })
log({ logger: 'train', content: `${err}`, level: 'error' })
);
} else if (obj) {
score = obj.score;
} else {
log({
logger: "train",
logger: 'train',
content: `Getting user score failed: ${err}`,
level: "error",
level: 'error',
});
}
});
let categoryArray: string[] = [];
const allCategories = [
"BIOLOGY",
"PHYSICS",
"CHEMISTRY",
"EARTH AND SPACE",
"ASTRONOMY",
"MATH",
'BIOLOGY',
'PHYSICS',
'CHEMISTRY',
'EARTH AND SPACE',
'ASTRONOMY',
'MATH',
];
const configCategories = await userConfig.findById(interaction.user.id);
@ -101,46 +101,46 @@ export async function execute(interaction: CommandInteraction) {
? configCategories.subjects || allCategories
: allCategories;
break;
case "astro":
case "astronomy":
categoryArray = ["ASTRONOMY"];
case 'astro':
case 'astronomy':
categoryArray = ['ASTRONOMY'];
break;
case "bio":
case "biology":
categoryArray = ["BIOLOGY"];
case 'bio':
case 'biology':
categoryArray = ['BIOLOGY'];
break;
case "ess":
case "earth science":
case "es":
categoryArray = ["EARTH SCIENCE"];
case 'ess':
case 'earth science':
case 'es':
categoryArray = ['EARTH SCIENCE'];
break;
case "chem":
case "chemistry":
categoryArray = ["CHEMISTRY"];
case 'chem':
case 'chemistry':
categoryArray = ['CHEMISTRY'];
break;
case "phys":
case "physics":
categoryArray = ["PHYSICS"];
case 'phys':
case 'physics':
categoryArray = ['PHYSICS'];
break;
case "math":
categoryArray = ["MATH"];
case 'math':
categoryArray = ['MATH'];
break;
case "energy":
categoryArray = ["ENERGY"];
case 'energy':
categoryArray = ['ENERGY'];
break;
default:
interaction.followUp({
embeds: [
new MessageEmbed()
.setDescription("<:red_x:816791117671825409> Not a valid subject!")
.setColor("#ffffff"),
.setDescription('<:red_x:816791117671825409> Not a valid subject!')
.setColor('#ffffff'),
],
});
return;
}
axios
.post("https://scibowldb.com/api/questions/random", {
.post('https://scibowldb.com/api/questions/random', {
categories: categoryArray,
})
.then((res) => {
@ -148,10 +148,10 @@ export async function execute(interaction: CommandInteraction) {
const tossupQuestion = questionData.tossup_question;
const tossupAnswer = questionData.tossup_answer;
const tossupFormat = questionData.tossup_format;
let answers = tossupAnswer.split(" (ACCEPT: ");
let answers = tossupAnswer.split(' (ACCEPT: ');
if (answers.length > 1) {
answers[1] = answers[1].slice(0, answers[1].length - 1); // If there are multiple elements, it means there was an 'accept' and therefore a trailing ')' which should be removed
answers = [answers[0], ...answers[1].split(new RegExp(" OR ", "i"))]; // Use the first element plus the last element split by 'OR' case insensitive
answers = [answers[0], ...answers[1].split(new RegExp(' OR ', 'i'))]; // Use the first element plus the last element split by 'OR' case insensitive
}
interaction
.followUp({ content: decode(tossupQuestion), fetchReply: true })
@ -160,11 +160,11 @@ export async function execute(interaction: CommandInteraction) {
const sourceButton = new MessageActionRow().addComponents(
new MessageButton()
.setURL(questionData.uri)
.setLabel("Source")
.setStyle("LINK")
.setLabel('Source')
.setStyle('LINK')
);
switch (tossupFormat) {
case "Short Answer": {
case 'Short Answer': {
// eslint-disable-next-line no-case-declarations
const messageFilter = (m) =>
m.author.id === interaction.user.id ||
@ -180,38 +180,38 @@ export async function execute(interaction: CommandInteraction) {
if (answerMsg?.author.id === interaction.client.user?.id)
return;
let predicted = "";
let predicted = '';
if (
answerMsg?.content.toLowerCase() ===
tossupAnswer.toLowerCase() ||
answers.includes(answerMsg?.content.toUpperCase())
) {
predicted = "correct";
predicted = 'correct';
} else {
predicted = "incorrect";
predicted = 'incorrect';
}
if (predicted === "correct") {
if (predicted === 'correct') {
updateScore(true, score, authorId).then((msgToReply) =>
answerMsg?.reply(msgToReply)
);
} else {
const overrideEmbed = new MessageEmbed()
.setAuthor({
name: answerMsg?.author.tag ? answerMsg.author.tag : "",
name: answerMsg?.author.tag ? answerMsg.author.tag : '',
iconURL: answerMsg?.author.displayAvatarURL(),
})
.addField("Correct answer", `\`${tossupAnswer}\``)
.addField('Correct answer', `\`${tossupAnswer}\``)
.setDescription(
"It seems your answer was incorrect. Please react with <:override:955265585086857236> to override your answer if you think you got it right."
'It seems your answer was incorrect. Please react with <:override:955265585086857236> to override your answer if you think you got it right.'
)
.setColor("#ffffff")
.setColor('#ffffff')
.setTimestamp();
const overrideButton = new MessageActionRow().addComponents(
new MessageButton()
.setCustomId("override")
.setEmoji("<:override:955265585086857236>")
.setStyle("SECONDARY")
.setCustomId('override')
.setEmoji('<:override:955265585086857236>')
.setStyle('SECONDARY')
);
answerMsg?.channel
.send({
@ -221,7 +221,7 @@ export async function execute(interaction: CommandInteraction) {
.then((overrideMsg) => {
const overrideFilter = (i) => {
return (
["override"].includes(i.customId) &&
['override'].includes(i.customId) &&
i.user.id === answerMsg.author.id
);
};
@ -239,49 +239,49 @@ export async function execute(interaction: CommandInteraction) {
})
.catch((err) =>
log({
logger: "train",
logger: 'train',
content: `Failed to override score: ${err}`,
level: "error",
level: 'error',
})
);
})
.catch((err) =>
log({
logger: "train",
logger: 'train',
content: `Failed to send override message: ${err}`,
level: "error",
level: 'error',
})
);
}
interaction.editReply({ components: [sourceButton] });
})
.catch((err) =>
log({ logger: "train", content: `${err}`, level: "error" })
log({ logger: 'train', content: `${err}`, level: 'error' })
);
break;
}
case "Multiple Choice": {
case 'Multiple Choice': {
const choices = new MessageActionRow().addComponents(
new MessageButton()
.setCustomId("w")
.setLabel("W")
.setStyle("SECONDARY"),
.setCustomId('w')
.setLabel('W')
.setStyle('SECONDARY'),
new MessageButton()
.setCustomId("x")
.setLabel("X")
.setStyle("SECONDARY"),
.setCustomId('x')
.setLabel('X')
.setStyle('SECONDARY'),
new MessageButton()
.setCustomId("y")
.setLabel("Y")
.setStyle("SECONDARY"),
.setCustomId('y')
.setLabel('Y')
.setStyle('SECONDARY'),
new MessageButton()
.setCustomId("z")
.setLabel("Z")
.setStyle("SECONDARY")
.setCustomId('z')
.setLabel('Z')
.setStyle('SECONDARY')
);
interaction.editReply({ components: [choices] });
const mcFilter = (i) =>
["w", "x", "y", "z"].includes(i.customId) &&
['w', 'x', 'y', 'z'].includes(i.customId) &&
i.user.id === interaction.user.id;
questionMessage
.awaitMessageComponent({ filter: mcFilter })
@ -298,11 +298,11 @@ export async function execute(interaction: CommandInteraction) {
name: interaction.user.tag,
iconURL: interaction.user.displayAvatarURL(),
})
.addField("Correct answer", `\`${tossupAnswer}\``)
.addField('Correct answer', `\`${tossupAnswer}\``)
.setDescription(
`It seems your answer ${mcChoice.customId.toUpperCase()} was incorrect.`
)
.setColor("#ffffff")
.setColor('#ffffff')
.setTimestamp();
mcChoice.reply({ embeds: [incorrectEmbed] });
}
@ -313,10 +313,10 @@ export async function execute(interaction: CommandInteraction) {
}
})
.catch((err) =>
log({ logger: "train", content: `${err}`, level: "error" })
log({ logger: 'train', content: `${err}`, level: 'error' })
);
})
.catch((err) =>
log({ logger: "train", content: `${err}`, level: "error" })
log({ logger: 'train', content: `${err}`, level: 'error' })
);
}

10
src/events/interactionCreate.ts

@ -1,6 +1,6 @@
import log from "../helpers/log";
import log from '../helpers/log';
export const name = "interactionCreate";
export const name = 'interactionCreate';
export const once = false;
@ -17,12 +17,12 @@ export async function execute(interaction) {
await command.execute(interaction);
} catch (error) {
log({
logger: "interaction",
logger: 'interaction',
content: `Interaction ${interaction.commandName} failed!`,
level: "error",
level: 'error',
});
await interaction.followUp({
content: "There was an error while executing this command!",
content: 'There was an error while executing this command!',
ephemeral: true,
});
}

20
src/events/messageCreate.ts

@ -1,31 +1,31 @@
import axios from "axios";
import { MessageEmbed } from "discord.js";
import { decode } from "html-entities";
import axios from 'axios';
import { MessageEmbed } from 'discord.js';
import { decode } from 'html-entities';
import { testingGuild } from "../helpers/env";
import { testingGuild } from '../helpers/env';
export const name = "messageCreate";
export const name = 'messageCreate';
export const once = false;
export async function execute(message) {
if (message.author.bot || message.guild.id != testingGuild) return;
if (message.content.startsWith("!q")) {
const questionId = message.content.split(" ")[1];
if (message.content.startsWith('!q')) {
const questionId = message.content.split(' ')[1];
axios
.get(`https://scibowldb.com/api/questions/${questionId}`)
.then((res) => {
const data = res.data.question;
const tossupQuestion = data.tossup_question;
const tossupAnswer = data.tossup_answer;
let answers = tossupAnswer.split(" (ACCEPT: ");
let answers = tossupAnswer.split(' (ACCEPT: ');
if (answers.length > 1) {
answers[1] = answers[1].slice(0, answers[1].length - 1); // If there are multiple elements, it means there was an 'accept' and therefore a trailing ')' which should be removed
answers = [answers[0], ...answers[1].split(new RegExp(" OR ", "i"))]; // Use the first element plus the last element split by 'OR' case insensitive
answers = [answers[0], ...answers[1].split(new RegExp(' OR ', 'i'))]; // Use the first element plus the last element split by 'OR' case insensitive
}
const dataEmbed = new MessageEmbed()
.setTitle("Data")
.setTitle('Data')
.setDescription(`\`\`\`json\n${JSON.stringify(data, null, 2)}\`\`\``);
message.reply({
content: decode(tossupQuestion) + `\n\nAnswers: [${answers}]`,

14
src/events/ready.ts

@ -1,17 +1,17 @@
import * as db from "../helpers/db";
import { mongoUri } from "../helpers/env";
import log from "../helpers/log";
import * as db from '../helpers/db';
import { mongoUri } from '../helpers/env';
import log from '../helpers/log';
export const name = "ready";
export const name = 'ready';
export const once = true;
export async function execute(client) {
await db.connect(mongoUri);
log({
logger: "status",
logger: 'status',
content: `Logged in as ${client.user.tag}!`,
level: "info",
level: 'info',
});
client.user.setActivity("for /help", { type: "WATCHING" });
client.user.setActivity('for /help', { type: 'WATCHING' });
}

22
src/helpers/db.ts

@ -1,7 +1,7 @@
import mongoose from "mongoose";
import mongoose from 'mongoose';
import log from "../helpers/log";
import userScore from "../models/userScore";
import log from '../helpers/log';
import userScore from '../models/userScore';
export async function updateScore(
isCorrect: boolean,
@ -23,15 +23,15 @@ export async function updateScore(
newUserScore.save((err) => {
if (err) {
log({
logger: "db",
logger: 'db',
content: `Error creating new user ${authorId} for scoring`,
level: "error",
level: 'error',
});
} else {
log({
logger: "db",
logger: 'db',
content: `Successfully created user ${authorId} for scoring`,
level: "debug",
level: 'debug',
});
}
});
@ -52,16 +52,16 @@ export async function connect(mongoUri) {
})
.then(() =>
log({
logger: "db",
logger: 'db',
content: `Connected to the database at ${mongoUri}!`,
level: "info",
level: 'info',
})
)
.catch((err) =>
log({
logger: "db",
logger: 'db',
content: `Failed to connect to the database at ${mongoUri}: ${err}`,
level: "fatal",
level: 'fatal',
})
);
}

10
src/helpers/env.ts

@ -1,7 +1,7 @@
import "dotenv/config";
import 'dotenv/config';
export const clientId = process.env.CLIENT_ID || "";
export const testingGuild = process.env.TESTING_GUILD || "";
export const token = process.env.TOKEN || "";
export const clientId = process.env.CLIENT_ID || '';
export const testingGuild = process.env.TESTING_GUILD || '';
export const token = process.env.TOKEN || '';
export const mongoUri = (process.env.MONGO_URI =
"mongodb://mongo:27017/AWESOME");
'mongodb://mongo:27017/AWESOME');

16
src/helpers/log.ts

@ -1,25 +1,25 @@
import log4js from "log4js";
import log4js from 'log4js';
export default function (config) {
const logger = log4js.getLogger(config.logger);
logger.level = "debug";
logger.level = 'debug';
switch (config.level) {
case "trace":
case 'trace':
logger.trace(config.content);
break;
case "debug":
case 'debug':
logger.debug(config.content);
break;
case "info":
case 'info':
logger.info(config.content);
break;
case "warn":
case 'warn':
logger.warn(config.content);
break;
case "error":
case 'error':
logger.error(config.content);
break;
case "fatal":
case 'fatal':
logger.fatal(config.content);
break;
default:

42
src/helpers/util/pagination.ts

@ -4,7 +4,7 @@ import {
MessageActionRow,
MessageButton,
MessageEmbed,
} from "discord.js";
} from 'discord.js';
export async function paginateMessage(
message: Message,
@ -15,13 +15,13 @@ export async function paginateMessage(
const row = new MessageActionRow();
row.addComponents(
new MessageButton()
.setCustomId("paginator-left")
.setEmoji("868552005977788466")
.setStyle("SECONDARY"),
.setCustomId('paginator-left')
.setEmoji('868552005977788466')
.setStyle('SECONDARY'),
new MessageButton()
.setCustomId("paginator-right")
.setEmoji("868551772887711754")
.setStyle("SECONDARY")
.setCustomId('paginator-right')
.setEmoji('868551772887711754')
.setStyle('SECONDARY')
);
await message
@ -35,17 +35,17 @@ export async function paginateMessage(
const paginatorCollector =
paginatorMessage.createMessageComponentCollector({
componentType: "BUTTON",
componentType: 'BUTTON',
filter: filter,
});
paginatorCollector.on("collect", async (i) => {
paginatorCollector.on('collect', async (i) => {
switch (i.customId) {
case "paginator-left":
case 'paginator-left':
index--;
if (index < 0) index = embeds.length - 1;
break;
case "paginator-right":
case 'paginator-right':
index++;
if (index > embeds.length - 1) index = 0;
break;
@ -67,13 +67,13 @@ export async function paginateInteraction(
const row = new MessageActionRow();
row.addComponents(
new MessageButton()
.setCustomId("paginator-left")
.setEmoji("868552005977788466")
.setStyle("SECONDARY"),
.setCustomId('paginator-left')
.setEmoji('868552005977788466')
.setStyle('SECONDARY'),
new MessageButton()
.setCustomId("paginator-right")
.setEmoji("868551772887711754")
.setStyle("SECONDARY")
.setCustomId('paginator-right')
.setEmoji('868551772887711754')
.setStyle('SECONDARY')
);
await interaction
@ -89,17 +89,17 @@ export async function paginateInteraction(
const paginatorCollector =
paginatorMessage.createMessageComponentCollector({
componentType: "BUTTON",
componentType: 'BUTTON',
filter: filter,
});
paginatorCollector.on("collect", async (i) => {
paginatorCollector.on('collect', async (i) => {
switch (i.customId) {
case "paginator-left":
case 'paginator-left':
index--;
if (index < 0) index = embeds.length - 1;
break;
case "paginator-right":
case 'paginator-right':
index++;
if (index > embeds.length - 1) index = 0;
break;

24
src/index.ts

@ -1,9 +1,9 @@
#!/usr/bin/env node
import fs from "node:fs";
import { Client, Collection, Intents } from "discord.js";
import { token } from "./helpers/env";
import log from "./helpers/log";
import fs from 'node:fs';
import { Client, Collection, Intents } from 'discord.js';
import { token } from './helpers/env';
import log from './helpers/log';
const client = new Client({
intents: [
@ -16,22 +16,22 @@ const client = new Client({
],
});
client["commands"] = new Collection();
client['commands'] = new Collection();
const commandFiles = fs
.readdirSync(`${__dirname}/commands`)
.filter((file) => file.endsWith(".js"));
.filter((file) => file.endsWith('.js'));
const eventFiles = fs
.readdirSync(`${__dirname}/events`)
.filter((file) => file.endsWith(".js"));
.filter((file) => file.endsWith('.js'));
for (const file of commandFiles) {
import(`${__dirname}/commands/${file}`).then((command) => {
client["commands"].set(command.data.name, command);
client['commands'].set(command.data.name, command);
log({
logger: "command",
logger: 'command',
content: `Registered command ${file}!`,
level: "info",
level: 'info',
});
});
}
@ -44,9 +44,9 @@ for (const file of eventFiles) {
client.on(event.name, (...args) => event.execute(...args));
}
log({
logger: "event",
logger: 'event',
content: `Registered event ${file}!`,
level: "info",
level: 'info',
});
});
}

4
src/models/generatedRound.ts

@ -1,4 +1,4 @@
import mongoose from "mongoose";
import mongoose from 'mongoose';
const generatedRoundSchema = new mongoose.Schema({
htmlContent: {
@ -19,4 +19,4 @@ const generatedRoundSchema = new mongoose.Schema({
},
});
export default mongoose.model("GeneratedRound", generatedRoundSchema);
export default mongoose.model('GeneratedRound', generatedRoundSchema);

4
src/models/userConfig.ts

@ -1,4 +1,4 @@
import mongoose from "mongoose";
import mongoose from 'mongoose';
const userConfigSchema = new mongoose.Schema({
_id: String,
@ -14,4 +14,4 @@ const userConfigSchema = new mongoose.Schema({
},
});
export default mongoose.model("UserConfig", userConfigSchema);
export default mongoose.model('UserConfig', userConfigSchema);

4
src/models/userScore.ts

@ -1,4 +1,4 @@
import mongoose from "mongoose";
import mongoose from 'mongoose';
const userScoreSchema = new mongoose.Schema({
authorID: {
@ -11,4 +11,4 @@ const userScoreSchema = new mongoose.Schema({
},
});
export default mongoose.model("UserScore", userScoreSchema);
export default mongoose.model('UserScore', userScoreSchema);

Loading…
Cancel
Save