3
3
import datetime
4
4
import os
5
5
import sys
6
- from enum import Enum
6
+ from enum import Enum , auto
7
7
8
8
import discord
9
9
import pandas as pd
@@ -249,16 +249,18 @@ async def help(interaction: discord.Interaction):
249
249
await interaction .response .send_message (view = ephemeral_url_view , ephemeral = True )
250
250
251
251
class Belt (Enum ):
252
- ORANGE = 0
253
- YELLOW = 1
254
- BLUE = 2
255
- ERROR = - 1
252
+ ORANGE_23S = auto ()
253
+ ORANGE = auto ()
254
+ YELLOW_22 = auto ()
255
+ YELLOW = auto ()
256
+ BLUE = auto ()
257
+ ERROR = auto ()
256
258
257
259
def get_role (self ):
258
260
match self :
259
- case Belt .ORANGE :
261
+ case Belt .ORANGE_23S | Belt . ORANGE :
260
262
return "Orange Belt"
261
- case Belt .YELLOW :
263
+ case Belt .YELLOW_22 | Belt . YELLOW :
262
264
return "Yellow Belt"
263
265
case Belt .BLUE :
264
266
return "Blue Belt"
@@ -267,9 +269,9 @@ def get_role(self):
267
269
268
270
def get_req_belt (self ):
269
271
match self :
270
- case Belt .ORANGE :
272
+ case Belt .ORANGE_23S | Belt . ORANGE :
271
273
return None
272
- case Belt .YELLOW :
274
+ case Belt .YELLOW_22 | Belt . YELLOW :
273
275
return Belt .ORANGE
274
276
case Belt .BLUE :
275
277
return Belt .YELLOW
@@ -278,6 +280,10 @@ def get_req_belt(self):
278
280
279
281
def get_course (self ):
280
282
match self :
283
+ case Belt .ORANGE_23S :
284
+ return 62725971 # CSE 365 - Spring 2023
285
+ case Belt .YELLOW_22 :
286
+ return - 2037203363 # CSE 466 - Fall 2022
281
287
case Belt .ORANGE :
282
288
return 1520512338 # CSE 365 - Fall 2023
283
289
case Belt .YELLOW :
@@ -287,11 +293,11 @@ def get_course(self):
287
293
case _:
288
294
return 0
289
295
290
- async def announce_belting (member , belt : Belt ):
291
- belt_message = await client .belting_ceremony_channel .send (content = f"{ member .mention } has earned their { belt .get_role ()} ! :tada:" )
296
+ async def announce_belting (member , belt : Belt , append_text = "" ):
297
+ belt_message = await client .belting_ceremony_channel .send (content = f"{ member .mention } earned their { belt .get_role ()} { append_text } ! :tada:" )
292
298
return belt_message
293
299
294
- async def check_belts ():
300
+ async def _check_belts ():
295
301
now = datetime .datetime .now ()
296
302
print (f"Checking belts @ { now } " )
297
303
@@ -304,21 +310,23 @@ async def check_belt(belt: Belt):
304
310
305
311
completion = pd .read_sql (f'''
306
312
select count(*) from dojo_challenges where dojo_id={ course } ;
307
- ''' , engine ).iloc [0 ][0 ]
313
+ ''' , engine ).values [0 ][0 ]
308
314
309
315
belted = pd .read_sql (f'''
310
- SELECT u.name, dis.discord_id, count(s.challenge_id)
311
- FROM dojo_challenges as d
312
- JOIN solves as s
313
- ON d.challenge_id=s.challenge_id
314
- JOIN users as u
315
- ON u.id=s.user_id
316
- JOIN discord_users as dis
317
- ON u.id=dis.user_id
318
- WHERE d.dojo_id={ course }
319
- GROUP BY u.name
320
- HAVING count(s.challenge_id)={ completion } ;
321
- ''' , engine )
316
+ select u.name, dis.discord_id, max(sub.date), count(sub.date)
317
+ FROM users as u
318
+ JOIN submissions as sub
319
+ ON u.id=.sub.user_id
320
+ JOIN dojo_challenges as d
321
+ ON d.challenge_id=sub.challenge_id
322
+ JOIN discord_users as dis
323
+ ON dis.user_id=u.id
324
+ WHERE d.dojo_id={ belt .get_course ()}
325
+ AND sub.type='correct'
326
+ GROUP BY u.name
327
+ HAVING count(sub.date)={ completion }
328
+ ORDER BY max(sub.date)
329
+ ''' , engine )
322
330
323
331
for _ , row in belted .iterrows ():
324
332
try :
@@ -329,10 +337,25 @@ async def check_belt(belt: Belt):
329
337
now = datetime .datetime .now ()
330
338
print (f"Awarding { belt .get_role ()} to { member .display_name } @ { now } " )
331
339
await member .add_roles (role )
332
- await announce_belting (member , belt )
340
+ await announce_belting (member , belt , append_text = f" { discord .utils .format_dt (row ['max(sub.date)' ])} " )
341
+
342
+
343
+ # TODO: remove the previous course
344
+ await check_belt (Belt .ORANGE_23S )
345
+ await check_belt (Belt .YELLOW_22 )
333
346
334
347
await check_belt (Belt .ORANGE )
335
348
await check_belt (Belt .YELLOW )
336
349
await check_belt (Belt .BLUE )
337
350
351
+
352
+ @client .tree .command ()
353
+ async def check_belts (interaction : discord .Interaction ):
354
+ senseis = list (role for role in interaction .guild .roles if "sensei" in role .name .lower ())
355
+
356
+ if not any (interaction .user in sensei .members for sensei in senseis ):
357
+ await interaction .response .send_message ("You are not a sensei!" , ephemeral = True )
358
+ return
359
+ await _check_belts ()
360
+
338
361
client .run (DISCORD_BOT_TOKEN )
0 commit comments