55import io
66import csv
77import datetime
8+ from matcherino_scraper import MatcherinoScraper
89
910logger = logging .getLogger (__name__ )
1011
@@ -36,7 +37,6 @@ async def match_free_agents_command(self, interaction: discord.Interaction):
3637 logger .info (f"Found { len (db_users )} users with Matcherino usernames in database" )
3738
3839 # Step 2: Fetch all participants from Matcherino API
39- from matcherino_scraper import MatcherinoScraper
4040 async with MatcherinoScraper () as scraper :
4141 participants = await scraper .get_tournament_participants (self .bot .TOURNAMENT_ID )
4242
@@ -310,5 +310,83 @@ async def generate_match_results_csv(self, exact_matches, name_only_matches,
310310 csv_bytes = csv_buffer .getvalue ().encode ('utf-8' )
311311 return discord .File (io .BytesIO (csv_bytes ), filename = "matcherino_participant_matches.csv" )
312312
313+ @app_commands .command (name = "list-unmatched" , description = "List all unmatched Matcherino participants for cleanup" )
314+ @app_commands .default_permissions (administrator = True )
315+ async def list_unmatched_command (self , interaction : discord .Interaction ):
316+ """Admin command to list all Matcherino participants that aren't matched to Discord users."""
317+ if not self .bot .TOURNAMENT_ID :
318+ await interaction .response .send_message ("MATCHERINO_TOURNAMENT_ID is not set. Please set it in the .env file." , ephemeral = True )
319+ return
320+
321+ await interaction .response .defer (ephemeral = True )
322+
323+ try :
324+ logger .info ("Starting unmatched participant listing process" )
325+
326+ # Get all registered users with their Matcherino usernames
327+ db_users = await self .bot .db .get_all_matcherino_usernames ()
328+ if not db_users :
329+ await interaction .followup .send ("No users with Matcherino usernames found in database." , ephemeral = True )
330+ return
331+
332+ # Fetch all participants from Matcherino
333+ async with MatcherinoScraper () as scraper :
334+ participants = await scraper .get_tournament_participants (self .bot .TOURNAMENT_ID )
335+
336+ if not participants :
337+ await interaction .followup .send ("No participants found in the Matcherino tournament." , ephemeral = True )
338+ return
339+
340+ # Process participants to find unmatched ones
341+ (exact_matches , name_only_matches , ambiguous_matches ,
342+ unmatched_participants , unmatched_db_users ) = await self .match_participants_with_db_users (
343+ participants , db_users
344+ )
345+
346+ # Create a text file listing unmatched participants
347+ content = ["# Unmatched Matcherino Participants" , "" ]
348+ content .append ("These participants are on Matcherino but not matched to any Discord user:\n " )
349+
350+ for participant in unmatched_participants :
351+ name = participant ['name' ]
352+ matcherino_id = participant ['matcherino_id' ]
353+ game_username = participant ['game_username' ]
354+
355+ line = f"- { name } "
356+ if matcherino_id :
357+ line += f" (ID: { matcherino_id } )"
358+ if game_username :
359+ line += f" [Game: { game_username } ]"
360+ content .append (line )
361+
362+ content .append ("\n # Ambiguous Matches" )
363+ content .append ("These participants have multiple potential Discord matches:\n " )
364+
365+ for match in ambiguous_matches :
366+ content .append (f"- { match ['participant' ]} " )
367+ if match .get ('participant_tag' ):
368+ content .append (f" Game username: { match ['participant_tag' ]} " )
369+ content .append (" Potential Discord matches:" )
370+ for potential in match ['potential_matches' ]:
371+ content .append (f" * Discord: { potential ['discord_username' ]} (ID: { potential ['discord_id' ]} )" )
372+ if potential .get ('matcherino_username' ):
373+ content .append (f" Current Matcherino username: { potential ['matcherino_username' ]} " )
374+ content .append ("" )
375+
376+ # Save as text file
377+ file_content = "\n " .join (content )
378+ file = discord .File (
379+ io .BytesIO (file_content .encode ('utf-8' )),
380+ filename = "unmatched_participants.txt"
381+ )
382+
383+ # Send the file
384+ summary = f"Found { len (unmatched_participants )} unmatched participants and { len (ambiguous_matches )} ambiguous matches."
385+ await interaction .followup .send (summary , file = file , ephemeral = True )
386+
387+ except Exception as e :
388+ logger .error (f"Error listing unmatched participants: { e } " , exc_info = True )
389+ await interaction .followup .send (f"An error occurred: { str (e )} " , ephemeral = True )
390+
313391async def setup (bot ):
314392 await bot .add_cog (MatcherinoCog (bot ))
0 commit comments