mirror of
https://gitlab.com/bignutty/labscore.git
synced 2025-06-08 06:03:04 -04:00
145 lines
No EOL
5.4 KiB
JavaScript
145 lines
No EOL
5.4 KiB
JavaScript
const { darksky } = require('#api');
|
||
const { paginator } = require('#client');
|
||
|
||
const { createEmbed, page } = require('#utils/embed')
|
||
const { pill, iconPill, smallPill, weatherIcon, timestamp, icon, link, stringwrap} = require('#utils/markdown');
|
||
const { editOrReply } = require('#utils/message')
|
||
const { STATICS } = require('#utils/statics');
|
||
|
||
// TODO: Turn this into a general purpose permissions constant
|
||
const { Permissions } = require("detritus-client/lib/constants");
|
||
|
||
const modifiers = {
|
||
"°C": (i)=>i,
|
||
"°F": (i)=>(i*(9/5))+32
|
||
}
|
||
|
||
const unitNames = {
|
||
"°C": "Celcius",
|
||
"°F": "Fahrenheit"
|
||
}
|
||
|
||
function temperature(value, units){
|
||
return `${Math.floor(modifiers[units](value))}${units}`
|
||
}
|
||
|
||
function getUvIndex(i){
|
||
switch(i){
|
||
case i <= 2:
|
||
return "uv_index_0"
|
||
case i <= 5:
|
||
return "uv_index_1"
|
||
case i <= 7:
|
||
return "uv_index_2"
|
||
case i <= 10:
|
||
return "uv_index_3"
|
||
case i <= 11:
|
||
return "uv_index_4"
|
||
default:
|
||
return "question"
|
||
}
|
||
}
|
||
|
||
function renderWeatherCard(context, data, units){
|
||
let description = `### ${weatherIcon(data.result.current.icon.id)} ${temperature(data.result.current.temperature.current, units)} • ${data.result.current.condition.label}\n\n${pill("Feels like")} ${smallPill(temperature(data.result.current.temperature.feels_like, units))} ${pill("Wind")} `
|
||
|
||
if(units == "°F") description += smallPill((data.result.current.wind.speed / 1.609).toFixed(2) + " mph")
|
||
else description += smallPill((data.result.current.wind.speed).toFixed(2) + " km/h")
|
||
|
||
let secondaryPills = [];
|
||
if(data.result.current.humidity > 0) secondaryPills.push(`${pill("Humidity")} ${smallPill(Math.floor(data.result.current.humidity * 100) + "%")}`)
|
||
if(data.result.current.uvindex > 0) secondaryPills.push(`${iconPill(getUvIndex(data.result.uvindex), "UV Index")} ${smallPill(data.result.current.uvindex)}`)
|
||
|
||
if(secondaryPills.length >= 1) description += '\n' + secondaryPills.join(` `)
|
||
|
||
if(data.result.air_quality){
|
||
description += `\n${iconPill("air_quality_" + data.result.air_quality.type, "Air Quality")} ${smallPill(`${data.result.air_quality.label} (${data.result.air_quality.value})`)}`
|
||
}
|
||
|
||
description += `\n\n${iconPill("sun", "Sunrise")} ${timestamp(data.result.current.sun.sunrise, "t")} ${iconPill("moon", "Sunset")} ${timestamp(data.result.current.sun.sunset, "t")}`
|
||
|
||
// Render weather alerts
|
||
if(data.result.warnings.length >= 1){
|
||
for(const w of [data.result.warnings[0]]){
|
||
if(description.includes(stringwrap(w.label, 50))) continue;
|
||
description += `\n\n${icon("weather_warning_" + (w.icon || "generic").toLowerCase())} **${stringwrap(w.label, 50)}**\n-# ${stringwrap(w.source, 50)} • ${link(w.url, "Learn More", "Learn more about this alert")}`
|
||
}
|
||
}
|
||
|
||
// Render Forecasts
|
||
description += `\n`
|
||
|
||
let space = 3;
|
||
if(units === "°F") space = 4;
|
||
for(const i of data.result.forecast){
|
||
description += `\n${pill(i.day)} ${weatherIcon(i.icon)}`
|
||
if(temperature(i.temperature.max, units).toString().length === space) description += `${pill(temperature(i.temperature.max, units) + " ")}`
|
||
else description += `${pill(temperature(i.temperature.max, units))}`
|
||
description += `**/**`
|
||
if(temperature(i.temperature.min, units).toString().length === space) description += `${smallPill(temperature(i.temperature.min, units) + " ")}`
|
||
else description += `${smallPill(temperature(i.temperature.min, units))}`
|
||
}
|
||
|
||
|
||
let e = createEmbed("default", context, {
|
||
description,
|
||
timestamp: new Date(data.result.current.date)
|
||
})
|
||
|
||
e.footer.iconUrl = STATICS.weather
|
||
if(data.result.location) e.footer.text = data.result.location
|
||
|
||
if(data.result.current.icon) e.thumbnail = { url: data.result.current.icon.url }
|
||
if(data.result.current.image) e.image = { url: data.result.current.image }
|
||
|
||
|
||
return e;
|
||
}
|
||
|
||
module.exports = {
|
||
name: 'weather',
|
||
aliases: ['forecast'],
|
||
label: 'query',
|
||
metadata: {
|
||
description: 'Displays information about the weather.',
|
||
description_short: 'Local weather information',
|
||
examples: ['weather Otter, Germany -t f'],
|
||
category: 'utils',
|
||
usage: 'weather <location> [-t <c|f>',
|
||
slashCommand: "weather"
|
||
},
|
||
args: [
|
||
{name: 't', default: 'celcius', type: 'units', help: "Temperature Units to use."},
|
||
],
|
||
permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.READ_MESSAGE_HISTORY],
|
||
run: async (context, args) => {
|
||
context.triggerTyping();
|
||
if(!args.query) return editOrReply(context, createEmbed("warning", context, `Missing Parameter (location).`))
|
||
try{
|
||
let data = await darksky(context, args.query)
|
||
|
||
data = data.response.body
|
||
|
||
let units = ["°C", "°F"]
|
||
if(["f","fahrenheit","°f"].includes(args.t.toLowerCase())) units = ["°F", "°C"]
|
||
|
||
let pages = []
|
||
pages.push(page(renderWeatherCard(context, data, units[0])))
|
||
pages.push(page(renderWeatherCard(context, data, units[1])))
|
||
|
||
await paginator.createPaginator({
|
||
context,
|
||
pages,
|
||
buttons: [{
|
||
customId: "next",
|
||
emoji: icon("button_thermometer"),
|
||
label: `Toggle ${unitNames[units[0]]}/${unitNames[units[1]]}`,
|
||
style: 2
|
||
}]
|
||
});
|
||
}catch(e){
|
||
console.log(e)
|
||
return editOrReply(context, createEmbed("warning", context, `No weather data available for given location.`))
|
||
}
|
||
}
|
||
}; |