Example #1
0
    async def set_event(self, schema_name: str, save_to_config=True):
        """Set the current CoNDOR event

        Parameters
        ----------
        schema_name: str
            The schema name for the league
        save_to_config: bool
            Whether to make this the default league, i.e., save the schema name to the bot's config file

        Raises
        ------
        necrobot.database.leaguedb.LeagueDoesNotExist
            If the schema name does not refer to a registered league
        """
        if not await condordb.is_condor_event(Config.LEAGUE_NAME):
            raise necrobot.exception.SchemaDoesNotExist('Schema "{0}" does not exist.'.format(schema_name))

        self._event = await condordb.get_event(schema_name=schema_name)
        dbutil.league_schema_name = schema_name
        MatchGlobals().set_deadline_fn(lambda: self.deadline())

        if save_to_config:
            Config.LEAGUE_NAME = schema_name
            Config.write()
Example #2
0
    async def set_league(cls, schema_name: str, save_to_config=True):
        """Set the current league
        
        Parameters
        ----------
        schema_name: str
            The schema name for the league
        save_to_config: bool
            Whether to make this the default league, i.e., save the schema name to the bot's config file
    
        Raises
        ------
        necrobot.database.leaguedb.LeagueDoesNotExist
            If the schema name does not refer to a registered league
        """
        cls._the_league = await leaguedb.get_league(schema_name)
        dbutil.league_schema_name = schema_name

        MatchGlobals().set_deadline_fn(LeagueMgr.deadline)

        if save_to_config:
            Config.LEAGUE_NAME = schema_name
            Config.write()
Example #3
0
 async def initialize(self):
     await self._recover_stored_match_rooms()
     category_channel = server.find_channel(channel_name=Config.MATCH_CHANNEL_CATEGORY_NAME)
     MatchGlobals().set_channel_category(category_channel)
Example #4
0
    async def _do_execute(self, cmd):
        match = self.bot_channel.match

        # Check for match already being confirmed
        if match.is_scheduled:
            await cmd.channel.send(
                '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=int(cmd.author.id))
        if not author_as_necrouser:
            await cmd.channel.send(
                '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 cmd.channel.send(
                '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 cmd.channel.send(
                '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 cmd.channel.send(
                '{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 cmd.channel.send(
                '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 cmd.channel.send(
                '{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.
        deadline = MatchGlobals().deadline
        if deadline is not None and suggested_time_utc - deadline > datetime.timedelta(seconds=0):
            await cmd.channel.send(
                '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 cmd.channel.send(
                            '{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 cmd.channel.send(
                            '{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 cmd.channel.send(
                        '{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()
Example #5
0
async def make_match_room(match: Match, register=False) -> MatchRoom or None:
    """Create a discord.Channel and a corresponding MatchRoom for the given Match. 
    
    Parameters
    ----------
    match: Match
        The Match to create a room for.
    register: bool
        If True, will register the Match in the database.

    Returns
    -------
    Optional[MatchRoom]
        The created room object.
    """
    # Check to see the match is registered
    if not match.is_registered:
        if register:
            await match.commit()
        else:
            console.warning(
                'Tried to make a MatchRoom for an unregistered Match ({0}).'.
                format(match.matchroom_name))
            return None

    # Check to see if we already have the match channel
    channel_id = match.channel_id
    match_channel = server.find_channel(
        channel_id=channel_id) if channel_id is not None else None

    # If we couldn't find the channel or it didn't exist, make a new one
    if match_channel is None:
        # Create permissions
        deny_read = discord.PermissionOverwrite(read_messages=False)
        permit_read = discord.PermissionOverwrite(read_messages=True)
        racer_permissions = {server.guild.default_role: deny_read}
        for racer in match.racers:
            if racer.member is not None:
                racer_permissions[racer.member] = permit_read

        # Find the matches category channel
        channel_categories = MatchGlobals(
        ).channel_categories  # type: List[discord.CategoryChannel]
        if channel_categories is None:
            category_name = Config.MATCH_CHANNEL_CATEGORY_NAME
            if len(category_name) > 0:
                channel_category = await server.create_channel_category(
                    category_name)
                MatchGlobals().set_channel_categories([channel_category])

        # Attempt to create the channel in each of the categories in reverse order
        if channel_categories is not None:
            success = False
            for channel_category in reversed(channel_categories):
                try:
                    match_channel = await server.guild.create_text_channel(
                        name=get_matchroom_name(match),
                        overwrites=racer_permissions,
                        category=channel_category)
                    success = True
                    break
                except discord.HTTPException:
                    pass

            # If we still haven't made the channel, we're out of space, so register a new matches category
            if not success:
                new_channel_category = await server.create_channel_category(
                    name=Config.MATCH_CHANNEL_CATEGORY_NAME)
                MatchGlobals().add_channel_category(
                    channel=new_channel_category)
                match_channel = await server.guild.create_text_channel(
                    name=get_matchroom_name(match),
                    overwrites=racer_permissions,
                    category=new_channel_category)

        # If we don't have or want a category channel, just make the match without a category
        else:
            match_channel = await server.guild.create_text_channel(
                name=get_matchroom_name(match), overwrites=racer_permissions)

        if match_channel is None:
            console.warning('Failed to make a match channel.')
            return None

    # Make the actual RaceRoom and initialize it
    match.set_channel_id(int(match_channel.id))
    new_room = MatchRoom(match_discord_channel=match_channel, match=match)
    Necrobot().register_bot_channel(match_channel, new_room)
    await new_room.initialize()

    return new_room