diff options
| -rw-r--r-- | bot/exts/info/information.py | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 5aaf85e5a..8eec22c58 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -6,11 +6,13 @@ from collections import Counter, defaultdict from string import Template from typing import Any, Mapping, Optional, Tuple, Union +from dateutil import parser from discord import ChannelType, Colour, Embed, Guild, Message, Role, Status, utils from discord.abc import GuildChannel from discord.ext.commands import BucketType, Cog, Context, Paginator, command, group, has_any_role from bot import constants +from bot.api import ResponseCodeError from bot.bot import Bot from bot.converters import FetchedMember from bot.decorators import in_whitelist @@ -21,7 +23,6 @@ from bot.utils.time import time_since log = logging.getLogger(__name__) - STATUS_EMOTES = { Status.offline: constants.Emojis.status_offline, Status.dnd: constants.Emojis.status_dnd, @@ -224,13 +225,16 @@ class Information(Cog): if is_set and (emoji := getattr(constants.Emojis, f"badge_{badge}", None)): badges.append(emoji) + verified_at, activity = await self.user_verification_and_messages(user) + if on_server: joined = time_since(user.joined_at, max_units=3) roles = ", ".join(role.mention for role in user.roles[1:]) - membership = textwrap.dedent(f""" - Joined: {joined} - Roles: {roles or None} - """).strip() + membership = {"Joined": joined, "Verified": verified_at, "Roles": roles or None} + if not is_mod_channel(ctx.channel): + membership.pop("Verified") + + membership = textwrap.dedent("\n".join([f"{key}: {value}" for key, value in membership.items()])) else: roles = None membership = "The user is not a member of the server" @@ -252,6 +256,8 @@ class Information(Cog): # Show more verbose output in moderation channels for infractions and nominations if is_mod_channel(ctx.channel): + fields.append(activity) + fields.append(await self.expanded_user_infraction_counts(user)) fields.append(await self.user_nomination_counts(user)) else: @@ -354,6 +360,36 @@ class Information(Cog): return "Nominations", "\n".join(output) + async def user_verification_and_messages(self, user: FetchedMember) -> Tuple[Union[bool, str], Tuple[str, str]]: + """ + Gets the time of verification and amount of messages for `member`. + + Fetches information from the metricity database that's hosted by the site. + If the database returns a code besides a 404, then many parts of the bot are broken including this one. + """ + activity_output = [] + verified_at = False + + try: + user_activity = await self.bot.api_client.get(f'bot/users/{user.id}/metricity_data') + except ResponseCodeError as e: + if e.status == 404: + activity_output = "No activity" + + else: + verified_at = user_activity['verified_at'] + if verified_at is not None: + verified_at = time_since(parser.isoparse(user_activity["verified_at"]), max_units=3) + + activity_output.append(user_activity['total_messages'] or "No messages") + activity_output.append(user_activity["activity_blocks"] or "No activity") + + activity_output = "\n".join( + f"{name}: {metric}" for name, metric in zip(["Messages", "Activity blocks"], activity_output) + ) + + return verified_at, ("Activity", activity_output) + def format_fields(self, mapping: Mapping[str, Any], field_width: Optional[int] = None) -> str: """Format a mapping to be readable to a human.""" # sorting is technically superfluous but nice if you want to look for a specific field |