from datetime import datetime import logging from typing import Any, Dict, List from discord import Embed from pymongo import DESCENDING from pytz import timezone from classes.enums import MessageEvents from classes.pycordbot import PycordBot from ujson import loads from modules.utils import hex_to_int from database import col_messages from modules.weather.parser import parse_weather # Example guild key # "forecast": { # "channel": 0, # "time": "10:00:00", # "delete_previous": true # "locations": [{"name": "Sample Location", "location": [10.000, 20.000]}], # } logger = logging.getLogger(__name__) async def report_weather( bot: PycordBot, guild: PycordGuild, # TODO channel_id: int, delete_previous: bool, locations: List[Dict[str, Any]], ) -> None: # sourcery skip: aware-datetime-for-utc channel = bot.get_channel(channel_id) if channel is None: logger.error( "Cannot generate weather report for %s's channel %s because channel was not found.", guild.id, channel_id, ) return # Find and delete previous forecast, if needed if delete_previous: async for event in col_messages.find( { "event": MessageEvents.WEATHER_FORECAST, "guild": guild.id, "channel": channel_id, }, limit=1, ).sort("date", direction=DESCENDING): try: old_message = bot.get_message(event["message"]) if old_message is not None: await old_message.delete( reason="Cleanup of the old weather report (look in guild config for details)" ) except Exception as exc: logger.warning( "Could not delete the previous weather report in %s' channel %s due to %s", guild.id, channel_id, exc, ) embeds: List[Embed] = [] # Iterate through the locations and request their forecasts. # Results must be parsed and added as embeds to the embeds lits. for location in locations: location_timezone_offset = ":".join( str( timezone(bot.config["bot"]["timezone"]).utcoffset(datetime.utcnow()) ).split(":")[:2] ) api_response = await ( await bot.client_session.get( f"https://api.openweathermap.org/data/2.5/onecall?lat={location['location'][0]}&lon={location['location'][1]}&exclude=minutely&units=metric&lang=uk&appid={bot.config['modules']['weather']['forecasts']['api_key']}&tz={location_timezone_offset}" ) ).json(loads=loads) parsed_weather = parse_weather(api_response) embeds.append( Embed( title=location["name"], description=parsed_weather, color=hex_to_int(guild.colors.default), ) ) # Add a trailing embed with OWM information embeds.append( Embed( title=bot._("weather_report_title", "embeds"), description=bot._("weather_report_description", "embeds"), color=hex_to_int(guild.colors.default), ) ) await channel.send( # type: ignore content=bot._("weather_report_content", "messages"), embeds=embeds )