Skip to content

Commit

Permalink
Implement guild configuration (#146)
Browse files Browse the repository at this point in the history
  • Loading branch information
No767 authored Jul 24, 2024
1 parent 179c3ba commit 9760ba2
Show file tree
Hide file tree
Showing 14 changed files with 1,116 additions and 170 deletions.
522 changes: 492 additions & 30 deletions bot/cogs/config.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bot/cogs/tickets.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ async def create_ticket(self, ticket: TicketThread) -> Optional[TicketOutput]:
]
processed_tags = [tag for tag in applied_tags if tag is not None]

content = f"({ticket.user.display_name}, {discord.utils.format_dt(ticket.created_at)})\n\n{ticket.content}"
content = f"({ticket.mention} - {ticket.user.display_name}, {discord.utils.format_dt(ticket.created_at)})\n\n{ticket.content}"
created_ticket = await tc.create_thread(
applied_tags=processed_tags,
name=ticket.title,
Expand Down
4 changes: 2 additions & 2 deletions bot/launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from aiohttp import ClientSession
from libs.utils import KeyboardInterruptHandler, RodhajLogger
from libs.utils.config import RodhajConfig
from rodhaj import Rodhaj
from rodhaj import Rodhaj, init

if os.name == "nt":
from winloop import run
Expand All @@ -27,7 +27,7 @@

async def main() -> None:
async with ClientSession() as session, asyncpg.create_pool(
dsn=POSTGRES_URI, min_size=25, max_size=25, command_timeout=30
dsn=POSTGRES_URI, min_size=25, max_size=25, init=init, command_timeout=30
) as pool:
async with Rodhaj(
config=config, intents=intents, session=session, pool=pool
Expand Down
1 change: 1 addition & 0 deletions bot/libs/tickets/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class TicketThread(msgspec.Struct):
title: str
user: Union[discord.User, discord.Member]
location_id: int
mention: str
content: str
tags: list[str]
files: list[discord.File]
Expand Down
41 changes: 41 additions & 0 deletions bot/libs/tickets/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
if TYPE_CHECKING:
from libs.utils.context import RoboContext

from bot.cogs.config import Config
from bot.cogs.tickets import Tickets
from bot.rodhaj import Rodhaj

Expand Down Expand Up @@ -133,6 +134,7 @@ def __init__(
bot: Rodhaj,
ctx: RoboContext,
cog: Tickets,
config_cog: Config,
content: str,
guild: discord.Guild,
delete_after: bool = True,
Expand All @@ -142,6 +144,7 @@ def __init__(
self.bot = bot
self.ctx = ctx
self.cog = cog
self.config_cog = config_cog
self.content = content
self.guild = guild
self.delete_after = delete_after
Expand All @@ -162,6 +165,18 @@ async def delete_response(self, interaction: discord.Interaction):

self.stop()

async def get_or_fetch_member(self, member_id: int) -> Optional[discord.Member]:
member = self.guild.get_member(member_id)
if member is not None:
return member

members = await self.guild.query_members(
limit=1, user_ids=[member_id], cache=True
)
if not members:
return None
return members[0]

@discord.ui.button(
label="Checklist",
style=discord.ButtonStyle.primary,
Expand Down Expand Up @@ -228,6 +243,31 @@ async def confirm(

applied_tags = [k for k, v in tags.items() if v is True]

guild_settings = await self.config_cog.get_guild_settings(self.guild.id)
potential_member = await self.get_or_fetch_member(author.id)

if not guild_settings:
await interaction.response.send_message(
"Unable to find guild settings", ephemeral=True
)
return

if (self.guild.created_at - interaction.created_at) < guild_settings.guild_age:
await interaction.response.send_message(
"The guild is too young in order to utilize Rodhaj.", ephemeral=True
)
return
elif (
potential_member
): # Since we are checking join times, if we don't have the proper member, we can only skip it.
joined_at = potential_member.joined_at or discord.utils.utcnow()
if (joined_at - interaction.created_at) < guild_settings.account_age:
await interaction.response.send_message(
"This account joined the server too soon in order to utilize Rodhaj.",
ephemeral=True,
)
return

if not status.title.is_set() or not status.tags.is_set():
dict_status = {"title": status.title, "tags": status.tags}
formatted_status = "\n".join(
Expand Down Expand Up @@ -255,6 +295,7 @@ async def confirm(
title=title,
user=author,
location_id=self.guild.id,
mention=guild_settings.mention,
content=self.content,
tags=applied_tags,
files=files,
Expand Down
37 changes: 37 additions & 0 deletions bot/libs/utils/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pathlib import Path
from typing import Any, Generic, Optional, TypeVar, Union, overload

import orjson
import yaml

_T = TypeVar("_T")
Expand Down Expand Up @@ -44,3 +45,39 @@ def __len__(self) -> int:

def all(self) -> dict[str, Union[_T, Any]]:
return self._config


class OptionsHelp(Generic[_T]):
def __init__(self, path: Path):
self.path = path
self._config: dict[str, Union[_T, Any]] = {}
self.load_from_file()

def load_from_file(self) -> None:
try:
with open(self.path, "r") as f:
self._config: dict[str, Union[_T, Any]] = orjson.loads(f.read())
except FileNotFoundError:
self._config = {}

@overload
def get(self, key: Any) -> Optional[Union[_T, Any]]: ...

@overload
def get(self, key: Any, default: Any) -> Union[_T, Any]: ...

def get(self, key: Any, default: Any = None) -> Optional[Union[_T, Any]]:
"""Retrieves a config entry."""
return self._config.get(str(key), default)

def __contains__(self, item: Any) -> bool:
return str(item) in self._config

def __getitem__(self, item: Any) -> Union[_T, Any]:
return self._config[str(item)]

def __len__(self) -> int:
return len(self._config)

def all(self) -> dict[str, Union[_T, Any]]:
return self._config
Loading

0 comments on commit 9760ba2

Please sign in to comment.