def _get_user_from_db_row(user_row): user = NecroUser(commit_fn=userdb.write_user) console.debug('Getting user from data: {}'.format(user_row)) user.set(discord_id=user_row[0], discord_name=user_row[1], twitch_name=user_row[2], rtmp_name=user_row[3], timezone=user_row[4], user_info=user_row[5], user_prefs=UserPrefs(daily_alert=bool(user_row[6]), race_alert=bool(user_row[7])), commit=False) user._user_id = int(user_row[8]) _cache_user(user) return user
async def make_single_match(racers): console.debug('MakeMatchesFromFile: Making match {0}-{1}'.format(racers[0], racers[1])) racer_1 = all_racers[racers[0]] racer_2 = all_racers[racers[1]] if racer_1 is None or racer_2 is None: console.warning('Couldn\'t find racers for match {0}-{1}.'.format( racers[0], racers[1] )) not_found_matches.append('`{0}`-`{1}`'.format(racers[0], racers[1])) return new_match = await matchutil.make_match( register=True, racer_1_id=racer_1.user_id, racer_2_id=racer_2.user_id, match_info=match_info, autogenned=True ) if new_match is None: console.debug('MakeMatchesFromFile: Match {0}-{1} not created.'.format(racers[0], racers[1])) not_found_matches.append('{0}-{1}'.format(racers[0], racers[1])) return matches.append(new_match) console.debug('MakeMatchesFromFile: Created {0}-{1}'.format( new_match.racer_1.rtmp_name, new_match.racer_2.rtmp_name) )
async def make_single_match(racers): console.debug( '_makematches_from_pairs: Making match {0}-{1}'.format( racers[0], racers[1])) racer_1 = all_racers[racers[0]][0] if len( all_racers[racers[0]]) == 1 else None racer_2 = all_racers[racers[1]][0] if len( all_racers[racers[1]]) == 1 else None if racer_1 is None or racer_2 is None: console.warning( 'Couldn\'t find racers for match {0}-{1}.'.format( racers[0], racers[1])) not_found_matches.append((racers[0], racers[1])) return new_match = await matchutil.make_match(register=True, racer_1_id=racer_1.user_id, racer_2_id=racer_2.user_id, match_info=match_info, league_tag=league.tag, autogenned=True) if new_match is None: console.debug( '_makematches_from_pairs: Match {0}-{1} not created.'. format(racers[0], racers[1])) not_found_matches.append((racers[0], racers[1])) return matches.append(new_match) console.debug('_makematches_from_pairs: Created {0}-{1}'.format( new_match.racer_1.matchroom_name, new_match.racer_2.matchroom_name))
async def get_matches(self, **kwargs): """Read racer names and match types from the GSheet; create corresponding matches. Parameters ---------- kwargs: Parameters to be passed to matchutil.make_match for every match made. Returns ------- list[Match] The list of created Matches. """ console.debug('get_matches begin...') await self.column_data.refresh_footer() matches = [] self._not_found_matches = [] write_match_ids = self.column_data.match_id is not None and 'register' in kwargs and kwargs[ 'register'] match_ids = [] async with Spreadsheets() as spreadsheets: value_range = await self.column_data.get_values(spreadsheets) console.debug('get_matches: Got values from spreadsheets.') if 'values' not in value_range: console.debug('get_matches: Values is empty.') return matches else: console.debug('get_matches: Values: {0}'.format( value_range['values'])) for row_idx, row_values in enumerate(value_range['values']): try: racer_1_name = row_values[self.column_data.racer_1].rstrip( ' ') racer_2_name = row_values[self.column_data.racer_2].rstrip( ' ') except IndexError: console.warning( 'Failed to make match from sheet row: <{}>'.format( row_values)) continue if not racer_1_name or not racer_2_name: continue # if racer_1_name[0] not in string.ascii_letters or racer_2_name[0] not in string.ascii_letters: # self._not_found_matches.append('{0}-{1}'.format(racer_1_name, racer_2_name)) # continue console.debug('get_matches: Creating {0}-{1}'.format( racer_1_name, racer_2_name)) racer_1 = await userlib.get_user(any_name=racer_1_name, register=True) racer_2 = await userlib.get_user(any_name=racer_2_name, register=True) if racer_1 is None or racer_2 is None: console.warning( 'Couldn\'t find racers for match {0}-{1}.'.format( racer_1_name, racer_2_name)) self._not_found_matches.append('{0}-{1}'.format( racer_1_name, racer_2_name)) continue sheet_info = MatchGSheetInfo() sheet_info.wks_id = self.wks_id sheet_info.row = row_idx kwarg_copy = kwargs.copy() if self.column_data.type is not None: match_info = kwarg_copy[ 'match_info'] if 'match_info' in kwargs else matchinfo.MatchInfo( ) try: parsed_args = shlex.split( row_values[self.column_data.type]) kwarg_copy['match_info'] = matchinfo.parse_args_modify( parsed_args, match_info) except IndexError: pass new_match = await matchutil.make_match( racer_1_id=racer_1.user_id, racer_2_id=racer_2.user_id, gsheet_info=sheet_info, **kwarg_copy) matches.append(new_match) console.debug('get_matches: Created {0}-{1}'.format( new_match.racer_1.rtmp_name, new_match.racer_2.rtmp_name)) if write_match_ids: match_ids.append([new_match.match_id]) if write_match_ids: ids_range = self.column_data.get_range_for_column( self.column_data.match_id) await self.column_data.update_cells(sheet_range=ids_range, values=match_ids, raw_input=True) console.debug('get_matches: Returning Matches=<{}>'.format(matches)) return matches
async def _do_execute(self, cmd: Command): if len(cmd.args) != 1: await self.client.send_message( cmd.channel, 'Wrong number of arguments for `{0}`.'.format(self.mention)) return wks_name = cmd.args[0] await self.client.send_message( cmd.channel, 'Creating matches from worksheet `{0}`...'.format(wks_name)) await self.client.send_typing(cmd.channel) match_info = LeagueMgr().league.match_info console.info('MakeFromSheet: Getting GSheet info...') try: matchup_sheet = await sheetlib.get_sheet( gsheet_id=LeagueMgr().league.gsheet_id, wks_name=wks_name, sheet_type=sheetlib.SheetType.MATCHUP) # type: MatchupSheet matches = await matchup_sheet.get_matches(register=False, match_info=match_info) except (googleapiclient.errors.Error, necrobot.exception.NecroException) as e: await self.client.send_message( cmd.channel, 'Error while making matchups: `{0}`'.format(e)) return console.info('MakeFromSheet: Creating Match objects...') not_found_matches = matchup_sheet.uncreated_matches() matches_with_channels = await matchutil.get_matches_with_channels() channeled_matchroom_names = dict() for match in matches_with_channels: if match.matchroom_name in channeled_matchroom_names: channeled_matchroom_names[match.matchroom_name] += 1 else: channeled_matchroom_names[match.matchroom_name] = 1 console.info('MakeFromSheet: Removing duplicate matches...') # Remove matches that have the same name as current channels (but only one per channel) unchanneled_matches = [] for match in matches: channeled_name = match.matchroom_name in channeled_matchroom_names if not channeled_name or channeled_matchroom_names[ match.matchroom_name] <= 0: unchanneled_matches.append(match) if channeled_name: channeled_matchroom_names[match.matchroom_name] -= 1 console.info('MakeFromSheet: Sorting matches...') # Sort the remaining matches unchanneled_matches = sorted(unchanneled_matches, key=lambda m: m.matchroom_name) console.debug( 'MakeFromSheet: Matches to make: {0}'.format(unchanneled_matches)) console.info('MakeFromSheet: Creating match channels...') for match in unchanneled_matches: console.info('MakeFromSheet: Creating {0}...'.format( match.matchroom_name)) new_room = await matchutil.make_match_room(match=match, register=True) await new_room.send_channel_start_text() uncreated_str = '' for match_str in not_found_matches: uncreated_str += match_str + ', ' if uncreated_str: uncreated_str = uncreated_str[:-2] if uncreated_str: report_str = 'Done creating matches. The following matches were not made: {0}'.format( uncreated_str) else: report_str = 'All matches created successfully.' await self.client.send_message(cmd.channel, report_str)
async def _do_execute(self, cmd: Command): if len(cmd.args) != 1: await cmd.channel.send( 'Wrong number of arguments for `{0}`.'.format(self.mention)) return wks_name = cmd.args[0] status_message = await cmd.channel.send( 'Creating matches from worksheet `{0}`... (Getting GSheet info)'. format(wks_name)) async with cmd.channel.typing(): match_info = LeagueMgr().league.match_info console.info('MakeFromSheet: Getting GSheet info...') try: matchup_sheet = await sheetlib.get_sheet( gsheet_id=LeagueMgr().league.gsheet_id, wks_name=wks_name, sheet_type=sheetlib.SheetType.MATCHUP ) # type: MatchupSheet matches = await matchup_sheet.get_matches( register=True, match_info=match_info) except (googleapiclient.errors.Error, necrobot.exception.NecroException) as e: await cmd.channel.send( 'Error while making matchups: `{0}`'.format(e)) return console.info('MakeFromSheet: Creating Match objects...') await status_message.edit( content= 'Creating matches from worksheet `{0}`... (Creating match list)' .format(wks_name)) not_found_matches = matchup_sheet.uncreated_matches() matches_with_channels = await matchchannelutil.get_matches_with_channels( ) console.info('MakeFromSheet: Removing duplicate matches...') # Remove matches from the list that already have channels unchanneled_matches = [] for match in matches: found = False for channeled_match in matches_with_channels: if match.match_id == channeled_match.match_id: found = True if not found: unchanneled_matches.append(match) console.info('MakeFromSheet: Sorting matches...') # Sort the remaining matches unchanneled_matches = sorted(unchanneled_matches, key=lambda m: m.matchroom_name) await status_message.edit( content= 'Creating matches from worksheet `{0}`... (Creating race rooms)' .format(wks_name)) console.debug('MakeFromSheet: Matches to make: {0}'.format( unchanneled_matches)) console.info('MakeFromSheet: Creating match channels...') for match in unchanneled_matches: console.info('MakeFromSheet: Creating {0}...'.format( match.matchroom_name)) new_room = await matchchannelutil.make_match_room( match=match, register=False) await new_room.send_channel_start_text() uncreated_str = '' for match_str in not_found_matches: uncreated_str += match_str + ', ' if uncreated_str: uncreated_str = uncreated_str[:-2] if uncreated_str: report_str = 'The following matches were not made: {0}'.format( uncreated_str) else: report_str = 'All matches created successfully.' await status_message.edit( content='Creating matches from worksheet `{0}`... done. {1}'. format(wks_name, report_str))
async def _do_execute(self, cmd): if len(cmd.args) != 1: await cmd.channel.send( 'Wrong number of arguments for `{0}`.'.format(self.mention) ) return filename = cmd.args[0] if not filename.endswith('.csv'): await cmd.channel.send( 'Matchup file should be a `.csv` file.' ) return file_path = os.path.join(filename) if not os.path.isfile(file_path): await cmd.channel.send( 'Cannot find file `{}`.'.format(filename) ) return match_info = LeagueMgr().league.match_info status_message = await cmd.channel.send( 'Creating matches from file `{0}`... (Reading file)'.format(filename) ) async with cmd.channel.typing(): # Store file data desired_match_pairs = [] with open(file_path) as file: for line in file: racernames = line.rstrip('\n').split(',') desired_match_pairs.append((racernames[0].lower(), racernames[1].lower(),)) # Find all racers all_racers = dict() for racerpair in desired_match_pairs: all_racers[racerpair[0]] = None all_racers[racerpair[1]] = None await userlib.fill_user_dict(all_racers) console.debug('MakeMatchesFromFile: Filled user dict: {}'.format(all_racers)) # Create Match objects matches = [] not_found_matches = [] async def make_single_match(racers): console.debug('MakeMatchesFromFile: Making match {0}-{1}'.format(racers[0], racers[1])) racer_1 = all_racers[racers[0]] racer_2 = all_racers[racers[1]] if racer_1 is None or racer_2 is None: console.warning('Couldn\'t find racers for match {0}-{1}.'.format( racers[0], racers[1] )) not_found_matches.append('`{0}`-`{1}`'.format(racers[0], racers[1])) return new_match = await matchutil.make_match( register=True, racer_1_id=racer_1.user_id, racer_2_id=racer_2.user_id, match_info=match_info, autogenned=True ) if new_match is None: console.debug('MakeMatchesFromFile: Match {0}-{1} not created.'.format(racers[0], racers[1])) not_found_matches.append('{0}-{1}'.format(racers[0], racers[1])) return matches.append(new_match) console.debug('MakeMatchesFromFile: Created {0}-{1}'.format( new_match.racer_1.rtmp_name, new_match.racer_2.rtmp_name) ) for racer_pair in desired_match_pairs: await make_single_match(racer_pair) matches = sorted(matches, key=lambda m: m.matchroom_name) await status_message.edit( content='Creating matches from file `{0}`... (Creating race rooms)'.format(filename) ) console.debug('MakeMatchesFromFile: Matches to make: {0}'.format(matches)) # Create match channels for match in matches: console.info('MakeMatchesFromFile: Creating {0}...'.format(match.matchroom_name)) new_room = await matchchannelutil.make_match_room(match=match, register=False) await new_room.send_channel_start_text() # Report on uncreated matches uncreated_str = '' for match_str in not_found_matches: uncreated_str += match_str + ', ' if uncreated_str: uncreated_str = uncreated_str[:-2] if uncreated_str: report_str = 'The following matches were not made: {0}'.format(uncreated_str) else: report_str = 'All matches created successfully.' await status_message.edit( content='Creating matches from file `{0}`... done. {1}'.format(filename, report_str) )
def execute(self, operation, *args, **kwargs): console.debug('Execute SQL: <{0}> <args={1}> <kwargs={2}>'.format( operation, args, kwargs)) return self.cursor.execute(operation, *args, **kwargs)
async def _makematches_from_pairs(cmd, league, desired_match_pairs): status_message = await cmd.channel.send( 'Creating matches... (Checking usernames)') match_info = league.match_info async with cmd.channel.typing(): # Find all racers all_racers = dict() # type: Dict[str, List[NecroUser]] for racerpair in desired_match_pairs: all_racers[racerpair[0]] = [] all_racers[racerpair[1]] = [] await userlib.fill_user_dict(all_racers) console.debug( '_makematches_from_pairs: Filled user dict: {}'.format(all_racers)) not_found_racers = [] doublename_racers = [] for username, userlist in all_racers.items(): if len(userlist) == 0: not_found_racers.append(username) elif len(userlist) > 1: doublename_racers.append(username) # Create Match objects matches = [] not_found_matches = [] # type: List[Tuple[str, str]] async def make_single_match(racers): console.debug( '_makematches_from_pairs: Making match {0}-{1}'.format( racers[0], racers[1])) racer_1 = all_racers[racers[0]][0] if len( all_racers[racers[0]]) == 1 else None racer_2 = all_racers[racers[1]][0] if len( all_racers[racers[1]]) == 1 else None if racer_1 is None or racer_2 is None: console.warning( 'Couldn\'t find racers for match {0}-{1}.'.format( racers[0], racers[1])) not_found_matches.append((racers[0], racers[1])) return new_match = await matchutil.make_match(register=True, racer_1_id=racer_1.user_id, racer_2_id=racer_2.user_id, match_info=match_info, league_tag=league.tag, autogenned=True) if new_match is None: console.debug( '_makematches_from_pairs: Match {0}-{1} not created.'. format(racers[0], racers[1])) not_found_matches.append((racers[0], racers[1])) return matches.append(new_match) console.debug('_makematches_from_pairs: Created {0}-{1}'.format( new_match.racer_1.matchroom_name, new_match.racer_2.matchroom_name)) for racer_pair in desired_match_pairs: await make_single_match(racer_pair) await asyncio.sleep(0) matches = sorted(matches, key=lambda m: m.matchroom_name) await status_message.edit( content='Creating matches... (Creating race rooms)') console.debug( '_makematches_from_pairs: Matches to make: {0}'.format(matches)) # Create match channels for match in matches: console.info('MakeMatchesFromFile: Creating {0}...'.format( match.matchroom_name)) new_room = await matchchannelutil.make_match_room(match=match, register=False) await new_room.send_channel_start_text() # Report on uncreated matches if not_found_matches: filename = leagueutil.get_unmade_matches_filename( league_tag=league.tag) with open(filename, 'w') as file: for r1, r2 in not_found_matches: file.write(f'{r1},{r2}\n') uncreated_str = ', '.join(f'`{t[0]}-{t[1]}`' for t in not_found_matches) report_str = f'The following matches were not made: {uncreated_str}. These matches were written to ' \ f'`{filename}`. Call `.make-unmade-matches` to attempt to remake these easily.' else: report_str = 'All matches created successfully.' unfound_racers_str = ', '.join(f'`{n}`' for n in not_found_racers) doubled_racers_str = ', '.join(f'`{n}`' for n in doublename_racers) if not_found_racers: report_str += \ f'\n\nThe following racers could not be found: {unfound_racers_str}.' if doubled_racers_str: report_str += \ f'\n\nThe following names were associated to more than one Discord account: {doubled_racers_str}.' await status_message.edit( content=f'Creating matches... done.\n\n{report_str}')