Beispiel #1
0
async def _do_rtmp_register(cmd: Command, cmd_type: CommandType, user: NecroUser, rtmp_name: str):
    try:
        user.set(rtmp_name=rtmp_name, commit=False)
        await user.commit()
    except mysql.connector.IntegrityError:
        duplicate_user = await userlib.get_user(rtmp_name=rtmp_name)
        if duplicate_user is None:
            await cmd_type.client.send_message(
                cmd.channel,
                'Unexpected error: Query raised a mysql.connector.IntegrityError, but couldn\'t find a racer '
                'with RTMP name `{0}`.'.format(rtmp_name)
            )
        else:
            await cmd_type.client.send_message(
                cmd.channel,
                'Error: This RTMP is already registered to the discord user `{0}`.'.format(
                    duplicate_user.discord_name)
            )
        return

    await NEDispatch().publish(event_type='rtmp_name_change', user=user)
    await cmd_type.client.send_message(
        cmd.channel,
        '{0}: Registered the RTMP `{1}` to user `{2}`.'.format(
            cmd.author.mention, rtmp_name, user.discord_name)
    )
Beispiel #2
0
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
Beispiel #3
0
async def _register_user(necro_user: NecroUser):
    rtmp_clash_user_id = await _get_resolvable_rtmp_clash_user_id(necro_user)

    params = (
        necro_user.discord_id,
        necro_user.discord_name,
        necro_user.twitch_name,
        necro_user.timezone_str,
        necro_user.user_info,
        necro_user.user_prefs.daily_alert,
        necro_user.user_prefs.race_alert,
        necro_user.rtmp_name,
    )

    async with DBConnect(commit=True) as cursor:
        if rtmp_clash_user_id is None:
            try:
                cursor.execute(
                    """
                    INSERT INTO users 
                    (discord_id, discord_name, twitch_name, timezone, user_info, daily_alert, race_alert, rtmp_name) 
                    VALUES (%s,%s,%s,%s,%s,%s,%s,%s) 
                    """, params)
                cursor.execute("SELECT LAST_INSERT_ID()")
                uid = int(cursor.fetchone()[0])
                necro_user._user_id = uid
            except mysql.connector.IntegrityError:
                console.warning(
                    'Tried to insert a duplicate racer entry. Params: {0}'.
                    format(params))
                raise
        else:
            cursor.execute(
                """
                UPDATE users 
                SET 
                   discord_id=%s, 
                   discord_name=%s, 
                   twitch_name=%s, 
                   timezone=%s, 
                   user_info=%s, 
                   daily_alert=%s, 
                   race_alert=%s 
                WHERE rtmp_name=%s
                """, params)
            necro_user._user_id = rtmp_clash_user_id
Beispiel #4
0
async def _get_user_any_name(name: str, register: bool) -> NecroUser or None:
    raw_db_data = await userdb.get_users_with_any(
        discord_name=name,
        twitch_name=name,
        rtmp_name=name,
    )

    if not raw_db_data:
        if not register:
            return None
        else:
            user = NecroUser(commit_fn=userdb.write_user)
            user.set(rtmp_name=name, commit=False)
            await user.commit()
            _cache_user(user)
            return user

    raw_db_data = sorted(raw_db_data,
                         key=lambda x: _raw_db_sort_fn(x, name, name, name),
                         reverse=True)
    for user_row in raw_db_data:
        return _get_user_from_db_row(user_row)
Beispiel #5
0
async def _get_user_any_name(name: str, register: bool) -> NecroUser or None:
    cached_user = _get_cached_user(rtmp_name=name)
    if cached_user is not None:
        return cached_user

    raw_db_data = await userdb.get_users_with_any(
        discord_name=name,
        twitch_name=name,
        rtmp_name=name,
    )

    if not raw_db_data:
        if not register:
            return None
        else:
            user = NecroUser(commit_fn=userdb.write_user)
            user.set(rtmp_name=name, commit=False)
            await user.commit()
            _cache_user(user)
            return user
    elif len(raw_db_data) > 1:

        def sort_fn(row):
            return \
                32*int(row[3] == name) \
                + 16*int(row[3].lower() == name.lower() if row[3] is not None else 0) + \
                8*int(row[1] == name) \
                + 4*int(row[1].lower() == name.lower() if row[1] is not None else 0) + \
                2*int(row[2] == name) \
                + 1*int(row[2].lower() == name.lower() if row[2] is not None else 0)

        raw_db_data = sorted(raw_db_data,
                             key=lambda x: sort_fn(x),
                             reverse=True)

    for user_row in raw_db_data:
        return _get_user_from_db_row(user_row)
Beispiel #6
0
async def get_user(discord_id: int = None,
                   discord_name: str = None,
                   twitch_name: str = None,
                   rtmp_name: str = None,
                   user_id: int = None,
                   any_name: str = None,
                   register: bool = False) -> NecroUser or None:
    """Search for a NecroUser satisfying the given parameter. Behavior only guaranteed when exactly one of the
    parameters other than register is non-None.

    Parameters
    ----------
    discord_id: int
        The user's discord ID.
    discord_name: str
        The user's discord name. Case-insensitve.
    twitch_name: str
        The user's twitch name. Case-insensitve.
    rtmp_name: str
        The user's RTMP name. Case-insensitve.
    user_id: int
        The user's database ID.
    any_name: str
        Will search for a user, if possible, whose rtmp_name, discord_name, or twitch_name is equal to that name, 
        case-insensitive. If multiple users, prioritize by name type (1=rtmp, 2=discord, 3=twitch), then randomly.
        Providing this field means that the above fields will be ignored.
    register: bool
        If True, will register a new user if none is found matching the given parameters. This requires that either
        discord_id, rtmp_name, or any_name is not None. (If any_name is given, it will be registered as an RTMP name.)

    Returns
    -------
    NecroUser or None
        The found NecroUser object.
    """
    if any_name is not None:
        return await _get_user_any_name(any_name, register)

    if discord_id is None and discord_name is None and twitch_name is None \
            and rtmp_name is None and user_id is None:
        return None

    cached_user = _get_cached_user(discord_id=discord_id, user_id=user_id)
    if cached_user is not None:
        return cached_user

    raw_db_data = await userdb.get_users_with_all(discord_id=discord_id,
                                                  discord_name=discord_name,
                                                  twitch_name=twitch_name,
                                                  rtmp_name=rtmp_name,
                                                  user_id=user_id)

    # If no user found, register if asked, otherwise return None
    if not raw_db_data:
        if not register:
            return None
        elif rtmp_name is not None:
            user = NecroUser(commit_fn=userdb.write_user)
            user.set(rtmp_name=rtmp_name, commit=False)
            await user.commit()
            _cache_user(user)
            return user
        elif discord_id is not None:
            discord_member = server.find_member(discord_id=discord_id)
            if discord_member is not None:
                user = NecroUser(commit_fn=userdb.write_user)
                user.set(discord_member=discord_member, commit=False)
                await user.commit()
                _cache_user(user)
                return user
        else:
            console.warning(
                'Tried to register a NecroUser without providing a name or ID.'
            )
            return None

    # If more than one user is found, raise an exception
    elif len(raw_db_data) > 1:
        raise necrobot.exception.DuplicateUserException(
            'Two or more users found satisfying discord_id={0}, discord_name={1}, twitch_name={2}, '
            'rtmp_name={3}, user_id={4}.'.format(discord_id, discord_name,
                                                 twitch_name, rtmp_name,
                                                 user_id))

    # Exactly one user was found; convert into a NecroUser and return it
    for row in raw_db_data:
        return _get_user_from_db_row(row)

    return None