1- import functools
21import logging
32import subprocess
43from typing import Any , Optional
54
6- import discord
7-
85
96def setup_logging (name : Optional [str ] = None ):
107 """Configure and setup logging for the application"""
@@ -26,31 +23,6 @@ def setup_logging(name: Optional[str] = None):
2623 return logger
2724
2825
29- logger = setup_logging (__name__ )
30-
31-
32- def with_error_handling (f : callable ):
33- @functools .wraps (f )
34- async def wrap (self , interaction : discord .Interaction , * args , ** kwargs ):
35- try :
36- await f (self , interaction , * args , ** kwargs )
37- except KernelBotError as e :
38- await send_discord_message (
39- interaction ,
40- str (e ),
41- ephemeral = True ,
42- )
43- except Exception as e :
44- logging .exception ("Unhandled exception %s" , e , exc_info = e )
45- await send_discord_message (
46- interaction ,
47- "An unexpected error occurred. Please report this to the developers." ,
48- ephemeral = True ,
49- )
50-
51- return wrap
52-
53-
5426class KernelBotError (Exception ):
5527 """
5628 This class represents an Exception that has been sanitized,
@@ -75,58 +47,6 @@ def get_github_branch_name():
7547 return "main"
7648
7749
78- async def get_user_from_id (bot , id ) -> str :
79- with bot .leaderboard_db as db :
80- return db .get_user_from_id (id ) or id
81-
82-
83- async def send_discord_message (
84- interaction : discord .Interaction , msg : str , * , ephemeral = False , ** kwargs
85- ) -> None :
86- """
87- To get around response messages in slash commands that are
88- called externally, send a message using the followup.
89- """
90- if interaction .response .is_done ():
91- await interaction .followup .send (msg , ephemeral = ephemeral , ** kwargs )
92- else :
93- await interaction .response .send_message (msg , ephemeral = ephemeral , ** kwargs )
94-
95-
96- async def send_logs (thread : discord .Thread , logs : str ) -> None :
97- """Send logs to a Discord thread, splitting by lines and respecting Discord's character limit.
98-
99- Args:
100- thread: The Discord thread to send logs to
101- logs: The log string to send
102- """
103- # Split logs into lines
104- log_lines = logs .splitlines ()
105-
106- current_chunk = []
107- current_length = 0
108-
109- for line in log_lines :
110- # Add 1 for the newline character
111- line_length = len (line ) + 1
112-
113- # If adding this line would exceed Discord's limit, send current chunk
114- if current_length + line_length > 1990 : # Leave room for code block markers
115- if current_chunk :
116- chunk_text = "\n " .join (current_chunk )
117- await thread .send (f"```\n { chunk_text } \n ```" )
118- current_chunk = []
119- current_length = 0
120-
121- current_chunk .append (line )
122- current_length += line_length
123-
124- # Send any remaining lines
125- if current_chunk :
126- chunk_text = "\n " .join (current_chunk )
127- await thread .send (f"```\n { chunk_text } \n ```" )
128-
129-
13050class LRUCache :
13151 def __init__ (self , max_size : int ):
13252 """LRU Cache implementation, as functools.lru doesn't work in async code
@@ -215,27 +135,3 @@ def format_time(value: float | str, err: Optional[float | str] = None, scale=Non
215135 return f"{ value :.0f} ± { err :.1f} { unit } "
216136 else :
217137 return f"{ value :.0f} { unit } "
218-
219-
220- async def leaderboard_name_autocomplete (
221- interaction : discord .Interaction ,
222- current : str ,
223- ) -> list [discord .app_commands .Choice [str ]]:
224- """Return leaderboard names that match the current typed name"""
225- try :
226- bot = interaction .client
227- name_cache = bot .leaderboard_db .name_cache
228- cached_value = name_cache [current ]
229- if cached_value is not None :
230- return cached_value
231-
232- with bot .leaderboard_db as db :
233- leaderboards = db .get_leaderboard_names ()
234- filtered = [lb for lb in leaderboards if current .lower () in lb .lower ()]
235- name_cache [current ] = [
236- discord .app_commands .Choice (name = name , value = name ) for name in filtered [:25 ]
237- ]
238- return name_cache [current ]
239- except Exception as e :
240- logger .exception ("Error in leaderboard autocomplete" , exc_info = e )
241- return []
0 commit comments