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 sheet_id = cmd.args[0] perm_info = await sheetutil.has_read_write_permissions(sheet_id) if not perm_info[0]: await self.client.send_message( cmd.channel, 'Cannot access GSheet: {0}'.format(perm_info[1]) ) return LeagueMgr().league.gsheet_id = sheet_id LeagueMgr().league.commit() await self.client.send_message( cmd.channel, 'Set default GSheet to "{0}". <{1}>'.format( perm_info[1], 'https://docs.google.com/spreadsheets/d/{0}'.format(sheet_id) ) )
async def _do_execute(self, cmd: Command) -> None: if len(cmd.args) != 1: await cmd.channel.send( 'Error: `{0}` requires exactly one argument.'.format( self.mention)) return sheet_id = cmd.args[0] perm_info = await sheetutil.has_read_write_permissions(sheet_id) if not perm_info[0]: await cmd.channel.send('Cannot access GSheet: {0}'.format( perm_info[1])) return LeagueMgr().league.speedrun_gsheet_id = sheet_id LeagueMgr().league.commit() await cmd.channel.send( 'The speedrun GSheet for `{league_name}` has been set to "{sheet_name}". <{sheet_url}>' .format( league_name=LeagueMgr().league.schema_name, sheet_name=perm_info[1], sheet_url='https://docs.google.com/spreadsheets/d/{0}'.format( LeagueMgr().league.speedrun_gsheet_id)))
async def _do_execute(self, cmd: Command): if LeagueMgr().league is None: await self.client.send_message( cmd.channel, 'Error: No league set.' ) return deadline_str = LeagueMgr().league.deadline if deadline_str is None: await self.client.send_message( cmd.channel, 'No deadline is set for the current league.' ) return try: deadline = dateparse.parse_datetime(deadline_str) except necrobot.exception.ParseException as e: await self.client.send_message(cmd.channel, str(e)) return await self.client.send_message( cmd.channel, 'The current league deadline is "{deadline_str}". As of now, this is ' '{deadline:%b %d (%A) at %I:%M %p} (UTC).' .format( deadline_str=deadline_str, deadline=deadline ) )
async def _do_execute(self, cmd: Command): await self.client.send_typing(cmd.channel) gsheet_id = LeagueMgr().league.gsheet_id if gsheet_id is None: await self.client.send_message( cmd.channel, 'Error: GSheet for this league is not yet set. Use `.setgsheet`.' ) return try: perm_info = await sheetutil.has_read_write_permissions( LeagueMgr().league.gsheet_id) except googleapiclient.errors.Error as e: await self.client.send_message(cmd.channel, 'Error: {0}'.format(e)) return if not perm_info[0]: await self.client.send_message( cmd.channel, 'Cannot access GSheet: {0}'.format(perm_info[1])) return else: await self.client.send_message( cmd.channel, 'The GSheet for `{league_name}` is "{sheet_name}". <{sheet_url}>' .format(league_name=LeagueMgr().league.schema_name, sheet_name=perm_info[1], sheet_url='https://docs.google.com/spreadsheets/d/{0}'. format(LeagueMgr().league.gsheet_id)))
async def _do_execute(self, cmd: Command): if LeagueMgr().league is None: await self.client.send_message( cmd.channel, 'Error: No league set.' ) return try: deadline = dateparse.parse_datetime(cmd.arg_string) except necrobot.exception.ParseException as e: await self.client.send_message(cmd.channel, str(e)) return LeagueMgr().league.deadline = cmd.arg_string LeagueMgr().league.commit() await self.client.send_message( cmd.channel, 'Set the current league\'s deadline to "{deadline_str}". As of now, this is ' '{deadline:%b %d (%A) at %I:%M %p (%Z)}.' .format( deadline_str=cmd.arg_string, deadline=deadline ) )
async def _do_execute(self, cmd: Command): league = LeagueMgr().league if league is None: await cmd.channel.send( 'Error: The current event (`{0}`) does not exist.'.format(Config.LEAGUE_NAME) ) return league.name = cmd.arg_string league.commit() await cmd.channel.send( 'Set the name of current CoNDOR event (`{0}`) to {1}.'.format(league.schema_name, league.name) )
async def load_condorbot_config(necrobot): # PM Channel necrobot.register_pm_channel(CondorPMChannel()) # Main Channel main_channel = server.find_channel(channel_id=Config.MAIN_CHANNEL_ID) if main_channel is None: console.warning( f'Could not find the main channel <#{Config.MAIN_CHANNEL_ID}>.') necrobot.register_bot_channel(main_channel, CondorMainChannel(ladder=True)) # Admin Channel admin_channel_name = 'adminchat' condor_admin_channel = server.find_channel(channel_name=admin_channel_name) if condor_admin_channel is None: console.warning( f'Could not find the admin channel "{admin_channel_name}".') necrobot.register_bot_channel(condor_admin_channel, CondorAdminChannel()) # Managers (Order is important!) necrobot.register_manager(CondorMgr()) necrobot.register_manager(LeagueMgr()) necrobot.register_manager(MatchMgr()) # Ratings ratingutil.init()
async def _do_execute(self, cmd): # Parse arguments if len(cmd.args) != 1: await cmd.channel.send( 'Error: Wrong number of arguments for `{0}`.'.format(self.mention)) return league = LeagueMgr().league if league is None: await cmd.channel.send( 'Error: The current event (`{0}`) does not exist.'.format(Config.LEAGUE_NAME) ) return # Make the match try: new_match = await cmd_matchmake.make_match_from_cmd( cmd=cmd, racer_names=[cmd.author.display_name, cmd.args[0]], match_info=league.match_info, allow_duplicates=False ) except necrobot.exception.DuplicateMatchException: await cmd.channel.send( 'A match between `{r1}` and `{r2}` already exists! Contact incnone if this is in error.'.format( r1=cmd.author.display_name, r2=cmd.args[0] ) ) return if new_match is not None: await NEDispatch().publish(event_type='create_match', match=new_match)
async def _do_execute(self, cmd: Command): league = LeagueMgr().league if league is None: await cmd.channel.send( 'Error: The current event (`{0}`) does not exist.'.format(Config.LEAGUE_NAME) ) return await cmd.channel.send( 'Current event (`{0}`) default rules: {1}'.format(league.schema_name, league.match_info.format_str) )
async def _do_execute(self, cmd: Command): league = LeagueMgr().league if league is None: await cmd.channel.send( 'Error: The current event (`{0}`) does not exist.'.format(Config.LEAGUE_NAME) ) return try: match_info = matchinfo.parse_args(cmd.args) except necrobot.exception.ParseException as e: await cmd.channel.send( 'Error parsing inputs: {0}'.format(e) ) return league.match_info = match_info league.commit() await cmd.channel.send( 'Set the default match rules for `{0}` to {1}.'.format(league.schema_name, match_info.format_str) )
async def _do_execute(self, cmd): if len(cmd.args) != 0: await cmd.channel.send( 'Wrong number of arguments for `{0}`.'.format(self.mention)) return league_list = LeagueMgr().leagues() await cmd.channel.send( f'Remaking unmade matches for all leagues ({", ".join(f"`{t}`" for t in league_list)})' ) for league_tag in league_list: await self._make_unmade_for_league(cmd=cmd, league_tag=league_tag)
async def _do_execute(self, cmd: Command): league = LeagueMgr().league if league is None: await self.client.send_message( cmd.channel, 'Error: The current event (`{0}`) does not exist.'.format(Config.LEAGUE_NAME) ) return try: match_info = matchinfo.parse_args(cmd.args) except necrobot.exception.ParseException as e: await self.client.send_message(cmd.channel, e) return match_info.race_info.condor_race = True league.match_info = match_info league.commit() await self.client.send_message( cmd.channel, 'Set the default match rules for `{0}` to {1}.'.format(league.schema_name, match_info.format_str) )
async def _do_execute(self, cmd: Command): league = LeagueMgr().league if league is None: await cmd.channel.send( 'Error: The current event (`{0}`) does not exist.'.format(Config.LEAGUE_NAME) ) return await cmd.channel.send( '```\n' 'Current event:\n' ' ID: {0}\n' ' Name: {1}\n' '```'.format(league.schema_name, league.name) )
async def _do_execute(self, cmd: Command): # Get the matchup sheet wks_id = 0 try: matchup_sheet = await sheetlib.get_sheet( gsheet_id=LeagueMgr().league.gsheet_id, wks_id=wks_id, sheet_type=sheetlib.SheetType.MATCHUP) # type: MatchupSheet except (googleapiclient.errors.Error, necrobot.exception.NecroException) as e: await cmd.channel.send('Error accessing GSheet: `{0}`'.format(e)) return if matchup_sheet is None: await cmd.channel.send('Error: MatchupSheet is None.') return await matchup_sheet.overwrite_gsheet()
async def load_condorbot_config(necrobot): # PM Channel necrobot.register_pm_channel(CondorPMChannel()) # Main Channel necrobot.register_bot_channel(server.main_channel, CondorMainChannel()) # Admin channel condor_admin_channel = server.find_channel(channel_name='adminchat') if condor_admin_channel is None: console.warning('Could not find the "{0}" channel.'.format('adminchat')) necrobot.register_bot_channel(condor_admin_channel, CondorAdminChannel()) # Managers (Order is very important!) necrobot.register_manager(LeagueMgr()) necrobot.register_manager(MatchMgr()) necrobot.register_manager(CondorMgr()) # Ratings ratingutil.init()
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 schema_name = cmd.args[0].lower() try: await LeagueMgr().set_league(schema_name=schema_name) except necrobot.exception.LeagueDoesNotExist: await cmd.channel.send( 'Error: Event `{0}` does not exist.'.format(schema_name) ) return league_name = LeagueMgr().league.name league_name_str = ' ({0})'.format(league_name) if league_name is not None else '' await cmd.channel.send( 'Set the current CoNDOR event to `{0}`{1}.'.format(schema_name, league_name_str) )
async def _do_execute(self, cmd): # Parse arguments if len(cmd.args) != 2: await cmd.channel.send( 'Error: Wrong number of arguments for `{0}`.'.format(self.mention)) return league = LeagueMgr().league if league is None: await cmd.channel.send( 'Error: The current event (`{0}`) does not exist.'.format(Config.LEAGUE_NAME) ) return new_match = await cmd_matchmake.make_match_from_cmd( cmd=cmd, racer_names=[cmd.args[0], cmd.args[1]], match_info=league.match_info ) if new_match is not None: await NEDispatch().publish(event_type='create_match', match=new_match)
async def _do_execute(self, cmd): # Parse arguments if len(cmd.args) != 2: await self.client.send_message( cmd.channel, 'Error: Wrong number of arguments for `{0}`.'.format(self.mention)) return league = LeagueMgr().league if league is None: await self.client.send_message( cmd.channel, 'Error: The current event (`{0}`) does not exist.'.format(Config.LEAGUE_NAME) ) return await cmd_matchmake.make_match_from_cmd( cmd=cmd, cmd_type=self, racer_names=[cmd.args[0], cmd.args[1]], match_info=league.match_info )
async def load_condorbot_config(necrobot): # PM Channel necrobot.register_pm_channel(CondorPMChannel()) # Main Channel server.main_channel = server.find_channel(channel_name=Config.MAIN_CHANNEL_NAME) if server.main_channel is None: console.warning(f'Could not find the "{Config.MAIN_CHANNEL_NAME}" channel.') necrobot.register_bot_channel(server.main_channel, CondorMainChannel()) # Admin channel condor_admin_channel = server.find_channel(channel_name=Config.ADMIN_CHANNEL_NAME) if condor_admin_channel is None: console.warning(f'Could not find the "{Config.ADMIN_CHANNEL_NAME}" channel.') necrobot.register_bot_channel(condor_admin_channel, CondorAdminChannel()) # Managers (Order is important!) necrobot.register_manager(LeagueMgr()) necrobot.register_manager(MatchMgr()) necrobot.register_manager(CondorMgr()) # Ratings ratingutil.init()
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) )
async def get_standings_sheet() -> StandingsSheet: return await sheetlib.get_sheet( gsheet_id=LeagueMgr().league.gsheet_id, wks_name='Standings', sheet_type=sheetlib.SheetType.STANDINGS)
async def get_gsheet(wks_id: str) -> MatchupSheet: return await sheetlib.get_sheet(gsheet_id=LeagueMgr().league.gsheet_id, wks_id=wks_id, sheet_type=sheetlib.SheetType.MATCHUP)
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): match = self.bot_channel.match # type: Match wks_id = match.sheet_id if wks_id is None: await self.client.send_message( cmd.channel, 'Error: No worksheet is assigned to this match (contact incnone).' ) return match_row = match.sheet_row if match_row is None: await self.client.send_message( cmd.channel, 'Error: This match doesn\'t have a designated sheet row (contact incnone).' ) return try: matchup_sheet = await sheetlib.get_sheet( gsheet_id=LeagueMgr().league.gsheet_id, wks_id=wks_id, sheet_type=sheetlib.SheetType.MATCHUP) # type: MatchupSheet standings_sheet = await sheetlib.get_sheet( gsheet_id=LeagueMgr().league.gsheet_id, wks_name='Standings', sheet_type=sheetlib.SheetType.STANDINGS ) # type: StandingsSheet except (googleapiclient.errors.Error, necrobot.exception.NecroException) as e: await self.client.send_message( cmd.channel, 'Error accessing GSheet: `{0}`'.format(e)) return # TODO after combining MatchRaceData with match, simplify (code duping with MatchRoom) if match.is_scheduled: await matchup_sheet.schedule_match(match) await matchup_sheet.set_cawmentary(match) match_race_data = await matchutil.get_race_data( match) # type: MatchRaceData if match.is_best_of: played_all = match_race_data.leader_wins > match.number_of_races // 2 else: played_all = match_race_data.num_finished >= match.number_of_races if played_all: # Send event if match_race_data.r1_wins > match_race_data.r2_wins: winner = match.racer_1.display_name winner_wins = match_race_data.r1_wins loser_wins = match_race_data.r2_wins elif match_race_data.r2_wins > match_race_data.r1_wins: winner = match.racer_2.display_name winner_wins = match_race_data.r2_wins loser_wins = match_race_data.r1_wins else: winner = '[Tied]' winner_wins = match_race_data.r1_wins loser_wins = match_race_data.r2_wins await matchup_sheet.record_score(match=match, winner=winner, winner_wins=winner_wins, loser_wins=loser_wins) await standings_sheet.update_standings( match=match, r1_wins=match_race_data.r1_wins, r2_wins=match_race_data.r2_wins) await self.client.send_message(cmd.channel, 'Sheet updated.')
async def _do_execute(self, cmd): match = self.bot_channel.match # Check for match already being confirmed if match.is_scheduled: await self.client.send_message( cmd.channel, 'The scheduled time for this match has already been confirmed by both racers. To reschedule, ' 'both racers should first call `.unconfirm`; you will then be able to `.suggest` a new time.') return # Get the command's author as a NecroUser object author_as_necrouser = await userlib.get_user(discord_id=cmd.author.id) if not author_as_necrouser: await self.client.send_message( cmd.channel, 'Error: {0} is not registered. Please register with `.stream` in the main channel. ' 'If the problem persists, contact CoNDOR Staff.'.format(cmd.author.mention)) return # Check that both racers in the match are registered if not match.racer_1 or not match.racer_2 \ or not match.racer_1.discord_id or not match.racer_2.discord_id: await self.client.send_message( cmd.channel, 'Error: At least one of the racers in this match is not registered, and needs to call ' '`.register` in the main channel. (To check if you are registered, you can call `.userinfo ' '<discord name>`. Use quotes around your discord name if it contains a space.)') return # Check that the command author is racing in the match if not match.racing_in_match(author_as_necrouser): await self.client.send_message( cmd.channel, 'Error: {0} does not appear to be one of the racers in this match. ' 'If this is in error, contact CoNDOR Staff.'.format(cmd.author.mention)) return # Get the racer's timezone if author_as_necrouser.timezone is None: await self.client.send_message( cmd.channel, '{0}: Please register a timezone with `.timezone`.'.format(cmd.author.mention)) return # Parse the inputs as a datetime try: suggested_time_utc = dateparse.parse_datetime(cmd.arg_string, author_as_necrouser.timezone) except necrobot.exception.ParseException as e: await self.client.send_message( cmd.channel, 'Failed to parse your input as a time ({0}).'.format(e)) return # Check if the scheduled time is in the past utcnow = pytz.utc.localize(datetime.datetime.utcnow()) time_until = suggested_time_utc - utcnow if not time_until.total_seconds() >= 0: await self.client.send_message( cmd.channel, '{0}: Error: The time you are suggesting for the match appears to be in the past.'.format( cmd.author.mention)) return # Check for deadlines on suggested times. league = LeagueMgr().league if league is not None: deadline_str = league.deadline if deadline_str is not None: deadline = dateparse.parse_datetime(deadline_str) if suggested_time_utc - deadline > datetime.timedelta(seconds=0): await self.client.send_message( cmd.channel, 'Matches must be scheduled before {deadline:%b %d (%A) at %I:%M %p} UTC' .format(deadline=deadline) ) return # Suggest the time and confirm match.suggest_time(suggested_time_utc) match.confirm_time(author_as_necrouser) # Output what we did for racer in match.racers: if racer.member is not None: if racer.timezone is not None: if racer == author_as_necrouser: await self.client.send_message( cmd.channel, '{0}: You\'ve suggested the match be scheduled for {1}. Waiting for the other ' 'racer to `.confirm`.'.format( racer.member.mention, timestr.str_full_12h(racer.timezone.normalize(suggested_time_utc)))) else: await self.client.send_message( cmd.channel, '{0}: This match is suggested to be scheduled for {1}. Please confirm with ' '`.confirm`.'.format( racer.member.mention, timestr.str_full_12h(racer.timezone.normalize(suggested_time_utc)))) else: await self.client.send_message( cmd.channel, '{0}: A match time has been suggested; please confirm with `.confirm`. I also suggest ' 'you register a timezone (use `.timezone`), so I can convert to your local time.'.format( racer.member.mention)) await self.bot_channel.update()
async def _overwrite_speedrun_sheet(): speedrun_sheet = await sheetlib.get_sheet( gsheet_id=LeagueMgr().league.speedrun_gsheet_id, wks_id='0', sheet_type=sheetlib.SheetType.SPEEDRUN) # type: SpeedrunSheet await speedrun_sheet.overwrite_gsheet()