Skip to content
This repository was archived by the owner on Feb 7, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7fed9ae
Add weather commands to a new cog
notsniped May 22, 2023
8a09997
Add new commands to commands db
notsniped May 22, 2023
1d91b4c
Add `async` keyword for `weather()` and `weather_set_location()`
notsniped May 23, 2023
835371e
Add weather cog to `active_cogs` list on bot init
notsniped May 23, 2023
5bc2cdf
Add `self` parameter in `weather()` and `weather_set_location()`
notsniped May 23, 2023
b79f982
Add `respond()` to send embed after `/weather` successfully executed
notsniped May 23, 2023
6faabe0
Convert `author.id` type to `str` for db key-matching
notsniped May 23, 2023
e92eab3
Add API request error code handling in `/weather`
notsniped May 23, 2023
352b502
Fix typo where list index for `forcast` & `forcast_description` were …
notsniped May 23, 2023
8929a72
Fix arithmetic error while converting `temp`, `temp_min` and `temp_ma…
notsniped May 23, 2023
88517e5
`round()` temperature values
notsniped May 23, 2023
2264285
Convert `humidity` from 2-decimal float to integer
notsniped May 23, 2023
c8e8fb8
Remove `rain_chance` as it is a dynamic response
notsniped May 23, 2023
8d729ba
Change response embed color from `light_blue` to `blue`
notsniped May 23, 2023
efbbfc9
Move `sunset` embed field before `sunrise` embed field
notsniped May 23, 2023
054765a
Move `sunset` and `sunrise` embed fields to single line
notsniped May 23, 2023
f49e512
Add country flag emoji next to location name in weather embed
notsniped May 23, 2023
04fd75e
Add missing parent key in country data
notsniped May 23, 2023
477e905
Remove `()` between flag display emoji
notsniped May 23, 2023
cdfacac
Update weather database format to support temp scale setting
notsniped May 23, 2023
93a7597
Add scale unit settings checking and conversion in `/weather`
notsniped May 23, 2023
6af5b0a
Add `/weather_set_scale` to allow users to set their preferred unit s…
notsniped May 23, 2023
38e9c50
Update unit scale capitalization
notsniped May 23, 2023
a99c49a
Fix missing argument name in embed color configuration
notsniped May 23, 2023
fd9828b
Update unit scale capitalization
notsniped May 23, 2023
ea582fd
Fix a small logical error in `/weather_set_scale`
notsniped May 23, 2023
12738d2
Add `/weather_set_scale` to commands db
notsniped May 24, 2023
918caea
Fix name and description for `/weather_set_location` command in comma…
notsniped May 24, 2023
508240e
Fix args in `/weather_set_scale` command in commands db
notsniped May 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions cogs/weather.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Imports
import discord
import json
import requests
from discord import ApplicationContext, option
from discord.ext import commands

# Variables
api_key = "21cab08deb7b27f4c2b55f3e2df28ea4"
with open("database/weather.json", 'r', encoding="utf-8") as f: user_db = json.load(f)

# Functions
def save():
"""Dumps all cached databases to storage."""
with open("database/weather.json", 'w+', encoding="utf-8") as f: json.dump(user_db, f, indent=4)

# Commands
class Weather(commands.Cog):
def __init__(self, bot):
self.bot = bot

@commands.slash_command(
name="weather_set_location",
description="Set your default location for the /weather command."
)
@option(name="location", description="What location do you want to set?", type=str)
async def weather_set_location(self, ctx: ApplicationContext, location: str):
if str(ctx.author.id) not in user_db: user_db[str(ctx.author.id)] = {"location": None, "scale": "Celsius"}
test_ping = requests.get(f"https://api.openweathermap.org/data/2.5/weather?q={location}&appid={api_key}").content
test_ping_json = json.loads(test_ping)
if test_ping_json["cod"] == 404: return await ctx.respond(":warning: This location does not exist.", ephemeral=True)
else:
user_db[str(ctx.author.id)]["location"] = location.lower()
save()
localembed = discord.Embed(description="Your default location has been updated.", color=discord.Color.green())
await ctx.respond(embed=localembed)

@commands.slash_command(
name="weather_set_scale",
description="Set your preferred unit scale for temperature for the /weather command."
)
@option(name="scale", description="Which scale do you want to use?", type=str, choices=["Celsius", "Fahrenheit", "Kelvin"])
async def weather_set_scale(self, ctx: ApplicationContext, scale: str):
if str(ctx.author.id) not in user_db: user_db[str(ctx.author.id)] = {"location": None, "scale": "Celsius"}
if scale not in ["Celsius", "Fahrenheit", "Kelvin"]: return 1
user_db[str(ctx.author.id)]["scale"] = scale
save()
localembed = discord.Embed(description="Your preferred unit scale has been updated.", color=discord.Color.green())
await ctx.respond(embed=localembed)

@commands.slash_command(
name="weather",
description="See the current weather conditions of your set location, or another location."
)
@option(name="location", description="The location you want weather info about (leave empty for set location)", type=str, default=None)
async def weather(self, ctx: ApplicationContext, location: str = None):
if str(ctx.author.id) not in user_db: user_db[str(ctx.author.id)] = {"location": None, "scale": "Celsius"}
if location == None:
if user_db[str(ctx.author.id)]["location"] == None: return await ctx.respond("You do not have a default location set yet.\nEnter a location name and try again.", ephemeral=True)
else: location = user_db[str(ctx.author.id)]["location"]
api_request = requests.get(f"https://api.openweathermap.org/data/2.5/weather?q={location}&appid={api_key}").content
req: dict = json.loads(api_request)
print(req)
if req["cod"] == 404: return await ctx.respond(":x: This location was not found. Check your spelling or try another location instead.", ephemeral=True)
elif req["cod"] != 200: return await ctx.respond("A slight problem occured when trying to get information. This error has been automatically reported to the devs.", ephemeral=True)
else: pass

# Stripped API request data
loc_name = req["name"]
if user_db[str(ctx.author.id)]["scale"] == "Celsius":
temp = round(req["main"]["temp"] - 273)
temp_max = round(req["main"]["temp_max"] - 273)
temp_min = round(req["main"]["temp_min"] - 273)
elif user_db[str(ctx.author.id)]["scale"] == "Fahrenheit":
temp = round(((req["main"]["temp"] - 273) * 9/5) + 32)
temp_max = round(((req["main"]["temp_max"] - 273) * 9/5) + 32)
temp_min = round(((req["main"]["temp_min"] - 273) * 9/5) + 32)
else:
temp = round(req["main"]["temp"])
temp_max = round(req["main"]["temp_max"])
temp_min = round(req["main"]["temp_min"])
humidity = req["main"]["humidity"]
sunset = req["sys"]["sunrise"]
sunrise = req["sys"]["sunset"]
forcast = req["weather"][0]["main"]
forcast_description = req["weather"][0]["description"]

localembed = discord.Embed(
title=f"Weather for {loc_name} :flag_{req['sys']['country'].lower()}:",
description=f"**{forcast}**\n{forcast_description}",
color=discord.Color.blue()
)
if user_db[str(ctx.author.id)]["scale"] == "Celsius": localembed.add_field(name="Temperature", value=f"**{temp}C** (max: {temp_max}C, min: {temp_min}C)")
elif user_db[str(ctx.author.id)]["scale"] == "Fahrenheit": localembed.add_field(name="Temperature", value=f"**{temp}F** (max: {temp_max}F, min: {temp_min}F)")
else: localembed.add_field(name="Temperature", value=f"**{temp}K** (max: {temp_max}K, min: {temp_min}K)")
localembed.add_field(name="Humidity", value=f"{humidity}%")
localembed.add_field(name="Sunrise", value=f"<t:{sunrise}:f>", inline=False)
localembed.add_field(name="Sunset", value=f"<t:{sunset}:f>", inline=True)
await ctx.respond(embed=localembed)

# Initialization
def setup(bot): bot.add_cog(Weather(bot))
30 changes: 30 additions & 0 deletions config/commands.json
Original file line number Diff line number Diff line change
Expand Up @@ -658,5 +658,35 @@
"usable_by": "everyone",
"disabled": false,
"bugged": false
},
"weather": {
"name": "Weather",
"description": "See the current weather conditions of your set location, or another location.",
"type": "weather",
"cooldown": null,
"args": ["location (optional, configurable by /weather_set_location)"],
"usable_by": "everyone",
"disabled": false,
"bugged": false
},
"weather_set_location": {
"name": "Set weather default location",
"description": "Set your default location for the `/weather` command.",
"type": "weather",
"cooldown": null,
"args": ["location"],
"usable_by": "everyone",
"disabled": false,
"bugged": false
},
"weather_set_scale": {
"name": "Set weather temperature unit scale",
"description": "Set your preferred unit scale for temperature for the `/weather` command.",
"type": "weather",
"cooldown": null,
"args": ["scale"],
"usable_by": "everyone",
"disabled": false,
"bugged": false
}
}
1 change: 1 addition & 0 deletions database/weather.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
3 changes: 2 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,8 @@ async def reload(ctx: ApplicationContext, cog: str):
"fun",
"utils",
"afk",
"osu"
"osu",
"weather"
]
i = 1
cog_errors = 0
Expand Down