3 Commits

Author SHA1 Message Date
e2c05f3bf6 WIP: #9 2024-02-19 23:09:00 +01:00
fe4dcc4a92 Message events initialized 2024-02-19 23:08:41 +01:00
d5691c2bbb Fixed scheduler-related issues 2024-02-19 23:07:38 +01:00
8 changed files with 143 additions and 1 deletions

View File

@@ -0,0 +1 @@
from .message_events import MessageEvents

View File

@@ -0,0 +1,5 @@
from enum import Enum
class MessageEvents(Enum):
WEATHER_FORECAST = 0

View File

@@ -14,6 +14,9 @@ class PycordBot(LibPycordBot):
self.client_session = ClientSession()
if self.scheduler is None:
return
# Scheduler job for DHL parcel tracking
self.scheduler.add_job(
update_tracks_dhl,
@@ -40,6 +43,8 @@ class PycordBot(LibPycordBot):
async def close(self, *args: Any, **kwargs: Any) -> None:
await self.client_session.close()
self.scheduler.shutdown()
if self.scheduler is not None:
self.scheduler.shutdown()
await super().close(*args, **kwargs)

View File

@@ -0,0 +1,9 @@
from dataclasses import dataclass
@dataclass
class PycordGuildColors:
default: str
success: str
warning: str
error: str

View File

@@ -24,6 +24,7 @@ db_client = AsyncClient(con_string)
db: AsyncDatabase = db_client.get_database(name=db_config["name"])
col_users: AsyncCollection = db.get_collection("users")
col_messages: AsyncCollection = db.get_collection("messages")
col_warnings: AsyncCollection = db.get_collection("warnings")
col_checkouts: AsyncCollection = db.get_collection("checkouts")
col_trackings: AsyncCollection = db.get_collection("trackings")

View File

@@ -0,0 +1,6 @@
def hex_to_int(hex_color: str) -> int:
return int(hex_color.lstrip("#"), 16)
def int_to_hex(integer_color: int) -> str:
return "#" + format(integer_color, "06x")

View File

@@ -0,0 +1,9 @@
from typing import Any, Dict
def parse_weather(api_response: Dict[str, Any]) -> str:
return ""
def parse_weather_current(api_response: Dict[str, Any]) -> str:
return ""

106
modules/weather/reporter.py Normal file
View File

@@ -0,0 +1,106 @@
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
)