diff options
author | TymanWasTaken <32660892+tymanwastaken@users.noreply.github.com> | 2021-04-27 21:06:22 -0600 |
---|---|---|
committer | TymanWasTaken <32660892+tymanwastaken@users.noreply.github.com> | 2021-04-27 21:06:22 -0600 |
commit | 763fb7d98c3accbb21adf035a7cf0a83cb9533c9 (patch) | |
tree | 9d333fbca2a2a8e19d79904a4e29226174925cfc /src/lib/extensions/Util.ts | |
download | tanzanite-763fb7d98c3accbb21adf035a7cf0a83cb9533c9.tar.gz tanzanite-763fb7d98c3accbb21adf035a7cf0a83cb9533c9.tar.bz2 tanzanite-763fb7d98c3accbb21adf035a7cf0a83cb9533c9.zip |
legit just copy utilibot v2 code
Diffstat (limited to 'src/lib/extensions/Util.ts')
-rw-r--r-- | src/lib/extensions/Util.ts | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/src/lib/extensions/Util.ts b/src/lib/extensions/Util.ts new file mode 100644 index 0000000..20bfd48 --- /dev/null +++ b/src/lib/extensions/Util.ts @@ -0,0 +1,196 @@ +import { ClientUtil } from 'discord-akairo'; +import { BotClient } from './BotClient'; +import { User } from 'discord.js'; +import { promisify } from 'util'; +import { exec } from 'child_process'; +import got from 'got'; +import { TextChannel } from 'discord.js'; + +interface hastebinRes { + key: string; +} + +export class Util extends ClientUtil { + /** + * The client of this ClientUtil + * @type {BotClient} + */ + public client: BotClient; + /** + * The hastebin urls used to post to hastebin, attempts to post in order + * @type {string[]} + */ + public hasteURLs = [ + 'https://hst.sh', + 'https://hasteb.in', + 'https://hastebin.com', + 'https://mystb.in', + 'https://haste.clicksminuteper.net', + 'https://paste.pythondiscord.com', + 'https://haste.unbelievaboat.com', + 'https://haste.tyman.tech' + ]; + /** + * A simple promise exec method + */ + private exec = promisify(exec); + + /** + * Creates this client util + * @param client The client to initialize with + */ + constructor(client: BotClient) { + super(client); + } + + /** + * Maps an array of user ids to user objects. + * @param ids The list of IDs to map + * @returns The list of users mapped + */ + public async mapIDs(ids: string[]): Promise<User[]> { + return await Promise.all(ids.map((id) => this.client.users.fetch(id))); + } + + /** + * Capitalizes the first letter of the given text + * @param text The text to capitalize + * @returns The capitalized text + */ + public capitalize(text: string): string { + return text.charAt(0).toUpperCase() + text.slice(1); + } + + /** + * Runs a shell command and gives the output + * @param command The shell command to run + * @returns The stdout and stderr of the shell command + */ + public async shell( + command: string + ): Promise<{ + stdout: string; + stderr: string; + }> { + return await this.exec(command); + } + + /** + * Posts text to hastebin + * @param content The text to post + * @returns The url of the posted text + */ + public async haste(content: string): Promise<string> { + for (const url of this.hasteURLs) { + try { + const res: hastebinRes = await got + .post(`${url}/documents`, { body: content }) + .json(); + return `${url}/${res.key}`; + } catch (e) { + // pass + } + } + throw new Error('No urls worked. (wtf)'); + } + + /** + * Logs something but only in dev mode + * @param content The thing to log + */ + public devLog(content: unknown): void { + if (this.client.config.dev) console.log(content); + } + + /** + * Resolves a user-provided string into a user object, if possible + * @param text The text to try and resolve + * @returns The user resolved or null + */ + public async resolveUserAsync(text: string): Promise<User | null> { + const idReg = /\d{17,19}/; + const idMatch = text.match(idReg); + if (idMatch) { + try { + const user = await this.client.users.fetch(text); + return user; + } catch { + // pass + } + } + const mentionReg = /<@!?(?<id>\d{17,19})>/; + const mentionMatch = text.match(mentionReg); + if (mentionMatch) { + try { + const user = await this.client.users.fetch(mentionMatch.groups.id); + return user; + } catch { + // pass + } + } + const user = this.client.users.cache.find((u) => u.username === text); + if (user) return user; + return null; + } + + /** + * Appends the correct ordinal to the given number + * @param n The number to append an ordinal to + * @returns The number with the ordinal + */ + public ordinal(n: number): string { + const s = ['th', 'st', 'nd', 'rd'], + v = n % 100; + return n + (s[(v - 20) % 10] || s[v] || s[0]); + } + + /** + * Chunks an array to the specified size + * @param arr The array to chunk + * @param perChunk The amount of items per chunk + * @returns The chunked array + */ + public chunk<T>(arr: T[], perChunk: number): T[][] { + return arr.reduce((all, one, i) => { + const ch = Math.floor(i / perChunk); + all[ch] = [].concat(all[ch] || [], one); + return all; + }, []); + } + + /** + * Logs a message to console and log channel as info + * @param message The message to send + */ + public async info(message: string): Promise<void> { + console.log(`INFO: ${message}`); + const channel = (await this.client.channels.fetch( + this.client.config.channels.log + )) as TextChannel; + await channel.send(`INFO: ${message}`); + } + + /** + * Logs a message to console and log channel as a warning + * @param message The message to send + */ + public async warn(message: string): Promise<void> { + console.warn(`WARN: ${message}`); + const channel = (await this.client.channels.fetch( + this.client.config.channels.log + )) as TextChannel; + await channel.send(`WARN: ${message}`); + } + + /** + * Logs a message to console and log channel as an error + * @param message The message to send + */ + public async error(message: string): Promise<void> { + console.error(`ERROR: ${message}`); + const channel = (await this.client.channels.fetch( + this.client.config.channels.error + )) as TextChannel; + await channel.send(`ERROR: ${message}`); + } +} |