aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/exts/info/information.py46
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