Skip to content

Commit

Permalink
Include server icon in mention events, Enforce embed limits, Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanC committed Oct 12, 2024
1 parent 71b21d9 commit 71cc8c0
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 85 deletions.
4 changes: 2 additions & 2 deletions core/animals.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from loguru import logger

from core.formatters import Response
from core.utils import GET, Trim
from core.utils import GET


async def BunniesIO() -> Embed | None:
Expand Down Expand Up @@ -226,7 +226,7 @@ async def TheCatAPI() -> Embed | None:
name = f"{name} ({altNames})"

if desc := breed["description"]:
info = Trim(desc, 120)
info = desc

if origin := breed["origin"]:
if country := breed["country_code"]:
Expand Down
182 changes: 157 additions & 25 deletions core/formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from enum import Enum

from arc import (
GatewayClient,
GatewayContext,
SlashCommand,
SlashSubCommand,
Expand All @@ -12,12 +13,15 @@
from hikari import (
CommandInteractionOption,
Embed,
GatewayGuild,
Guild,
GuildChannel,
GuildThreadChannel,
PartialChannel,
PartialGuild,
PartialInteraction,
Role,
Snowflake,
TextableGuildChannel,
User,
)
Expand Down Expand Up @@ -48,7 +52,7 @@ def ExpandCommand(
"""Build a modular command string for the provided context."""

if (not hasattr(ctx, "command")) or (not ctx.command):
logger.debug("Failed to expand null command")
logger.debug("Command is null")

return "Unknown Command"

Expand Down Expand Up @@ -83,17 +87,24 @@ def ExpandCommand(
return result


def ExpandUser(
user: User | None,
async def ExpandUser(
user: User | Snowflake | None,
*,
mention: bool = False,
format: bool = True,
showId: bool = True,
client: GatewayClient | None = None,
) -> str:
"""Build a modular string for the provided user."""

if isinstance(user, Snowflake):
if client:
user = await client.rest.fetch_user(user)
else:
user = None

if not user:
logger.debug("Failed to expand null user")
logger.debug("User is null")

return "Unknown User"

Expand All @@ -118,13 +129,23 @@ def ExpandUser(
return result


def ExpandServer(
server: Guild | None, *, format: bool = True, showId: bool = True
async def ExpandServer(
server: Guild | PartialGuild | Snowflake | None,
*,
format: bool = True,
showId: bool = True,
client: GatewayClient | None = None,
) -> str:
"""Build a modular string for the provided server."""

if isinstance(server, Snowflake):
if client:
server = await client.rest.fetch_guild(server)
else:
server = None

if not server:
logger.debug("Failed to expand null server")
logger.debug("Server is null")

return "Unknown Server"

Expand All @@ -146,21 +167,29 @@ def ExpandServer(
return result


def ExpandChannel(
async def ExpandChannel(
channel: GuildChannel
| PartialChannel
| TextableGuildChannel
| GuildThreadChannel
| Snowflake
| None,
*,
mention: bool = False,
format: bool = True,
showId: bool = True,
client: GatewayClient | None = None,
) -> str:
"""Build a modular string for the provided channel."""

if isinstance(channel, Snowflake):
if client:
channel = await client.rest.fetch_channel(channel)
else:
channel = None

if not channel:
logger.debug("Failed to expand null channel")
logger.debug("Channel is null")

return "Unknown Channel"

Expand All @@ -174,9 +203,9 @@ def ExpandChannel(

if channel.name:
if format:
result += f"`{channel.name}`"
result += f"`#{channel.name}`"
else:
result += channel.name
result += f"\\#{channel.name}"

if showId:
if format:
Expand All @@ -199,7 +228,7 @@ def ExpandThread(
"""Build a modular string for the provided thread."""

if not thread:
logger.debug("Failed to expand null thread")
logger.debug("Thread is null")

return "Unknown Thread"

Expand Down Expand Up @@ -235,7 +264,7 @@ def ExpandRole(
"""Build a modular string for the provided role."""

if not role:
logger.debug("Failed to expand null role")
logger.debug("Role is null")

return "Unknown Role"

Expand Down Expand Up @@ -266,7 +295,7 @@ def ExpandInteraction(
"""Build a modular string for the provided interaction."""

if not interaction:
logger.debug("Failed to expand null interaction")
logger.debug("Interaction is null")

return "Unknown Interaction"

Expand All @@ -289,7 +318,7 @@ def ExpandInteraction(
return result.lstrip()


def GetAvatar(user: User) -> str | None:
def GetUserAvatar(user: User) -> str | None:
"""Return a URL for the provided Discord user's avatar."""

if user.avatar_url:
Expand All @@ -298,6 +327,41 @@ def GetAvatar(user: User) -> str | None:
return str(user.default_avatar_url)


async def GetServerIcon(
server: PartialGuild
| Guild
| GatewayGuild
| GuildChannel
| TextableGuildChannel
| GuildThreadChannel
| Snowflake
| None,
*,
client: GatewayClient | None = None,
) -> str | None:
"""Return a URL for the provided Discord server's icon."""

if isinstance(server, GuildChannel):
server = server.get_guild()
elif isinstance(server, TextableGuildChannel):
server = server.get_guild()
elif isinstance(server, GuildThreadChannel):
server = server.get_guild()
elif isinstance(server, Snowflake):
if client:
server = await client.rest.fetch_guild(server)
else:
server = None

if not server:
logger.debug("Guild is null")

return

if url := server.make_icon_url():
return str(url)


def RandomString(length: int) -> str:
"""
Generate a random string consisting of letters and numbers at the
Expand All @@ -322,18 +386,24 @@ def Response(
footerIcon: str | None = None,
timestamp: datetime | None = None,
) -> Embed:
"""Build a generic response Embed object."""
"""
Build a generic response Embed object.
All provided string values will be trimmed according to the embed
limits defined in the Discord API documentation.
https://discord.com/developers/docs/resources/message#embed-object-embed-limits
"""

result: Embed = Embed(
title=title,
description=description,
title=Trim(title, 256),
description=Trim(description, 4096),
url=url,
color=color,
timestamp=timestamp,
)

if author:
result.set_author(name=author, url=authorUrl, icon=authorIcon)
result.set_author(name=Trim(author, 256), url=authorUrl, icon=authorIcon)

if thumbnail:
result.set_thumbnail(thumbnail)
Expand All @@ -342,14 +412,38 @@ def Response(
result.set_image(image)

if footer:
result.set_footer(footer, icon=footerIcon)
result.set_footer(Trim(footer, 2048), icon=footerIcon)

for field in fields:
result.add_field(
str(field["name"]),
str(field["value"]),
inline=bool(field.get("inline", True)),
)
name: str | bool | None = field["name"]
value: str | bool | None = field["value"]

if not isinstance(name, str):
logger.warning(
f"Invalid value provided for field name: {name} ({type(name)})"
)

continue
elif not isinstance(value, str):
logger.warning(
f"Invalid value provided for field value: {value} ({type(value)})"
)

continue
if not (name := Trim(name, 256)):
logger.warning(
f"Invalid value provided for field name: {name} ({type(name)})"
)

continue
elif not (value := Trim(value, 1024)):
logger.warning(
f"Invalid value provided for field value: {value} ({type(value)})"
)

continue

result.add_field(name, value, inline=bool(field.get("inline", True)))

return result

Expand Down Expand Up @@ -413,3 +507,41 @@ def FormatOptions(options: list[CommandInteractionOption]) -> str:
logger.debug(f"Formatted options {options} to sequence {result}")

return result.rstrip()

def Trim(
input: str | None,
length: int,
*,
prefix: str | None = None,
suffix: str | None = "...",
) -> str | None:
"""Trim a string using the provided parameters."""

if not input:
return

# Account for length of prefix
if prefix:
length -= len(prefix)

# Account for length of suffix
if suffix:
length -= len(suffix)

if len(input) <= length:
return input

result: str = input[:length]

try:
result = result.rsplit(" ", 1)[0]
except Exception as e:
logger.opt(exception=e).debug("Failed to cleanly trim string")

if prefix:
result = prefix + result

if suffix:
result += suffix

return result
10 changes: 5 additions & 5 deletions core/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ async def HookLog(ctx: GatewayContext) -> None:
cfg: Config = ctx.client.get_type_dependency(Config)

command: str = ExpandCommand(ctx, format=False)
user: str = ExpandUser(ctx.user, format=False)
server: str = ExpandServer(ctx.get_guild(), format=False)
channel: str = ExpandChannel(ctx.get_channel(), format=False)
user: str = await ExpandUser(ctx.user, format=False)
server: str = await ExpandServer(ctx.get_guild(), format=False)
channel: str = await ExpandChannel(ctx.get_channel(), format=False)

logger.info(f"Command {command} used by {user} in {server} {channel}")

user: str = ExpandUser(ctx.user)
channel: str = ExpandChannel(ctx.get_channel())
user = await ExpandUser(ctx.user)
channel = await ExpandChannel(ctx.get_channel())

await ctx.client.rest.create_message(
cfg.channels["user"],
Expand Down
3 changes: 1 addition & 2 deletions core/reddit.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from loguru import logger

from core.formatters import Response
from core.utils import Trim


async def CreateClient() -> Reddit | None:
Expand Down Expand Up @@ -138,7 +137,7 @@ async def GetRandomImage(community: str) -> Embed | None:
return

return Response(
title=Trim(post.title, 128), # type: ignore
title=post.title, # type: ignore
url=f"https://reddit.com{post.permalink}", # type: ignore
image=post.url, # type: ignore
)
Expand Down
Loading

0 comments on commit 71cc8c0

Please sign in to comment.