Initial Commit
This commit is contained in:
57
src/cacheController.js
Normal file
57
src/cacheController.js
Normal file
@@ -0,0 +1,57 @@
|
||||
const fs = require('fs/promises');
|
||||
const fsSync = require('fs');
|
||||
const path = require('path')
|
||||
const { request } = require('undici')
|
||||
const { cacheInfo } = require('../config.json');
|
||||
|
||||
const AVAILABLE_TAGS = {
|
||||
SPC_OUTLOOK: "spcoutlook"
|
||||
}
|
||||
|
||||
class CacheController {
|
||||
constructor(options) {
|
||||
|
||||
}
|
||||
|
||||
initCache() {
|
||||
Object.values(AVAILABLE_TAGS).forEach(tag => {
|
||||
if(!fsSync.existsSync(path.join(cacheInfo.path, tag))) {
|
||||
fsSync.mkdirSync(path.join(cacheInfo.path, tag))
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async storeFile(fileData, fileName, tag) {
|
||||
return fs.writeFile(path.join(cacheInfo.path, tag, fileName), fileData)
|
||||
}
|
||||
|
||||
async fetchFile(fileName, tag) {
|
||||
try {
|
||||
const fileData = await fs.readFile(path.join(cacheInfo.path, tag, fileName));
|
||||
return {fileExists: true, fileData}
|
||||
}
|
||||
catch (err) {
|
||||
return {fileExists: false, error: err}
|
||||
}
|
||||
}
|
||||
|
||||
async getOrCacheBinary(url, fileName, tag) {
|
||||
let results = await this.fetchFile(fileName, tag)
|
||||
if(results.fileExists) {
|
||||
console.log("File exists!")
|
||||
return results.fileData
|
||||
}
|
||||
console.log("We gotta fetch it!")
|
||||
let response = await request(url);
|
||||
let requestFileData = await response.body.bytes();
|
||||
await this.storeFile(Buffer.from(requestFileData.buffer), fileName, tag)
|
||||
return Buffer.from(requestFileData.buffer)
|
||||
}
|
||||
}
|
||||
|
||||
const Cache = new CacheController();
|
||||
Cache.initCache()
|
||||
module.exports = {
|
||||
Cache,
|
||||
AVAILABLE_TAGS
|
||||
}
|
||||
47
src/commands/ping.js
Normal file
47
src/commands/ping.js
Normal file
@@ -0,0 +1,47 @@
|
||||
const { isMessageInstance } = require('@sapphire/discord.js-utilities');
|
||||
const { Command } = require('@sapphire/framework');
|
||||
|
||||
class PingCommand extends Command {
|
||||
constructor(context, options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'ping',
|
||||
aliases: ['pong'],
|
||||
description: 'ping pong'
|
||||
});
|
||||
}
|
||||
|
||||
registerApplicationCommands(registry) {
|
||||
registry.registerChatInputCommand((builder) =>
|
||||
builder //
|
||||
.setName(this.name)
|
||||
.setDescription(this.description)
|
||||
,{
|
||||
idHints: '1355583305029783573'
|
||||
});
|
||||
}
|
||||
|
||||
async messageRun(message) {
|
||||
const msg = await message.channel.send('Ping?');
|
||||
|
||||
const content = `Pong from JavaScript! Bot Latency ${Math.round(this.container.client.ws.ping)}ms. API Latency ${msg.createdTimestamp - message.createdTimestamp}ms.`;
|
||||
|
||||
return msg.edit(content);
|
||||
}
|
||||
|
||||
async chatInputRun(interaction) {
|
||||
const currentDate = new Date();
|
||||
const msg = await interaction.reply({ content: `Ping? Current UTC time is ${currentDate.getUTCHours()}:${currentDate.getUTCMinutes()}:${currentDate.getUTCSeconds()}`, ephemeral: true, fetchReply: true });
|
||||
|
||||
if (isMessageInstance(msg)) {
|
||||
const diff = msg.createdTimestamp - interaction.createdTimestamp;
|
||||
const ping = Math.round(this.container.client.ws.ping);
|
||||
return interaction.editReply(`Pong 🏓! (Round trip took: ${diff}ms. Heartbeat: ${ping}ms.)`);
|
||||
}
|
||||
|
||||
return interaction.editReply('Failed to retrieve ping :(');
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
PingCommand
|
||||
};
|
||||
135
src/commands/spc.js
Normal file
135
src/commands/spc.js
Normal file
@@ -0,0 +1,135 @@
|
||||
const { Subcommand } = require('@sapphire/plugin-subcommands');
|
||||
const { AVAILABLE_TAGS, Cache } = require('../cacheController')
|
||||
const { request } = require('undici')
|
||||
const { spcGenerationTimes } = require('../../config.json')
|
||||
|
||||
// Extend `Subcommand` instead of `Command`
|
||||
class UserCommand extends Subcommand {
|
||||
constructor(context, options) {
|
||||
super(context, {
|
||||
...options,
|
||||
name: 'spc',
|
||||
subcommands: [
|
||||
{
|
||||
name: 'getoutlook',
|
||||
chatInputRun: 'getOutlook'
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
registerApplicationCommands(registry) {
|
||||
registry.registerChatInputCommand((builder) =>
|
||||
builder
|
||||
.setName('spc')
|
||||
.setDescription('Get SPC Information') // Needed even though base command isn't displayed to end user
|
||||
.addSubcommand((command) =>
|
||||
command.setName('getoutlook')
|
||||
.setDescription('Gets SPC Outlooks')
|
||||
.addStringOption((option) =>
|
||||
option.setName("outlookday")
|
||||
.setDescription("Outlook Day(s) to pull")
|
||||
.setRequired(true)
|
||||
.addChoices(
|
||||
{ name: 'Day 1 (Today)', value: 'day1'},
|
||||
{ name: 'Day 2 (Tomorrow)', value: 'day2'},
|
||||
{ name: 'Day 3', value: 'day3'},
|
||||
{ name: 'Days 4-7', value: 'day4'}
|
||||
)
|
||||
)
|
||||
)
|
||||
, {
|
||||
idHints: '1355696856037986435'
|
||||
});
|
||||
}
|
||||
|
||||
async getOutlook(interaction) {
|
||||
await interaction.deferReply()
|
||||
const day = interaction.options.getString('outlookday');
|
||||
|
||||
const currentDate = new Date();
|
||||
const cacheDateString = currentDate.getMonth() + "" + currentDate.getDate() + "" + currentDate.getFullYear()
|
||||
if(day == "day4" ) {
|
||||
console.log("Day is day4")
|
||||
|
||||
let fileData = await Cache.getOrCacheBinary('https://www.spc.noaa.gov/products/exper/day4-8/day48prob.gif',
|
||||
cacheDateString.concat("_", day), AVAILABLE_TAGS.SPC_OUTLOOK);
|
||||
|
||||
return interaction.editReply({
|
||||
files: [{
|
||||
attachment: fileData, name: `SPC_Day4Outlook_${cacheDateString}.gif`
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
let timeText = this.normalizeTime(day);
|
||||
console.log(`The timeText is ${timeText}`)
|
||||
if(day == "day1" || day == "day2") {
|
||||
console.log(`It's day1 or day2! It's ${day}`)
|
||||
const cacheDateString = currentDate.getMonth() + "" + currentDate.getDate() + "" + currentDate.getFullYear()
|
||||
// Day 1 and Day 2 have probabalistic that we want to grab.
|
||||
try {
|
||||
console.log("Trying!")
|
||||
let files = await Promise.all([
|
||||
Cache.getOrCacheBinary(`https://www.spc.noaa.gov/products/outlook/${day}otlk_${timeText}.gif`,
|
||||
cacheDateString.concat("_", day, timeText), AVAILABLE_TAGS.SPC_OUTLOOK),
|
||||
Cache.getOrCacheBinary(`https://www.spc.noaa.gov/products/outlook/${day}probotlk_${timeText}_torn.gif`,
|
||||
cacheDateString.concat("_", day, timeText, "torn"), AVAILABLE_TAGS.SPC_OUTLOOK),
|
||||
Cache.getOrCacheBinary(`https://www.spc.noaa.gov/products/outlook/${day}probotlk_${timeText}_wind.gif`,
|
||||
cacheDateString.concat("_", day, timeText, "wind"), AVAILABLE_TAGS.SPC_OUTLOOK),
|
||||
Cache.getOrCacheBinary(`https://www.spc.noaa.gov/products/outlook/${day}probotlk_${timeText}_hail.gif`,
|
||||
cacheDateString.concat("_", day, timeText, "hail"), AVAILABLE_TAGS.SPC_OUTLOOK)
|
||||
])
|
||||
|
||||
return interaction.editReply({
|
||||
files: [{
|
||||
attachment: files[0], name: `SPC_${day}Outlook_${timeText}_${cacheDateString}.gif`
|
||||
}, {
|
||||
attachment: files[1], name: `SPC_${day}Outlook_${timeText}_Tornado_${cacheDateString}.gif`
|
||||
}, {
|
||||
attachment: files[2], name: `SPC_${day}Outlook_${timeText}_Wind_${cacheDateString}.gif`
|
||||
}, {
|
||||
attachment: files[3], name: `SPC_${day}Outlook_${timeText}_Hail_${cacheDateString}.gif`
|
||||
}]
|
||||
})
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
return interaction.editReply("Oh shit something happened!")
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log("It's day3!")
|
||||
const cacheDateString = currentDate.getMonth() + "" + currentDate.getDate() + "" + currentDate.getFullYear()
|
||||
let file = await Cache.getOrCacheBinary(`https://www.spc.noaa.gov/products/outlook/day3otlk_${timeText}.gif`,
|
||||
cacheDateString.concat("_", day, timeText), AVAILABLE_TAGS.SPC_OUTLOOK)
|
||||
|
||||
return interaction.editReply({
|
||||
files: [{
|
||||
attachment: file, name: `SPC_Day3Outlook_${timeText}_${cacheDateString}.gif`
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
normalizeTime(day) {
|
||||
const currentUTCHour = (new Date()).getUTCHours();
|
||||
const currentUTCMinutes = (new Date()).getUTCMinutes();
|
||||
const dateNumber = (currentUTCHour * 100) + currentUTCMinutes
|
||||
|
||||
let generationTimes = spcGenerationTimes[day];
|
||||
let timeLiteral = ""
|
||||
generationTimes.forEach((timeObject) => {
|
||||
if(dateNumber >= timeObject.startTime && dateNumber < timeObject.endTime) {
|
||||
timeLiteral = timeObject.timeText
|
||||
}
|
||||
});
|
||||
|
||||
return timeLiteral;
|
||||
}
|
||||
|
||||
}
|
||||
module.exports = {
|
||||
UserCommand
|
||||
};
|
||||
11
src/index.js
Normal file
11
src/index.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const { LogLevel, SapphireClient } = require('@sapphire/framework');
|
||||
const { GatewayIntentBits } = require('discord.js');
|
||||
const { token } = require('../config.json')
|
||||
|
||||
const client = new SapphireClient({
|
||||
intents: [GatewayIntentBits.MessageContent, GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
|
||||
loadMessageCommandListeners: true,
|
||||
logger: { level: LogLevel.Debug }
|
||||
});
|
||||
|
||||
client.login(token);
|
||||
Reference in New Issue
Block a user