Esempio n. 1
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 = []
        for racer in match.racers:
            if racer.member is not None:
                racer_permissions.append(discord.ChannelPermissions(target=racer.member, overwrite=permit_read))

        # Make a channel for the room
        # noinspection PyUnresolvedReferences
        match_channel = await server.client.create_channel(
            server.server,
            get_matchroom_name(match),
            discord.ChannelPermissions(target=server.server.default_role, overwrite=deny_read),
            discord.ChannelPermissions(target=server.server.me, overwrite=permit_read),
            *racer_permissions,
            type=discord.ChannelType.text)

        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
Esempio n. 2
0
async def _register_match(match: Match) -> None:
    match_racetype_id = await racedb.get_race_type_id(race_info=match.race_info, register=True)

    params = (
        match_racetype_id,
        match.racer_1.user_id,
        match.racer_2.user_id,
        match.suggested_time,
        match.confirmed_by_r1,
        match.confirmed_by_r2,
        match.r1_wishes_to_unconfirm,
        match.r2_wishes_to_unconfirm,
        match.ranked,
        match.is_best_of,
        match.number_of_races,
        match.cawmentator_id,
        match.finish_time,
        match.autogenned
    )

    async with DBConnect(commit=True) as cursor:
        cursor.execute(
            """
            INSERT INTO {matches} 
            (
               race_type_id, 
               racer_1_id, 
               racer_2_id, 
               suggested_time, 
               r1_confirmed, 
               r2_confirmed, 
               r1_unconfirmed, 
               r2_unconfirmed, 
               ranked, 
               is_best_of, 
               number_of_races, 
               cawmentator_id,
               finish_time,
               autogenned
            )
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
            """.format(matches=tn('matches')),
            params
        )
        cursor.execute("SELECT LAST_INSERT_ID()")
        match.set_match_id(int(cursor.fetchone()[0]))

        params = (match.racer_1.user_id, match.racer_2.user_id,)
        cursor.execute(
            """
            INSERT IGNORE INTO {entrants} (user_id)
            VALUES (%s), (%s)
            """.format(entrants=tn('entrants')),
            params
        )
Esempio n. 3
0
async def make_match_from_raw_db_data(row: list) -> Match:
    match_id = int(row[0])
    if match_id in match_library:
        return match_library[match_id]

    match_info = MatchInfo(race_info=await racedb.get_race_info_from_type_id(
        int(row[1])) if row[1] is not None else RaceInfo(),
                           ranked=bool(row[9]),
                           is_best_of=bool(row[10]),
                           max_races=int(row[11]))

    sheet_info = MatchGSheetInfo()
    sheet_info.wks_id = row[14]
    sheet_info.row = row[15]

    new_match = Match(commit_fn=matchdb.write_match,
                      match_id=match_id,
                      match_info=match_info,
                      racer_1_id=int(row[2]),
                      racer_2_id=int(row[3]),
                      suggested_time=row[4],
                      finish_time=row[16],
                      r1_confirmed=bool(row[5]),
                      r2_confirmed=bool(row[6]),
                      r1_unconfirmed=bool(row[7]),
                      r2_unconfirmed=bool(row[8]),
                      cawmentator_id=row[12],
                      channel_id=int(row[13]) if row[13] is not None else None,
                      gsheet_info=sheet_info,
                      autogenned=bool(row[17]))

    await new_match.initialize()
    match_library[new_match.match_id] = new_match
    return new_match
Esempio n. 4
0
async def make_match(register=False,
                     update=False,
                     **kwargs) -> Optional[Match]:
    # noinspection PyIncorrectDocstring
    """Create a Match object.

    Parameters
    ----------
    racer_1_id: int
        The DB user ID of the first racer.
    racer_2_id: int
        The DB user ID of the second racer.
    max_races: int
        The maximum number of races this match can be. (If is_best_of is True, then the match is a best of
        max_races; otherwise, the match is just repeating max_races.)
    match_id: int
        The DB unique ID of this match. If this parameter is specified, the return value may be None, if no match
        in the database has the specified ID.
    suggested_time: datetime.datetime
        The time the match is suggested for. If no tzinfo, UTC is assumed.
    r1_confirmed: bool
        Whether the first racer has confirmed the match time.
    r2_confirmed: bool
        Whether the second racer has confirmed the match time.
    r1_unconfirmed: bool
        Whether the first racer wishes to unconfirm the match time.
    r2_unconfirmed: bool
        Whether the second racer wishes to unconfirm the match time.
    match_info: MatchInfo
        The types of races to be run in this match.
    cawmentator_id: int
        The DB unique ID of the cawmentator for this match.
    sheet_id: int
        The sheetID of the worksheet the match was created from, if any.
    league_tag: str
        The tag for the league this match is in, if any.
    register: bool
        Whether to register the match in the database. 
    update: bool
        If match_id is given and this is True, updates the database match with any other specified parameters.
    
    Returns
    ---------
    Match
        The created match.
    """
    if 'match_id' in kwargs and kwargs['match_id'] is not None:
        cached_match = await get_match_from_id(kwargs['match_id'])
        if update and cached_match is not None:
            cached_match.raw_update(**kwargs)
            await cached_match.commit()
        return cached_match

    match = Match(commit_fn=matchdb.write_match, **kwargs)
    await match.initialize()
    if register:
        await match.commit()
        match_library[match.match_id] = match
    return match
Esempio n. 5
0
async def make_match(*args, register=False, update=False, **kwargs) -> Match:
    """Create a Match object. There should be no need to call this directly; use matchutil.make_match instead,
    since this needs to interact with the database.

    Parameters
    ----------
    racer_1_id: int
        The DB user ID of the first racer.
    racer_2_id: int
        The DB user ID of the second racer.
    max_races: int
        The maximum number of races this match can be. (If is_best_of is True, then the match is a best of
        max_races; otherwise, the match is just repeating max_races.)
    match_id: int
        The DB unique ID of this match.
    suggested_time: datetime.datetime
        The time the match is suggested for. If no tzinfo, UTC is assumed.
    r1_confirmed: bool
        Whether the first racer has confirmed the match time.
    r2_confirmed: bool
        Whether the second racer has confirmed the match time.
    r1_unconfirmed: bool
        Whether the first racer wishes to unconfirm the match time.
    r2_unconfirmed: bool
        Whether the second racer wishes to unconfirm the match time.
    match_info: MatchInfo
        The types of races to be run in this match.
    cawmentator_id: int
        The DB unique ID of the cawmentator for this match.
    sheet_id: int
        The sheetID of the worksheet the match was created from, if any.
    register: bool
        Whether to register the match in the database.

    Returns
    ---------
    Match
        The created match.
    """
    if 'match_id' in kwargs and kwargs['match_id'] is not None:
        cached_match = await get_match_from_id(kwargs['match_id'])
        if update:
            cached_match.raw_update(**kwargs)
            await cached_match.commit()
        return cached_match

    match = Match(*args, commit_fn=matchdb.write_match, **kwargs)
    await match.initialize()
    if register:
        await match.commit()
        match_library[match.match_id] = match
    return match
Esempio n. 6
0
async def close_match_room(match: Match) -> None:
    """Close the discord.Channel corresponding to the Match, if any.
    
    Parameters
    ----------
    match: Match
        The Match to close the channel for.
    """
    if not match.is_registered:
        console.warning('Trying to close the room for an unregistered match.')
        return

    channel_id = match.channel_id
    channel = server.find_channel(channel_id=channel_id)
    if channel is None:
        console.warning('Coudn\'t find channel with id {0} in close_match_room '
                        '(match_id={1}).'.format(channel_id, match.match_id))
        return

    await Necrobot().unregister_bot_channel(channel)
    await server.client.delete_channel(channel)
    match.set_channel_id(None)
Esempio n. 7
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