Compare commits
No commits in common. "e71558959c8930e3af90b109776c96b2c2415400" and "1dfa03bc175d259b01ebe26ee80fa0fcce1aac5d" have entirely different histories.
e71558959c
...
1dfa03bc17
5 changed files with 6 additions and 289 deletions
|
|
@ -1,43 +0,0 @@
|
||||||
import asyncio
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import discord
|
|
||||||
from discord.ext import commands
|
|
||||||
|
|
||||||
from bot.types import RichEmbed
|
|
||||||
|
|
||||||
_log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class Debug(commands.Cog):
|
|
||||||
def __init__(self, bot: commands.Bot) -> None:
|
|
||||||
self.bot = bot
|
|
||||||
|
|
||||||
@commands.command()
|
|
||||||
async def ping(self, ctx: commands.Context):
|
|
||||||
_log.debug("pong!")
|
|
||||||
|
|
||||||
embed: RichEmbed = {
|
|
||||||
"type": "rich",
|
|
||||||
"description": "Pong."
|
|
||||||
}
|
|
||||||
|
|
||||||
await ctx.send(embed=discord.Embed.from_dict(embed))
|
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot: commands.Bot):
|
|
||||||
_log.debug("Adding Debug cog")
|
|
||||||
await bot.add_cog(Debug(bot))
|
|
||||||
|
|
||||||
cog = bot.get_cog(Debug.__name__)
|
|
||||||
|
|
||||||
if cog is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
_log.debug("Loaded Debug cog with the following commands:")
|
|
||||||
_log.debug([c.name for c in cog.get_commands()])
|
|
||||||
|
|
||||||
|
|
||||||
async def teardown(bot: commands.Bot):
|
|
||||||
_log.debug("Removing Debug cog")
|
|
||||||
await bot.remove_cog(Debug.__name__)
|
|
||||||
|
|
@ -11,14 +11,11 @@ from discord.ext import commands
|
||||||
from bot.env import Environment
|
from bot.env import Environment
|
||||||
|
|
||||||
|
|
||||||
_log = logging.getLogger(__name__)
|
_log: logging.Logger
|
||||||
_default_extensions: dict[str, str] = {
|
|
||||||
"Debug": "bot.cogs.debug",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def setup_logging():
|
def setup_logging() -> logging.Logger:
|
||||||
root_logger = logging.getLogger()
|
root_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
log_level_map = {
|
log_level_map = {
|
||||||
"NOTSET": logging.NOTSET,
|
"NOTSET": logging.NOTSET,
|
||||||
|
|
@ -60,6 +57,8 @@ def setup_logging():
|
||||||
log_error_file_handler.setLevel(logging.ERROR)
|
log_error_file_handler.setLevel(logging.ERROR)
|
||||||
root_logger.addHandler(log_error_file_handler)
|
root_logger.addHandler(log_error_file_handler)
|
||||||
|
|
||||||
|
return root_logger
|
||||||
|
|
||||||
|
|
||||||
def setup_bot() -> commands.Bot:
|
def setup_bot() -> commands.Bot:
|
||||||
intents = discord.Intents.all()
|
intents = discord.Intents.all()
|
||||||
|
|
@ -130,17 +129,6 @@ def register_event_handlers(bot: commands.Bot):
|
||||||
async def on_ready():
|
async def on_ready():
|
||||||
_log.info("Ready: Connected to Discord")
|
_log.info("Ready: Connected to Discord")
|
||||||
|
|
||||||
_log.info("Loading extensions")
|
|
||||||
for ext_name, ext_path in _default_extensions.items():
|
|
||||||
try:
|
|
||||||
_log.info(f'Loading extension "{ext_name}" ({ext_path})')
|
|
||||||
await bot.load_extension(ext_path)
|
|
||||||
_log.info(f'Loaded extension "{ext_name}" ({ext_path})')
|
|
||||||
except Exception as e:
|
|
||||||
_log.error(
|
|
||||||
f'Failed to load extension "{ext_name}" ({ext_path})', exc_info=e
|
|
||||||
)
|
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_resumed():
|
async def on_resumed():
|
||||||
_log.info("Resumed: Session with Discord resumed")
|
_log.info("Resumed: Session with Discord resumed")
|
||||||
|
|
@ -156,7 +144,6 @@ def register_event_handlers(bot: commands.Bot):
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_message(message: discord.Message):
|
async def on_message(message: discord.Message):
|
||||||
_log.debug(f"Read message ({message.id = }): {message.content}")
|
_log.debug(f"Read message ({message.id = }): {message.content}")
|
||||||
await bot.process_commands(message)
|
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_command(ctx: commands.Context):
|
async def on_command(ctx: commands.Context):
|
||||||
|
|
@ -194,7 +181,7 @@ async def main():
|
||||||
await bot.start(token=token, reconnect=True)
|
await bot.start(token=token, reconnect=True)
|
||||||
|
|
||||||
|
|
||||||
setup_logging()
|
_log = setup_logging()
|
||||||
_log.debug("Logging initialised")
|
_log.debug("Logging initialised")
|
||||||
|
|
||||||
_log.debug(f"{sys.argv = }")
|
_log.debug(f"{sys.argv = }")
|
||||||
|
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
from datetime import date, datetime, timezone
|
|
||||||
|
|
||||||
from .embed import (
|
|
||||||
Embed,
|
|
||||||
RichEmbed,
|
|
||||||
ImageEmbed,
|
|
||||||
VideoEmbed,
|
|
||||||
GifvEmbed,
|
|
||||||
ArticleEmbed,
|
|
||||||
LinkEmbed,
|
|
||||||
)
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"Embed",
|
|
||||||
"RichEmbed",
|
|
||||||
"ImageEmbed",
|
|
||||||
"VideoEmbed",
|
|
||||||
"GifvEmbed",
|
|
||||||
"ArticleEmbed",
|
|
||||||
"LinkEmbed",
|
|
||||||
"ISO8601Timestamp",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class ISO8601Timestamp:
|
|
||||||
def __init__(self, dt: date | datetime) -> None:
|
|
||||||
self.dt = dt
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return self.dt.isoformat()
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return f"ISO8601Timestamp({repr(self.dt)})"
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def today(cls):
|
|
||||||
return cls(date.today())
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def now(cls, tz: timezone | None):
|
|
||||||
return cls(datetime.now(tz))
|
|
||||||
|
|
@ -1,166 +0,0 @@
|
||||||
from typing import Annotated, Literal, TypedDict
|
|
||||||
from annotated_types import Len
|
|
||||||
|
|
||||||
import discord
|
|
||||||
|
|
||||||
from .timestamp import ISO8601Timestamp
|
|
||||||
|
|
||||||
|
|
||||||
class _EmbedFooterReq(TypedDict):
|
|
||||||
text: str
|
|
||||||
|
|
||||||
|
|
||||||
class _EmbedFooterOpt(TypedDict, total=False):
|
|
||||||
icon_url: str
|
|
||||||
proxy_icon_url: str
|
|
||||||
|
|
||||||
|
|
||||||
class EmbedFooter(_EmbedFooterReq, _EmbedFooterOpt):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class _EmbedImageReq(TypedDict):
|
|
||||||
url: str
|
|
||||||
|
|
||||||
|
|
||||||
class _EmbedImageOpt(TypedDict, total=False):
|
|
||||||
proxy_url: str
|
|
||||||
height: int
|
|
||||||
width: int
|
|
||||||
|
|
||||||
|
|
||||||
class EmbedImage(_EmbedImageReq, _EmbedImageOpt):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class _EmbedThumbnailReq(TypedDict):
|
|
||||||
url: str
|
|
||||||
|
|
||||||
|
|
||||||
class _EmbedThumbnailOpt(TypedDict, total=False):
|
|
||||||
proxy_url: str
|
|
||||||
height: int
|
|
||||||
width: int
|
|
||||||
|
|
||||||
|
|
||||||
class EmbedThumbnail(_EmbedThumbnailReq, _EmbedThumbnailOpt):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class EmbedVideo(TypedDict, total=False):
|
|
||||||
url: str
|
|
||||||
proxy_url: str
|
|
||||||
height: int
|
|
||||||
width: int
|
|
||||||
|
|
||||||
|
|
||||||
class EmbedProvider(TypedDict, total=False):
|
|
||||||
name: str
|
|
||||||
url: str
|
|
||||||
|
|
||||||
|
|
||||||
class EmbedAuthor(TypedDict, total=False):
|
|
||||||
name: str
|
|
||||||
url: str
|
|
||||||
icon_url: str
|
|
||||||
proxy_icon_url: str
|
|
||||||
|
|
||||||
|
|
||||||
class _EmbedFieldReq(TypedDict):
|
|
||||||
name: str
|
|
||||||
value: str
|
|
||||||
|
|
||||||
|
|
||||||
class _EmbedFieldOpt(TypedDict, total=False):
|
|
||||||
inline: bool
|
|
||||||
|
|
||||||
|
|
||||||
class EmbedField(_EmbedFieldReq, _EmbedFieldOpt):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class _EmbedBase(TypedDict, total=False):
|
|
||||||
title: str
|
|
||||||
description: str
|
|
||||||
url: str
|
|
||||||
timestamp: ISO8601Timestamp
|
|
||||||
color: discord.Colour | int
|
|
||||||
footer: EmbedFooter
|
|
||||||
image: EmbedImage
|
|
||||||
thumbnail: EmbedThumbnail
|
|
||||||
video: EmbedVideo
|
|
||||||
provider: EmbedProvider
|
|
||||||
author: EmbedAuthor
|
|
||||||
fields: Annotated[list[EmbedField], Len(max_length=25)]
|
|
||||||
|
|
||||||
|
|
||||||
class RichEmbedImpl(TypedDict):
|
|
||||||
type: Literal["rich"]
|
|
||||||
|
|
||||||
|
|
||||||
class RichEmbed(_EmbedBase, RichEmbedImpl):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ImageEmbedImpl(TypedDict):
|
|
||||||
type: Literal["image"]
|
|
||||||
|
|
||||||
|
|
||||||
class ImageEmbed(_EmbedBase, ImageEmbedImpl):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class VideoEmbedImpl(TypedDict):
|
|
||||||
type: Literal["video"]
|
|
||||||
|
|
||||||
|
|
||||||
class VideoEmbed(_EmbedBase, VideoEmbedImpl):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class GifvEmbedImpl(TypedDict):
|
|
||||||
type: Literal["givf"]
|
|
||||||
|
|
||||||
|
|
||||||
class GifvEmbed(_EmbedBase, GifvEmbedImpl):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ArticleEmbedImpl(TypedDict):
|
|
||||||
type: Literal["article"]
|
|
||||||
|
|
||||||
|
|
||||||
class ArticleEmbed(_EmbedBase, ArticleEmbedImpl):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class LinkEmbedImpl(TypedDict):
|
|
||||||
type: Literal["link"]
|
|
||||||
|
|
||||||
|
|
||||||
class LinkEmbed(_EmbedBase, LinkEmbedImpl):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class PollResultEmbedImpl(TypedDict):
|
|
||||||
type: Literal["poll_result"]
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: There are a bunch of fields for poll results, but I *really*
|
|
||||||
# don't need these at the moment:
|
|
||||||
# https://discord.com/developers/docs/resources/message#embed-fields-by-embed-type-poll-result-embed-fields
|
|
||||||
|
|
||||||
|
|
||||||
class PollResultEmbed(_EmbedBase, PollResultEmbedImpl):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
Embed = (
|
|
||||||
RichEmbed
|
|
||||||
| ImageEmbed
|
|
||||||
| VideoEmbed
|
|
||||||
| GifvEmbed
|
|
||||||
| ArticleEmbed
|
|
||||||
| LinkEmbed
|
|
||||||
| PollResultEmbed
|
|
||||||
)
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
from datetime import date, datetime, timezone
|
|
||||||
|
|
||||||
|
|
||||||
class ISO8601Timestamp:
|
|
||||||
def __init__(self, dt: date | datetime) -> None:
|
|
||||||
self.dt = dt
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return self.dt.isoformat()
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return f"ISO8601Timestamp({repr(self.dt)})"
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def today(cls):
|
|
||||||
return cls(date.today())
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def now(cls, tz: timezone | None):
|
|
||||||
return cls(datetime.now(tz))
|
|
||||||
Loading…
Add table
Reference in a new issue