Preparing for George Update (#2895)

* bot-commands rename

* removed bot dal

* reomoved unnecessary configuration entry

* quotes:code_javascript: Add regex-heavy quote. (#2929) markstos

* quotes:code_javascript: Add regex-heavy quote.

This quote contains a long regex that will be a workout for typing
symbols and numbers.

Source code can be confirmed to available under an open source license
here: https://github.com/markstos/parse-coordinates/blob/master/index.js

* fixed length

Co-authored-by: Miodec <bartnikjack@gmail.com>

* fixed script names

* fixed incorrect path

* definitely didnt forget about those

Co-authored-by: Miodec <bartnikjack@gmail.com>
Co-authored-by: Mark Stosberg <mark@rideamigos.com>
Co-authored-by: Jack <jack@monkeytype.com>
This commit is contained in:
Evan 2022-05-06 16:48:15 -05:00 committed by GitHub
parent 9b9960628e
commit d9ffcfb4ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 52 additions and 87 deletions

View file

@ -7,7 +7,6 @@ import {
updateTypingStats,
} from "../../dal/user";
import * as PublicStatsDAL from "../../dal/public-stats";
import * as BotDAL from "../../dal/bot";
import { roundTo2, stdDev } from "../../utils/misc";
import objectHash from "object-hash";
import Logger from "../../utils/logger";
@ -81,8 +80,6 @@ export async function addResult(
): Promise<MonkeyResponse> {
const { uid } = req.ctx.decodedToken;
const useRedisForBotTasks = req.ctx.configuration.useRedisForBotTasks.enabled;
const result = Object.assign({}, req.body.result);
result.uid = uid;
if (isTestTooShort(result)) {
@ -261,18 +258,12 @@ export async function addResult(
if (result.mode === "time" && String(result.mode2) === "60") {
incrementBananas(uid, result.wpm);
if (isPb && user.discordId) {
if (useRedisForBotTasks) {
George.updateDiscordRole(user.discordId, result.wpm);
}
BotDAL.updateDiscordRole(user.discordId, result.wpm);
George.updateDiscordRole(user.discordId, result.wpm);
}
}
if (result.challenge && user.discordId) {
if (useRedisForBotTasks) {
George.awardChallenge(user.discordId, result.challenge);
}
BotDAL.awardChallenge(user.discordId, result.challenge);
George.awardChallenge(user.discordId, result.challenge);
} else {
delete result.challenge;
}

View file

@ -1,5 +1,4 @@
import * as UserDAL from "../../dal/user";
import * as BotDAL from "../../dal/bot";
import MonkeyError from "../../utils/error";
import Logger from "../../utils/logger";
import { MonkeyResponse } from "../../utils/monkey-response";
@ -127,8 +126,6 @@ export async function linkDiscord(
data: { tokenType, accessToken },
} = req.body;
const useRedisForBotTasks = req.ctx.configuration.useRedisForBotTasks.enabled;
const userInfo = await UserDAL.getUser(uid, "link discord");
if (userInfo.discordId) {
throw new MonkeyError(
@ -160,10 +157,7 @@ export async function linkDiscord(
await UserDAL.linkDiscord(uid, discordId);
if (useRedisForBotTasks) {
George.linkDiscord(discordId, uid);
}
await BotDAL.linkDiscord(uid, discordId);
George.linkDiscord(discordId, uid);
Logger.logToDb("user_discord_link", `linked to ${discordId}`, uid);
return new MonkeyResponse("Discord account linked", discordId);
@ -174,18 +168,12 @@ export async function unlinkDiscord(
): Promise<MonkeyResponse> {
const { uid } = req.ctx.decodedToken;
const useRedisForBotTasks = req.ctx.configuration.useRedisForBotTasks.enabled;
const userInfo = await UserDAL.getUser(uid, "unlink discord");
if (!userInfo.discordId) {
throw new MonkeyError(404, "User does not have a linked Discord account");
}
if (useRedisForBotTasks) {
George.unlinkDiscord(userInfo.discordId, uid);
}
await BotDAL.unlinkDiscord(uid, userInfo.discordId);
George.unlinkDiscord(userInfo.discordId, uid);
await UserDAL.unlinkDiscord(uid);
Logger.logToDb("user_discord_unlinked", userInfo.discordId, uid);

View file

@ -26,9 +26,6 @@ const BASE_CONFIGURATION: MonkeyTypes.Configuration = {
enableSavingResults: {
enabled: false,
},
useRedisForBotTasks: {
enabled: false,
},
favoriteQuotes: {
maxFavorites: 100,
},

View file

@ -1,61 +1,59 @@
import { InsertManyResult, InsertOneResult } from "mongodb";
import * as db from "../init/db";
async function addCommand(
command,
commandArguments
async function addTask(
task,
taskArgs
): Promise<InsertOneResult<any>> {
return await db.collection<any>("bot-commands").insertOne({
command,
arguments: commandArguments,
executed: false,
return await db.collection<any>("bot-tasks").insertOne({
name: task,
args: taskArgs,
requestTimestamp: Date.now(),
});
}
async function addCommands(
commands,
commandArguments
async function addTasks(
tasks,
taskArgs
): Promise<void | InsertManyResult> {
if (commands.length === 0 || commands.length !== commandArguments.length) {
if (tasks.length === 0 || tasks.length !== taskArgs.length) {
return;
}
const normalizedCommands = commands.map((command, index) => {
const normalizedTasks = tasks.map((task, index) => {
return {
command,
arguments: commandArguments[index],
executed: false,
name: task,
args: taskArgs[index],
requestTimestamp: Date.now(),
};
});
return await db.collection("bot-commands").insertMany(normalizedCommands);
return await db.collection("bot-tasks").insertMany(normalizedTasks);
}
export async function updateDiscordRole(
discordId,
wpm
): Promise<InsertOneResult> {
return await addCommand("updateRole", [discordId, wpm]);
return await addTask("updateRole", [discordId, wpm]);
}
export async function linkDiscord(uid, discordId): Promise<InsertOneResult> {
return await addCommand("linkDiscord", [discordId, uid]);
return await addTask("linkDiscord", [discordId, uid]);
}
export async function unlinkDiscord(uid, discordId): Promise<InsertOneResult> {
return await addCommand("unlinkDiscord", [discordId, uid]);
return await addTask("unlinkDiscord", [discordId, uid]);
}
export async function awardChallenge(
discordId,
challengeName
): Promise<InsertOneResult> {
return await addCommand("awardChallenge", [discordId, challengeName]);
return await addTask("awardChallenge", [discordId, challengeName]);
}
export async function announceLbUpdate(
export async function announceLeaderboardUpdate(
newRecords,
leaderboardId
): Promise<InsertManyResult | void> {
@ -63,8 +61,8 @@ export async function announceLbUpdate(
return;
}
const leaderboardCommands = Array(newRecords.length).fill("sayLbUpdate");
const leaderboardCommandsArguments = newRecords.map((newRecord) => {
const leaderboardTasks = Array(newRecords.length).fill("sayLbUpdate");
const leaderboardTaskArgs = newRecords.map((newRecord) => {
return [
newRecord.discordId ?? newRecord.name,
newRecord.rank,
@ -76,5 +74,5 @@ export async function announceLbUpdate(
];
});
return await addCommands(leaderboardCommands, leaderboardCommandsArguments);
return await addTasks(leaderboardTasks, leaderboardTaskArgs);
}

View file

@ -1,8 +1,6 @@
import { CronJob } from "cron";
import { announceLbUpdate } from "../dal/bot";
import * as George from "../tasks/george";
import * as LeaderboardsDAL from "../dal/leaderboards";
import { getCachedConfiguration } from "../init/configuration";
const CRON_SCHEDULE = "30 14/15 * * * *";
const RECENT_AGE_MINUTES = 10;
@ -51,15 +49,9 @@ async function updateLeaderboardAndNotifyChanges(
});
if (newRecords.length > 0) {
const cachedConfig = await getCachedConfiguration();
const leaderboardId = `time ${leaderboardTime} english`;
if (cachedConfig.useRedisForBotTasks.enabled) {
await George.announceLbUpdate(newRecords, leaderboardId);
}
await announceLbUpdate(newRecords, leaderboardId);
await George.announceLeaderboardUpdate(newRecords, leaderboardId);
}
}

View file

@ -3,15 +3,17 @@ import { Queue, QueueScheduler } from "bullmq";
const QUEUE_NAME = "george-tasks";
type GeorgeTaskArgument = string | number;
interface GeorgeTask {
command: string;
arguments: any[];
name: string;
args: GeorgeTaskArgument[];
}
function buildGeorgeTask(command: string, taskArguments: any[]): GeorgeTask {
function buildGeorgeTask(task: string, taskArgs: GeorgeTaskArgument[]): GeorgeTask {
return {
command,
arguments: taskArguments,
name: task,
args: taskArgs,
};
}
@ -41,12 +43,12 @@ export function initJobQueue(redisConnection: IORedis.Redis | undefined): void {
});
}
async function addToQueue(command: string, task: GeorgeTask): Promise<void> {
async function addToQueue(taskName: string, task: GeorgeTask): Promise<void> {
if (!jobQueue) {
return;
}
await jobQueue.add(command, task);
await jobQueue.add(taskName, task);
}
async function addToQueueBulk(
@ -63,49 +65,49 @@ export async function updateDiscordRole(
discordId: string,
wpm: number
): Promise<void> {
const command = "updateRole";
const updateDiscordRoleTask = buildGeorgeTask(command, [discordId, wpm]);
await addToQueue(command, updateDiscordRoleTask);
const task = "updateRole";
const updateDiscordRoleTask = buildGeorgeTask(task, [discordId, wpm]);
await addToQueue(task, updateDiscordRoleTask);
}
export async function linkDiscord(
discordId: string,
uid: string
): Promise<void> {
const command = "linkDiscord";
const linkDiscordTask = buildGeorgeTask(command, [discordId, uid]);
await addToQueue(command, linkDiscordTask);
const task = "linkDiscord";
const linkDiscordTask = buildGeorgeTask(task, [discordId, uid]);
await addToQueue(task, linkDiscordTask);
}
export async function unlinkDiscord(
discordId: string,
uid: string
): Promise<void> {
const command = "unlinkDiscord";
const unlinkDiscordTask = buildGeorgeTask(command, [discordId, uid]);
await addToQueue(command, unlinkDiscordTask);
const task = "unlinkDiscord";
const unlinkDiscordTask = buildGeorgeTask(task, [discordId, uid]);
await addToQueue(task, unlinkDiscordTask);
}
export async function awardChallenge(
discordId: string,
challengeName: string
): Promise<void> {
const command = "awardChallenge";
const awardChallengeTask = buildGeorgeTask(command, [
const task = "awardChallenge";
const awardChallengeTask = buildGeorgeTask(task, [
discordId,
challengeName,
]);
await addToQueue(command, awardChallengeTask);
await addToQueue(task, awardChallengeTask);
}
export async function announceLbUpdate(
export async function announceLeaderboardUpdate(
newRecords: any[],
leaderboardId: string
): Promise<void> {
const command = "announceLbUpdate";
const task = "announceLeaderboardUpdate";
const leaderboardUpdateTasks = newRecords.map((record) => {
const taskData = buildGeorgeTask(command, [
const taskData = buildGeorgeTask(task, [
record.discordId ?? record.name,
record.rank,
leaderboardId,
@ -116,7 +118,7 @@ export async function announceLbUpdate(
]);
return {
name: command,
name: task,
data: taskData,
};
});

View file

@ -26,9 +26,6 @@ declare namespace MonkeyTypes {
enableSavingResults: {
enabled: boolean;
};
useRedisForBotTasks: {
enabled: boolean;
};
favoriteQuotes: {
maxFavorites: number;
};