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)
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('*', '\\*'))
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
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))
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
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)))
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