bot: types: add types package
This package collects all kinds of useful type definitions that will aid me in development. Some things could be expanded in the future when they become necessary (e.g. poll result embeds), but for now this should be enough. Signed-off-by: Max R. Carrara <max@aequito.sh>
This commit is contained in:
parent
8ffe964386
commit
52d619377e
3 changed files with 227 additions and 0 deletions
41
src/bot/types/__init__.py
Normal file
41
src/bot/types/__init__.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
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))
|
||||
166
src/bot/types/embed.py
Normal file
166
src/bot/types/embed.py
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
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
|
||||
)
|
||||
20
src/bot/types/timestamp.py
Normal file
20
src/bot/types/timestamp.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
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