Added front percent breakdown command

This commit is contained in:
Ske 2018-08-02 11:10:09 +02:00
parent 944f0093a9
commit 3d2d6b0ea6
2 changed files with 101 additions and 11 deletions

View File

@ -1,11 +1,11 @@
import logging from datetime import datetime
from typing import List from typing import List
from urllib.parse import urlparse from urllib.parse import urlparse
import dateparser
import humanize import humanize
import pluralkit.utils import pluralkit.utils
from pluralkit.bot import utils
from pluralkit.bot.commands import * from pluralkit.bot.commands import *
logger = logging.getLogger("pluralkit.commands") logger = logging.getLogger("pluralkit.commands")
@ -216,3 +216,84 @@ async def system_delete(ctx: CommandContext, args: List[str]):
return "System deleted." return "System deleted."
else: else:
return "System deletion cancelled." return "System deletion cancelled."
@command(cmd="system frontpercent", usage="[time]",
description="Shows the fronting percentage of every member, averaged over the given time",
category="System commands")
async def system_frontpercent(ctx: CommandContext, args: List[str]):
# Parse the time limit (will go this far back)
before = dateparser.parse(" ".join(args), languages=["en"], settings={
"TO_TIMEZONE": "UTC",
"RETURN_AS_TIMEZONE_AWARE": False
})
# If time is in the future, just kinda discard
if before and before > datetime.utcnow():
before = None
# Fetch list of switches
all_switches = await pluralkit.utils.get_front_history(ctx.conn, ctx.system.id, 99999)
if not all_switches:
raise CommandError("No switches registered to this system.")
# Cull the switches *ending* before the limit, if given
# We'll need to find the first switch starting before the limit, then cut off every switch *before* that
if before:
for last_stamp, _ in all_switches:
if last_stamp < before:
break
all_switches = [(stamp, members) for stamp, members in all_switches if stamp >= last_stamp]
start_times = [stamp for stamp, _ in all_switches]
end_times = [datetime.utcnow()] + start_times
switch_members = [members for _, members in all_switches]
# Gonna save a list of members by ID for future lookup too
members_by_id = {}
# Using the ID as a key here because it's a simple number that can be hashed and used as a key
member_times = {}
for start_time, end_time, members in zip(start_times, end_times, switch_members):
# Cut off parts of the switch that occurs before the time limit (will only happen if this is the last switch)
if before and start_time < before:
start_time = before
# Calculate length of the switch
switch_length = end_time - start_time
def add_switch(member_id, length):
if member_id not in member_times:
member_times[member_id] = length
else:
member_times[member_id] += length
for member in members:
# Add the switch length to the currently registered time for that member
add_switch(member.id, switch_length)
# Also save the member in the ID map for future reference
members_by_id[member.id] = member
# Also register a no-fronter switch with the key None
if not members:
add_switch(None, switch_length)
# Find the total timespan of the range
span_start = max(start_times[-1], before) if before else start_times[-1]
total_time = datetime.utcnow() - span_start
embed = utils.make_default_embed(None)
for member_id, front_time in sorted(member_times.items(), key=lambda x: x[1], reverse=True):
member = members_by_id[member_id] if member_id else None
# Calculate percent
fraction = front_time / total_time
percent = int(fraction * 100)
embed.add_field(name=member.name if member else "(no fronter)",
value="{}% ({})".format(percent, humanize.naturaldelta(front_time)))
embed.set_footer(text="Since {}".format(span_start.isoformat(sep=" ", timespec="seconds")))
return embed

View File

@ -137,7 +137,16 @@ For example:
`pk;system fronter` - Shows the current fronter(s) in your own system. `pk;system fronter` - Shows the current fronter(s) in your own system.
`pk;system fronter abcde` - Shows the current fronter in the system with the ID `abcde`. `pk;system fronter abcde` - Shows the current fronter in the system with the ID `abcde`.
`pk;system fronthistory` - Shows the past 10 switches in your own system. `pk;system fronthistory` - Shows the past 10 switches in your own system.
`pk;system fronthistory @JohnsAccount` - Shows the past 10 switches in the system linked to @JohnsAccount.""") `pk;system fronthistory @JohnsAccount` - Shows the past 10 switches in the system linked to @JohnsAccount."""),
("Viewing a front breakdown",
"""To see a per-member breakdown of your switches, use the `pk;system frontpercent` command. You can optionally give it a time limit to only count switches after that point.
For example:
`pk;system frontpercent` - Shows a front breakdown for your system since you started logging switches
`pk;system frontpercent 1 day` - Shows a front breakdown for your system for the past day
`pk;system frontpercent Jan 1st 2018` - Shows a front breakdown for your system since January 1st, 2018
Note that the percentages don't necessarily add up to 100%, as multiple members can be listed as fronting at a time.""")
], ],
"mod": [ "mod": [
(None, "Note that all moderation commands require you to have administrator privileges on the server they're used on."), (None, "Note that all moderation commands require you to have administrator privileges on the server they're used on."),