bitbot-3.11-fork/modules/badges.py
2020-02-26 21:02:10 +00:00

104 lines
4.1 KiB
Python

#--depends-on commands
import datetime, re
from src import ModuleManager, utils
RE_HUMAN_FORMAT = re.compile(r"(\d\d\d\d)-(\d?\d)-(\d?\d)")
HUMAN_FORMAT_HELP = "year-month-day (e.g. 2018-12-29)"
class Module(ModuleManager.BaseModule):
@utils.export("command-spec.marginstring")
def _marginstring_spec(self, server, channel, user, args):
if len(args) > 1:
new_args = args[:-1]
return " ".join(new_args), len(new_args)
else:
return None, 1
def _round_up_day(self, dt: datetime.datetime):
return dt.date()+datetime.timedelta(days=1)
def _days_since(self, now: datetime.date, dt: datetime.datetime):
return (now-dt.date()).days
def _get_badges(self, user):
return user.get_setting("badges", {})
def _set_badges(self, user, badges):
user.set_setting("badges", badges)
def _del_badges(self, user):
user.del_setting("badges")
@utils.hook("received.command.badge")
@utils.kwarg("help", "List, add and remove badges")
@utils.spec("!'list ?<nickname>ouser")
@utils.spec("!'show !<name>string")
@utils.spec("!'add !<name>marginstring !'now,today")
@utils.spec("!'add !<name>marginstring !date")
@utils.spec("!'remove !<name>string")
def badge(self, event):
now = self._round_up_day(utils.datetime.utcnow())
if event["spec"][0] == "list":
target = event["spec"][1] or event["user"]
badges = self._get_badges(target)
if not badges:
raise utils.EventError("%s has no badges" % target.nickname)
outs = []
for name in sorted(badges.keys()):
dt = utils.datetime.parse.iso8601(badges[name])
days_since = self._days_since(now, dt)
human = utils.datetime.format.date_human(dt)
outs.append("%s on day %d (%s)"
% (name, days_since, human))
event["stdout"].write("badges for %s: %s"
% (target.nickname, ", ".join(outs)))
else:
badges = self._get_badges(event["user"])
mut_badges = badges.copy()
name = event["spec"][1]
if event["spec"][0] == "add":
if event["spec"][2] in ["now", "today"]:
dt = utils.datetime.utcnow()
else:
dt = event["spec"][2]
exists = name in badges
action = "updated" if exists else "added"
mut_badges[name] = utils.datetime.format.iso8601(dt)
human = utils.datetime.format.date_human(dt)
event["stdout"].write("%s: %s badge %s (%s)"
% (event["user"].nickname, action, name, human))
else:
if not name in badges:
raise utils.EventError("%s: you don't have a '%s' badge"
% (event["user"].nickname, name))
dt = utils.datetime.parse.iso8601(badges[name])
human = utils.datetime.format.date_human(dt)
if event["spec"][0] == "remove":
del mut_badges[name]
event["stdout"].write("%s: removed badge '%s' (%s)"
% (event["user"].nickname, name, human))
elif event["spec"][0] == "show":
days_since = self._days_since(now, dt)
event["stdout"].write("%s: your %s badge is on day %d (%s)"
% (event["user"].nickname, name, days_since, human))
if not mut_badges == badges:
self._set_badges(event["user"], mut_badges)
@utils.hook("received.command.badgeclear")
@utils.kwarg("help", "Clear a user's badges")
@utils.kwarg("permission", "badge-clear")
@utils.spec("!<nickname>ouser")
def badgeclear(self, event):
if self._get_badges(event["spec"][0]):
self._del_badges(event["spec"][0])
event["stdout"].write("Cleared badges for %s"
% event["spec"][0].nickname)
else:
event["stderr"].write("%s has no badges"
% event["spec"][0].nickname)