Example #1
0
 def user_disp(self) -> str:
     """ Displayed user: either a mention if possible, else their user_name_only. """
     try:
         s_user_id = extract_user_id(self.user_id)
     except discord.InvalidArgument:
         return self.user_name_only.strip()
     else:
         return user_mention(s_user_id)
Example #2
0
 def discord_str(self):
     try:
         s_user_id = extract_user_id(self.user_id)
     except discord.InvalidArgument:
         author_value = "{} (invalid ID)".format(self.user_name_only)
     else:
         author_value = "{} ({})".format(self.user_name_only, user_mention(s_user_id))
     return "{} - *{}*".format(author_value, self.project.replace('*', '\\*'))
Example #3
0
async def query_user(bot: discord.Client, id_: str):
    """
    Find a user given an ID string passed by command, or create it if it does not exist.

    id_ can be passed to a command in four formats:
    * Discord Mention: <@123456789012345678>
    * Discord ID: 123456789012345678
    * Discord Name+Discriminator: Username#1234
    * Database ID: *134

    For Discord-based inputs, if the user is not found but exists on Discord, a new
    entry is created. In other cases, a :cls:`~.UserNotFound` error is raised.

    :raises UserNotFound: User was not found. Either the Discord user exists neither on Discord
        nor in the database, or a database ID was passed and could not be found.
    :raises discord.HTTPException: Discord API error occurred
    :raises db.exc.MultipleResultsFound: Should never happen - database is buggered.
    """
    # Parse the passed ID
    if id_.startswith('*'):  # KazTron database ID lookup
        try:
            db_id = int(id_[1:])
        except ValueError:
            raise ValueError(
                'Invalid KazTron user ID: must be "*" followed by a number')
        db_user = await get_user_by_db_id(db_id, bot)
    elif id_[-5] == '#':  # name#discriminator lookup
        id_ = id_.lstrip('@')  # stray @ from an attempted mention
        for server in bot.servers:
            member = server.get_member_named(id_)
            if member:
                db_user = await get_user_by_discord_id(member.id, bot)
                break
        else:
            raise ValueError('Invalid Discord user ID format')
    else:  # mention/ID lookup
        try:
            discord_id = extract_user_id(id_)
        except discord.InvalidArgument:
            raise ValueError('Invalid Discord user ID format')
        db_user = await get_user_by_discord_id(discord_id, bot)

    for server in bot.servers:
        member = server.get_member(db_user.discord_id)  # type: discord.Member
        if member:
            update_nicknames(db_user, member)
            break
    else:
        logger.warning(
            "Can't find Discord member to update nicknames for {!r}".format(
                db_user))

    return db_user
Example #4
0
    async def send_spotlight_info(self, destination: discord.Object, app: SpotlightApp) -> None:
        """
        Sends a discord.Embed object containing human-readable formatted
        spotlight_data to the given destination.

        :param destination: The destination as a Discord object (often a :cls:`discord.Channel`)
        :param app: the array of spotlight data to send
        :return: None, or a :cls:`discord.HTTPException` class if sending fails (this is already
            logged and communicated over Discord, provided for informational purposes/further
            handling)
        """
        index = self.applications.index(app) + 1
        logger.info("Displaying spotlight data for: {!s}".format(app))

        try:
            s_user_id = extract_user_id(app.user_id)
        except discord.InvalidArgument:
            author_value = "{} (invalid ID)".format(app.user_name_only)
        else:
            author_value = "{} ({})".format(user_mention(s_user_id), app.user_name_only)

        em = discord.Embed(color=0x80AAFF)
        em.add_field(name="Project Name", value=app.project, inline=True)
        em.add_field(name="Author", value=author_value, inline=True)

        # if app.is_filled(app.user_reddit):
        #     em.add_field(name="Reddit", value="/u/" + app.user_reddit[:128], inline=True)

        em.add_field(name="Elevator Pitch",
                     value=natural_truncate(app.pitch, Limits.EMBED_FIELD_VALUE) or "None",
                     inline=False)

        if app.is_filled(app.mature):
            em.add_field(name="Mature & Controversial Issues",
                         value=natural_truncate(app.mature, Limits.EMBED_FIELD_VALUE),
                         inline=False)

        em.add_field(name="Keywords",
                     value=natural_truncate(app.keywords, Limits.EMBED_FIELD_VALUE) or "None",
                     inline=False)

        if app.is_filled(app.art_url):
            em.add_field(name="Project Art",
                         value=natural_truncate(app.art_url, Limits.EMBED_FIELD_VALUE),
                         inline=True)

        if app.is_filled(app.additional_info_url):
            em.add_field(name="Additional Content",
                         value=natural_truncate(app.additional_info_url, Limits.EMBED_FIELD_VALUE),
                         inline=True)

        await self.bot.send_message(destination, embed=em)
        await self.bot.say("Spotlight ID #{:d}: {!s}".format(index, app))
Example #5
0
def query_user(server: discord.Server, id_: str):
    """
    Find a user given an ID string passed by command, or create it if it does not exist.

    id_ can be passed to a command as a discord mention ``<@123456789012345678>`` or
    ``<@!123456789012345678>``, or as a Discord ID ``123456789012345678`` (various malformed
    inputs may also be accepted, e.g., ``@123456789012345678``).

    For Discord Mention or Discord ID, if the user is not found but exists on Discord, a new
    entry is created. In other cases, a :cls:`~.UserNotFound` error is raised.

    :raises UserNotFound: User was not found. Either the Discord user exists neither on Discord
        nor in the database, or a database ID was passed and could not be found.
    :raises discord.HTTPException: Discord API error occurred
    :raises db.exc.MultipleResultsFound: Should never happen - database is buggered.
    """

    # Parse the passed ID
    try:
        discord_id = extract_user_id(id_)
    except discord.InvalidArgument:
        raise ValueError('Invalid Discord user ID format')
    logger.debug('query_user: passed Discord ID: {}'.format(discord_id))

    # Check if user exists
    try:
        db_user = session.query(User).filter_by(discord_id=discord_id).one()
    except db.orm_exc.MultipleResultsFound:
        logger.exception("Er, mate, I think we've got a problem here. "
                         "The database is buggered.")
        raise
    except db.orm_exc.NoResultFound:
        logger.debug('query_user: user not found, creating user')
        try:
            member = server.get_member(discord_id)  # type: discord.Member
        except discord.NotFound as e:
            raise UserNotFound('Discord user not found') from e
        db_user = create_user(member)
        logger.debug('query_user: created user: {!r}'.format(db_user))
    else:
        logger.debug('query_user: found user: {!r}'.format(db_user))

        try:
            member = server.get_member(discord_id)  # type: discord.Member
        except discord.NotFound:
            logger.warning("Can't find user {!r} on Discord, skipping update nicknames"
                .format(db_user))
        else:
            update_nicknames(db_user, member)

    return db_user
Example #6
0
    async def send_validation_warnings(self, ctx: commands.Context, app: SpotlightApp):
        """
        Handles validating the app (mostly existence of the user), and communicating any warnings
        via Discord message to msg_dest.
        """
        try:
            user_id = extract_user_id(app.user_id)
        except discord.InvalidArgument:
            logger.warning("User ID format for spotlight app is invalid: '{}'".format(app.user_id))
            await self.bot.say("**Warning**: User ID format is invalid: '{}'".format(app.user_id))
            return

        # user not on server
        if ctx.message.server.get_member(user_id) is None:
            logger.warning("Spotlight app user not on server: '{}' {}"
                .format(app.user_name_only, user_id))
            await self.bot.say("**Warning:** User not on server: {} {}"
                .format(app.user_name_only, user_mention(user_id)))
Example #7
0
def process_project_row(row_dict) -> dict:
    """
    Process a project row. Pre-process and validate all fields, and look up the user in the database
    based on the discord_id field.
    """
    proj_dict = OrderedDict()

    if None in row_dict:  # too many columns
        raise ValueError(
            "CSV file row contains too many columns (title={!r})".format(
                row_dict['title']))

    for key, val in row_dict.items():
        if key == 'discord_id':
            member_obj = discord.Object(extract_user_id(
                row_dict['discord_id']))
            user = query.get_or_make_user(member_obj)
            proj_dict['user'] = user
        else:
            proj_dict[key] = wizard.validators[key](
                val.strip()) if val else None
    proj_dict.user_id = proj_dict['user'].discord_id
    return proj_dict