Skip to content

Commit

Permalink
🛠️Some work
Browse files Browse the repository at this point in the history
  • Loading branch information
Aluerie committed Feb 11, 2025
1 parent c72b149 commit 0d01801
Show file tree
Hide file tree
Showing 16 changed files with 87 additions and 77 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"emotestats",
"EUNE",
"notifs",
"pepoblanket",
"prpl",
"roleidentification",
"subscopes",
Expand Down
6 changes: 2 additions & 4 deletions core/help_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,18 +267,16 @@ def get_command_short_help(self, command: AluCommand) -> str:
help_str = command.help or "No documentation"
split = help_str.split("\n", 1)
extra_info = " [...]" if len(split) > 1 else ""
help_str = split[0] + extra_info
return help_str
return split[0] + extra_info

@override
def get_bot_mapping(self) -> dict[ExtCategory, dict[AluCog, list[AluCommand]]]:
"""Retrieves the bot mapping passed to `send_bot_help`."""
# TODO: include solo slash commands and Context Menu commands.
categories = self.context.bot.category_cogs

mapping = {category: {cog: cog.get_commands() for cog in cog_list} for category, cog_list in categories.items()}
return {category: {cog: cog.get_commands() for cog in cog_list} for category, cog_list in categories.items()}
# todo: think how to sort front page to front
return mapping

async def send_help_menu(
self,
Expand Down
2 changes: 2 additions & 0 deletions examples/beta/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
if TYPE_CHECKING:
from collections.abc import Callable, Coroutine, Sequence

from bot import AluInteraction


log = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion examples/beta/beta.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ async def beta_task(self) -> None:
pass

@app_commands.command()
async def slash(self, interaction: discord.Interaction[AluBot]) -> None:
async def slash(self, interaction: AluInteraction) -> None:
await interaction.response.send_message("slash")


Expand Down
57 changes: 31 additions & 26 deletions ext/community/confessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,30 @@
from discord.ext import commands

from bot import AluModal, AluView
from utils.const import Colour, Emote
from utils.fmt import human_timedelta
from utils import const, fmt

from ._base import CommunityCog

if TYPE_CHECKING:
from bot import AluBot
from bot import AluBot, AluInteraction


class ButtonOnCooldown(commands.CommandError):
def __init__(self, retry_after: float) -> None:
self.retry_after: float = retry_after


def key(interaction: discord.Interaction) -> discord.User | discord.Member:
def key(interaction: AluInteraction) -> discord.User | discord.Member:
return interaction.user


# rate of 1 token per 30 minutes using our key function
cd = commands.CooldownMapping.from_cooldown(1.0, 30.0 * 60, key)


class ConfModal(AluModal):
class ConfessionModal(AluModal):
"""Modal to make a confession."""

def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)

Expand All @@ -40,29 +41,37 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
)

@override
async def on_submit(self, interaction: discord.Interaction) -> None:
embed = discord.Embed(title=self.title, colour=Colour.prpl, description=self.conf.value)
async def on_submit(self, interaction: AluInteraction) -> None:
embed = discord.Embed(title=self.title, colour=const.Colour.prpl, description=self.conf.value)
if self.title == "Non-anonymous confession":
embed.set_author(name=interaction.user.display_name, icon_url=interaction.user.display_avatar.url)
channel = interaction.channel
assert isinstance(channel, discord.TextChannel)

await channel.send(embeds=[embed])
saint_string = "{0} {0} {0} {1} {1} {1} {2} {2} {2}".format(Emote.bubuChrist, "\N{CHURCH}", Emote.PepoBeliever)
saint_string = (
f"{const.Emote.bubuChrist} {const.Emote.bubuChrist} {const.Emote.bubuChrist} "
"\N{CHURCH} \N{CHURCH} \N{CHURCH} "
f"{const.Emote.PepoBeliever} {const.Emote.PepoBeliever} {const.Emote.PepoBeliever}"
)
await channel.send(saint_string)
await interaction.response.send_message(content=f"The Lord be with you {Emote.PepoBeliever}", ephemeral=True)
await interaction.response.send_message(
content=f"The Lord be with you {const.Emote.PepoBeliever}", ephemeral=True
)
if interaction.message:
await interaction.message.delete()
await channel.send(view=ConfView())
await channel.send(view=ConfessionView())
cd.update_rate_limit(interaction)


class ConfView(AluView):
class ConfessionView(AluView):
"""View with buttons to make confessions."""

def __init__(self) -> None:
super().__init__(author_id=None, timeout=None)

@override
async def interaction_check(self, interaction: discord.Interaction) -> bool:
async def interaction_check(self, interaction: AluInteraction) -> bool:
# retry_after = self.cd.update_rate_limit(ntr) # returns retry_after which is nice
bucket = cd.get_bucket(interaction)
if bucket and (retry_after := bucket.get_retry_after()):
Expand All @@ -77,39 +86,35 @@ async def on_error(
item: discord.ui.Item[Self],
) -> None:
if isinstance(error, ButtonOnCooldown):
e = discord.Embed(
colour=Colour.error,
description=(
f"Sorry, you are on cooldown \nTime left `{human_timedelta(error.retry_after, mode='brief')}`"
),
).set_author(name=error.__class__.__name__)
await interaction.response.send_message(embed=e, ephemeral=True)
msg = f"Sorry, you are on cooldown \nTime left `{fmt.human_timedelta(error.retry_after, mode='brief')}`"
embed = discord.Embed(colour=const.Colour.error, description=msg).set_author(name=error.__class__.__name__)
await interaction.response.send_message(embed=embed, ephemeral=True)
else:
await super().on_error(interaction, error, item)

@discord.ui.button(
label="Anonymous confession",
custom_id="anonconf-button",
style=discord.ButtonStyle.primary,
emoji=Emote.bubuChrist,
emoji=const.Emote.bubuChrist,
)
async def button0_callback(self, interaction: discord.Interaction, button: discord.ui.Button[Self]) -> None:
await interaction.response.send_modal(ConfModal(title=button.label))
async def button0_callback(self, interaction: AluInteraction, button: discord.ui.Button[Self]) -> None:
await interaction.response.send_modal(ConfessionModal(title=button.label))

@discord.ui.button(
label="Non-anonymous confession",
custom_id="nonanonconf-button",
style=discord.ButtonStyle.primary,
emoji=Emote.PepoBeliever,
emoji=const.Emote.PepoBeliever,
)
async def button1_callback(self, interaction: discord.Interaction, button: discord.ui.Button[Self]) -> None:
await interaction.response.send_modal(ConfModal(title=button.label))
async def button1_callback(self, interaction: AluInteraction, button: discord.ui.Button[Self]) -> None:
await interaction.response.send_modal(ConfessionModal(title=button.label))


class Confession(CommunityCog):
@commands.Cog.listener()
async def on_ready(self) -> None:
self.bot.add_view(ConfView()) # Registers a View for persistent listening
self.bot.add_view(ConfessionView()) # Registers a View for persistent listening

# very silly testing way
# print('hello')
Expand Down
18 changes: 11 additions & 7 deletions ext/community/emote_spam.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,18 @@ async def delete_the_message(self, message: discord.Message) -> None:
await message.delete()
except discord.NotFound:
return
channel: discord.TextChannel = message.channel # type: ignore # emote_spam channel is secured
answer_text = f"{message.author.mention}, you are NOT allowed to use non-emotes in {channel.mention}. Emote-only channel ! {const.Emote.Ree} {const.Emote.Ree} {const.Emote.Ree}"
channel: discord.TextChannel = message.channel # type: ignore[reportAssignmentType] # emote_spam channel is secured
answer_text = (
f"{message.author.mention}, you are NOT allowed to use non-emotes in {channel.mention}. "
f"Emote-only channel ! {const.Emote.Ree} {const.Emote.Ree} {const.Emote.Ree}"
)
embed = discord.Embed(
title="Deleted message",
description=message.content,
color=const.Colour.error,
).set_author(name=message.author.display_name, icon_url=message.author.display_avatar.url)
if s := message.stickers:
embed.set_thumbnail(url=s[0].url)
if stickers := message.stickers:
embed.set_thumbnail(url=stickers[0].url)
await self.bot.community.bot_spam.send(answer_text, embed=embed)

async def emote_spam_work(self, message: discord.Message) -> None:
Expand Down Expand Up @@ -174,7 +177,7 @@ async def cog_unload(self) -> None:
async def comfy_chat_control(self, message: discord.Message) -> Literal[0, 1] | None:
"""Check if messages in #comfy-spam consists only out of emotes."""
if message.channel.id == const.Channel.comfy_spam:
channel: discord.TextChannel = message.channel # type: ignore
channel: discord.TextChannel = message.channel # type: ignore[reportAssignmentType]
if len(message.embeds):
await message.delete()
return None
Expand All @@ -184,15 +187,16 @@ async def comfy_chat_control(self, message: discord.Message) -> Literal[0, 1] |
text = text.replace(item, "")
if text:
answer_text = (
f"{message.author.mention}, you are NOT allowed to use anything but truly the only one comfy-emote in {channel.mention} ! "
f"{const.Emote.Ree} {const.Emote.Ree} {const.Emote.Ree}"
f"{message.author.mention}, you are NOT allowed to use anything but truly the only one comfy-emote "
f"in {channel.mention} ! {const.Emote.Ree} {const.Emote.Ree} {const.Emote.Ree}"
)
e = discord.Embed(title="Deleted message", description=message.content, color=const.Colour.prpl)
e.set_author(name=message.author.display_name, icon_url=message.author.display_avatar.url)
await self.bot.community.bot_spam.send(answer_text, embed=e)
await message.delete()
return 1
return 0
return None

@commands.Cog.listener()
async def on_message(self, message: discord.Message) -> None:
Expand Down
2 changes: 1 addition & 1 deletion ext/community/old_timers.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class DailyEmbedMessageTuple(NamedTuple):
f"Hey chat, {Channel.confessions} exist {Emote.PepoBeliever} {Emote.PepoBeliever} {Emote.PepoBeliever}",
f"Hey chat, fix your posture {Emote.PepoBeliever}",
"Hey chat, remember to smile \N{SLIGHTLY SMILING FACE}",
f"Hey chat, feel free to invite new cool people to this server {Emote.peepoComfy} {Emote.peepoComfy} {Emote.peepoComfy}",
f"Hey chat, feel free to invite new people to this server {Emote.peepoComfy} {Emote.peepoComfy} {Emote.peepoComfy}",
"Hey chat, follow étiquette.",
f"Hey chat, if you ever see {User.alubot} offline (it should be always at the top of the members list online) - "
"immediately ping me",
Expand Down
5 changes: 2 additions & 3 deletions ext/community/suggestions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import asyncio
import contextlib
from typing import TYPE_CHECKING

import discord
Expand All @@ -24,10 +25,8 @@ async def pin_suggestion_topic(self, thread: discord.Thread) -> None:
return

message = thread.get_partial_message(thread.id)
try:
with contextlib.suppress(discord.HTTPException):
await message.pin()
except discord.HTTPException:
pass

query = """
UPDATE botinfo
Expand Down
2 changes: 1 addition & 1 deletion ext/community/twitch_notifs.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, bot: AluBot) -> None:
# cooldown attrs
self._lock: asyncio.Lock = asyncio.Lock()
# TODO: This is a crutch, if we make it `seconds=600`, then it will give it out fake notifications for when
# I close discord during the stream but then reopen it (since presence gonna proc without anything holding it back)
# I close discord during the stream but then reopen it (presence gonna proc without anything holding it back)
self.cooldown: datetime.timedelta = datetime.timedelta(hours=13)
self._most_recent: datetime.datetime | None = None

Expand Down
2 changes: 1 addition & 1 deletion ext/community/welcome.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ async def get_send_welcome_kwargs(self, member: discord.Member, back: bool = Fal

@commands.Cog.listener("on_member_join")
async def welcome_new_member(self, member: discord.Member) -> None:
"""Welcome new member
"""Welcome new member.
This listener also gives back to old returning members their roles and old nickname if any.
"""
Expand Down
7 changes: 3 additions & 4 deletions ext/dev/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import importlib
import importlib.metadata
import logging
import os
import platform
import socket
import sys
Expand Down Expand Up @@ -44,9 +43,9 @@ async def system_restart(self, interaction: discord.Interaction[AluBot]) -> None
await asyncio.sleep(3)
try:
# non systemctl users - sorry
os.system("sudo systemctl restart alubot")
except Exception as error:
log.error(error, stack_info=True)
await asyncio.create_subprocess_shell("sudo systemctl restart alubot")
except Exception:
log.exception("Failed to restart the bot", stack_info=True)
# it might not go off
await interaction.followup.send("Something went wrong.")

Expand Down
14 changes: 7 additions & 7 deletions ext/fpc/dota/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,9 @@ def draw_items_row() -> int:
canvas.paste(img.resize((item_w, h)), (count * item_w, canvas_h - h))

# item timings
for count, (item_id, item_timing) in enumerate(self.sorted_item_purchases):
for count, (_item_id, item_timing) in enumerate(self.sorted_item_purchases):
if item_timing:
text_w, text_h = self.bot.transposer.get_text_wh(item_timing, font)
_text_w, text_h = self.bot.transposer.get_text_wh(item_timing, font)
draw.text((count * item_w, canvas_h - text_h), item_timing, font=font, align="left")

canvas.paste(im=neutral_item_image.resize((item_w, h)), box=(canvas_w - item_w, canvas_h - h))
Expand All @@ -344,7 +344,7 @@ def draw_kda() -> float:
Returns height of the segment.
"""
font = ImageFont.truetype("./assets/fonts/Inter-Black-slnt=0.ttf", 33)
w, h = self.bot.transposer.get_text_wh(self.kda, font)
_w, h = self.bot.transposer.get_text_wh(self.kda, font)
draw.text((0, canvas_h - items_h - abilities_h - h), self.kda, font=font)
return h

Expand All @@ -356,7 +356,7 @@ def draw_outcome() -> float:
Returns height of the segment.
"""
font = ImageFont.truetype("./assets/fonts/Inter-Black-slnt=0.ttf", 33)
w, h = self.bot.transposer.get_text_wh(self.outcome, font)
_w, h = self.bot.transposer.get_text_wh(self.outcome, font)
colour_map = {
"Win": str(const.Palette.green(shade=800)),
"Loss": str(const.Palette.red(shade=900)),
Expand All @@ -382,7 +382,7 @@ def draw_talent_tree_choices() -> None:
p = 6

for count, (talent_id, talent) in enumerate(talents.items()):
text_w, text_h = self.bot.transposer.get_text_wh(talent.display_name, font)
text_w, _text_h = self.bot.transposer.get_text_wh(talent.display_name, font)

x = 0 if count % 2 else canvas_w - text_w
position = (x, canvas_h - items_h - abilities_h - kda_h - outcome_h - 20 - 26 * (count // 2))
Expand Down Expand Up @@ -439,12 +439,12 @@ async def edit_notification_image(self, embed_image_url: str, colour: discord.Co

def build_notification_image() -> Image.Image:
edit_log.debug("Building edited notification message.")
width, height = img.size
_width, height = img.size

draw = ImageDraw.Draw(img)
font = ImageFont.truetype("./assets/fonts/Inter-Black-slnt=0.ttf", 45)
text = "Not Counted"
text_w, text_h = self.bot.transposer.get_text_wh(text, font)
_text_w, text_h = self.bot.transposer.get_text_wh(text, font)
draw.text(
xy=(0, height - text_h),
text=text,
Expand Down
3 changes: 1 addition & 2 deletions ext/information/discord_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,10 @@ def get_avatar_embed_worker(
user: discord.User,
) -> discord.Embed:
"""Embed for view user avatar related commands."""
embed = discord.Embed(
return discord.Embed(
colour=user.colour,
title=f"Avatar for {user.display_name}",
).set_image(url=user.display_avatar.url)
return embed

async def view_user_avatar(self, interaction: discord.Interaction, user: discord.User) -> None:
"""Callback for context menu command "View User Avatar"."""
Expand Down
Loading

0 comments on commit 0d01801

Please sign in to comment.