Skip to content

Commit

Permalink
Merge pull request #285 from FirePlank/adventofcode
Browse files Browse the repository at this point in the history
  • Loading branch information
SylteA authored Nov 30, 2023
2 parents 416e585 + d8e594f commit c35e0c4
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 67 deletions.
6 changes: 0 additions & 6 deletions bot/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,6 @@ class Tags(BaseModel):
required_role_id: int # [lvl 30] Engineer


class Timathon(BaseModel):
channel_id: int
participant_role_id: int


class Hastebin(BaseModel):
base_url: str

Expand Down Expand Up @@ -112,7 +107,6 @@ class Settings(BaseSettings):
moderation: Moderation
reaction_roles: ReactionRoles
tags: Tags
timathon: Timathon
hastebin: Hastebin
errors: ErrorHandling
custom_roles: CustomRoles
Expand Down
7 changes: 3 additions & 4 deletions bot/extensions/adventofcode/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@

from bot import core
from bot.extensions.adventofcode.utils import home_embed
from bot.extensions.adventofcode.views import CreateAdventOfCodeView
from bot.extensions.adventofcode.views import AdventOfCodeView


class AdventOfCode(commands.Cog):
def __init__(self, bot):
self.bot = bot
self._create_aoc_view = CreateAdventOfCodeView(timeout=None)
self.bot.add_view(self._create_aoc_view)
self.bot.add_view(AdventOfCodeView())

@app_commands.command(name="advent-of-code")
async def advent_of_code(self, interaction: core.InteractionType):
"""Returns information about the Advent of Code"""
await interaction.response.send_message(embed=home_embed(), ephemeral=True, view=self._create_aoc_view)
await interaction.response.send_message(embed=home_embed(), ephemeral=True, view=AdventOfCodeView())
18 changes: 12 additions & 6 deletions bot/extensions/adventofcode/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Optional, Union
from zoneinfo import ZoneInfo

import aiohttp
import discord
from async_lru import alru_cache
from pydantic import BaseModel, validator
Expand Down Expand Up @@ -76,7 +77,7 @@ class Member(BaseModel):
local_score: int

@validator("name", pre=True)
def set_name_to_anonymous(cls, val: Optional[str]) -> str:
def check_username(cls, val: Optional[str]) -> str:
if val is None:
return "Anonymous User"
return val
Expand All @@ -88,11 +89,16 @@ async def fetch_leaderboard(local: bool = False) -> Union[str, dict]:
if local:
url += f"/private/view/{LEADERBOARD_ID}.json"

async with http.session.get(url, headers=AOC_REQUEST_HEADERS, raise_for_status=True) as resp:
async with http.session.get(url, headers=AOC_REQUEST_HEADERS) as resp:
if resp.status == 200:
if local:
response = await resp.json()
try:
return await resp.json()
except aiohttp.ContentTypeError:
return "Failed to get leaderboard data. Please check that the leaderboard code is correct."
else:
response = await resp.text()

return response
return await resp.text()
elif resp.status == 500:
return "Failed to get leaderboard data. Please check that the session cookie is correct."
else:
return "Failed to get leaderboard data. Please check that all the env values are correct."
28 changes: 22 additions & 6 deletions bot/extensions/adventofcode/views.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import re
import typing as t
from datetime import datetime
from zoneinfo import ZoneInfo

import discord
from bs4 import BeautifulSoup
from discord import ui
from discord.ui import Item

from bot import core
from bot.extensions.adventofcode.utils import LEADERBOARD_ID, YEAR, Member, fetch_leaderboard, home_embed, ordinal


class CreateAdventOfCodeView(ui.View):
class AdventOfCodeView(ui.View):
def __init__(self):
super().__init__(timeout=None)

HOME_CUSTOM_ID = "extensions:adventofcode:home"
LOCAL_LEADERBOARD_CUSTOM_ID = "extensions:adventofcode:local"
GLOBAL_LEADERBOARD_CUSTOM_ID = "extensions:adventofcode:global"
Expand All @@ -22,17 +27,21 @@ async def home(self, interaction: core.InteractionType, _button: ui.Button):
@discord.ui.button(
label="Local Leaderboard", style=discord.ButtonStyle.gray, emoji="👥", custom_id=LOCAL_LEADERBOARD_CUSTOM_ID
)
async def local_leaderboard(self, interaction: core.InteractionType, button: ui.Button):
async def local_leaderboard(self, interaction: core.InteractionType, _button: ui.Button):
leaderboard = await fetch_leaderboard(local=True)

members = [Member(**member_data) for member_data in leaderboard["members"].values()]

embed = discord.Embed(
title=f"{interaction.guild.name} Advent of Code Leaderboard",
colour=0x68C290,
url=f"https://adventofcode.com/{YEAR}/leaderboard/private/view/{LEADERBOARD_ID}",
)

if isinstance(leaderboard, str):
embed.description = leaderboard
return await interaction.response.edit_message(embed=embed, view=self)

members = [Member(**member_data) for member_data in leaderboard["members"].values()]

leaderboard = {
"owner_id": leaderboard["owner_id"],
"event": leaderboard["event"],
Expand All @@ -53,16 +62,20 @@ async def local_leaderboard(self, interaction: core.InteractionType, button: ui.
@discord.ui.button(
label="Global Leaderboard", style=discord.ButtonStyle.gray, emoji="🌎", custom_id=GLOBAL_LEADERBOARD_CUSTOM_ID
)
async def global_leaderboard(self, interaction: core.InteractionType, button: ui.Button):
async def global_leaderboard(self, interaction: core.InteractionType, _button: ui.Button):
raw_html = await fetch_leaderboard(local=False)
soup = BeautifulSoup(raw_html, "html.parser")

embed = discord.Embed(
title="Advent of Code Global Leaderboard",
colour=0x68C290,
url=f"https://adventofcode.com/{YEAR}/leaderboard",
)

if raw_html.startswith("Failed to get leaderboard data."):
embed.description = raw_html
return await interaction.response.edit_message(embed=embed, view=self)

soup = BeautifulSoup(raw_html, "html.parser")
if soup.find("p").text == "Nothing to show on the leaderboard... yet.":
embed.description = "The global leaderboard is not available yet. Please try again later."
return await interaction.response.edit_message(embed=embed, view=self)
Expand Down Expand Up @@ -98,3 +111,6 @@ async def global_leaderboard(self, interaction: core.InteractionType, button: ui
embed.description = s_desc

await interaction.response.edit_message(embed=embed, view=self)

async def on_error(self, interaction: core.InteractionType, _error: Exception, _item: Item[t.Any], /) -> None:
await interaction.client.on_error("adventofcode_view")
6 changes: 1 addition & 5 deletions bot/extensions/challenges/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ def submit_channel(self) -> discord.TextChannel | None:
def submissions_channel(self) -> discord.TextChannel | None:
return self.bot.guild.get_channel(settings.challenges.submissions_channel_id)

@property
def games_channel(self) -> discord.TextChannel | None:
return self.bot.guild.get_channel(settings.bot.games_channel_id)

@app_commands.command()
async def clear_winners(self, interaction: core.InteractionType):
"""Clears the winner role from all members that have it."""
Expand Down Expand Up @@ -150,7 +146,7 @@ async def announce(self, interaction: core.InteractionType):
"""Send an announcement in the info channel mentioning the winners."""

text = (
f"{self.winner_role.mention} 🥞 have been given out, go deposit them in {self.games_channel.mention}."
f"{self.winner_role.mention} 🥞 have been given out, go deposit them in <#{settings.bot.games_channel_id}>."
f"\nAnalysis for the challenge will be available shortly in {self.info_channel.mention}."
)
await self.info_channel.send(text, allowed_mentions=discord.AllowedMentions(roles=[self.winner_role]))
Expand Down
6 changes: 2 additions & 4 deletions bot/extensions/polls/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
class Polls(commands.GroupCog, group_name="poll"):
def __init__(self, bot: core.DiscordBot):
self.bot = bot

self._create_poll_view = CreatePollView(timeout=None)
self.bot.add_view(self._create_poll_view)
self.bot.add_view(CreatePollView())

@app_commands.command()
@app_commands.describe(question="Your question")
Expand All @@ -26,7 +24,7 @@ async def new(self, interaction: core.InteractionType, question: str):
color=discord.colour.Color.gold(),
)
embed.set_footer(text=f"Poll by {interaction.user.display_name}")
await interaction.response.send_message(embed=embed, ephemeral=True, view=self._create_poll_view)
await interaction.response.send_message(embed=embed, ephemeral=True, view=CreatePollView())

@app_commands.command()
async def show(
Expand Down
8 changes: 7 additions & 1 deletion bot/extensions/polls/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ async def on_submit(self, interaction: discord.Interaction) -> None:

embed.add_field(name=f"{str(emojis[field_count])} {self.name}", value=self.description, inline=False)
field_count += 1
view = CreatePollView()

view = CreatePollView()
add_choice_btn = discord.utils.get(view.children, custom_id=CreatePollView.ADD_CUSTOM_ID)
create_poll_btn = discord.utils.get(view.children, custom_id=CreatePollView.CREATE_CUSTOM_ID)
delete_select = discord.utils.find(lambda child: isinstance(child, discord.ui.Select), view.children)
Expand Down Expand Up @@ -82,6 +82,9 @@ async def callback(self, interaction: core.InteractionType):


class CreatePollView(ui.View):
def __init__(self):
super().__init__(timeout=None)

ADD_CUSTOM_ID = "extensions:polls:add"
DELETE_CUSTOM_ID = "extensions:polls:delete"
CREATE_CUSTOM_ID = "extensions:polls:create"
Expand Down Expand Up @@ -115,3 +118,6 @@ async def create_poll(self, interaction: core.InteractionType, _button: ui.Butto

for i in range(0, len(embed.fields)):
await message.add_reaction(emojis[i])

async def on_error(self, interaction: core.InteractionType, _error: Exception, _item: ui.Item[t.Any], /) -> None:
await interaction.client.on_error("poll_view")
62 changes: 27 additions & 35 deletions example.env
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@
# -------- Config
# --- AoC
AOC__CHANNEL_ID=0
AOC__ROLE_ID=0
AOC__LEADERBOARD_CODE = 975452-d90a48b0
AOC__SESSION_COOKIE=...
AOC__CHANNEL_ID=
AOC__ROLE_ID=
AOC__LEADERBOARD_CODE=975452-d90a48b0
AOC__SESSION_COOKIE=

# --- Bots

# List[int] # [#bot-commands, #commands] (main bot-commands channel at index 0)
# Leave no sapce or use double quotes `"` e.g: "[0, 0]"
BOT__COMMANDS_CHANNELS_IDS=[0,0]
BOT__GAMES_CHANNEL_ID=0
BOT__GAMES_CHANNEL_ID=
BOT__TOKEN=

# --- CHALLENGES
CHALLENGES__CHANNEL_ID=0
CHALLENGES__DISCUSSION_CHANNEL_ID=0
CHALLENGES__HOST_HELPER_ROLE_ID=0
CHALLENGES__HOST_ROLE_ID=0
CHALLENGES__INFO_CHANNEL_ID=0
CHALLENGES__PARTICIPANT_ROLE_ID=0
CHALLENGES__SUBMISSIONS_CHANNEL_ID=0
CHALLENGES__SUBMITTED_ROLE_ID=0
CHALLENGES__SUBMIT_CHANNEL_ID=0
CHALLENGES__WINNER_ROLE_ID=0
CHALLENGES__CHANNEL_ID=
CHALLENGES__DISCUSSION_CHANNEL_ID=
CHALLENGES__HOST_HELPER_ROLE_ID=
CHALLENGES__HOST_ROLE_ID=
CHALLENGES__INFO_CHANNEL_ID=
CHALLENGES__PARTICIPANT_ROLE_ID=
CHALLENGES__SUBMISSIONS_CHANNEL_ID=
CHALLENGES__SUBMITTED_ROLE_ID=
CHALLENGES__SUBMIT_CHANNEL_ID=
CHALLENGES__WINNER_ROLE_ID=

# --- COC
COC__CHANNEL_ID=0
COC__MESSAGE_ID=0
COC__ROLE_ID=0
COC__CHANNEL_ID=
COC__MESSAGE_ID=
COC__ROLE_ID=

# --- Postgres
POSTGRES__MAX_POOL_CONNECTIONS=10
Expand All @@ -37,16 +33,16 @@ POSTGRES__URI=

# --- Guild
GUILD__ID=
GUILD__WELCOMES_CHANNEL_ID=0
GUILD__WELCOMES_CHANNEL_ID=

# --- Moderation
# List[int], # Leave no sapce or use double quotes `"` e.g: "[0, 0]"
MODERATION__ADMIN_ROLES_IDS=
MODERATION__STAFF_ROLE_ID=

# --- Notification
NOTIFICATION__CHANNEL_ID=0
NOTIFICATION__ROLE_ID=0
NOTIFICATION__CHANNEL_ID=
NOTIFICATION__ROLE_ID=

# --- Reaction Roles
# Access to reaction roles
Expand All @@ -57,19 +53,15 @@ REACTION_ROLES__ROLES={"0":0}
REACTION_ROLES__MESSAGE_ID=0

# --- Tags
TAGS__LOG_CHANNEL_ID=0
TAGS__LOG_CHANNEL_ID=
# Access to tag commands
TAGS__REQUIRED_ROLE_ID=0

# --- Timathon
TIMATHON__CHANNEL_ID=0
TIMATHON__PARTICIPANT_ROLE_ID=0
TAGS__REQUIRED_ROLE_ID=

# --- Custom Roles
CUSTOM_ROLES__LOG_CHANNEL_ID=0
CUSTOM_ROLES__DIVIDER_ROLE_ID=0
CUSTOM_ROLES__LOG_CHANNEL_ID=
CUSTOM_ROLES__DIVIDER_ROLE_ID=

# --- Youtube
YOUTUBE__CHANNEL_ID=UC4JX40jDee_tINbkjycV4Sg
YOUTUBE__TEXT_CHANNEL_ID=0
YOUTUBE__ROLE_ID=0
YOUTUBE__TEXT_CHANNEL_ID=
YOUTUBE__ROLE_ID=

0 comments on commit c35e0c4

Please sign in to comment.