Added front percent breakdown command
This commit is contained in:
parent
944f0093a9
commit
3d2d6b0ea6
@ -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
|
||||||
|
@ -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."),
|
||||||
|
Loading…
Reference in New Issue
Block a user