Convert some things to new command API+users

MessageDispatcher, sleepy mode, warnings, and the latency command,
to be exact. Sleepy also benefits from some code deduplication in
addition to now operating on users.

The warnings code could use a more comprehensive overhaul too, but
that's going to be harder to achieve.
This commit is contained in:
skizzerz 2018-01-09 16:01:43 -07:00
parent 6d401fd461
commit f4876d254e
4 changed files with 145 additions and 243 deletions

View File

@ -1,7 +1,7 @@
from src import channels, users from src import channels, users
from src import settings as var from src import settings as var
from src.utilities import list_players from src.functions import get_players
class MessageDispatcher: class MessageDispatcher:
"""Dispatcher class for raw IRC messages.""" """Dispatcher class for raw IRC messages."""
@ -39,8 +39,10 @@ class MessageDispatcher:
if self.private: if self.private:
self.source.send(*messages, **kwargs) self.source.send(*messages, **kwargs)
elif (self.target is channels.Main and elif (self.target is channels.Main and
((self.source.nick not in list_players() and var.PHASE in var.GAME_PHASES) or ((self.source not in get_players() and var.PHASE in var.GAME_PHASES) or
(var.DEVOICE_DURING_NIGHT and var.PHASE == "night"))): # FIXME (var.DEVOICE_DURING_NIGHT and var.PHASE == "night"))):
# TODO: ideally the above check would be handled in game logic somehow
# (perhaps via an event) rather than adding game logic to the transport layer
kwargs.setdefault("notice", True) kwargs.setdefault("notice", True)
self.source.send(*messages, **kwargs) self.source.send(*messages, **kwargs)
else: else:

View File

@ -2,6 +2,7 @@ import random
import math import math
import threading import threading
import copy import copy
import functools
from datetime import datetime from datetime import datetime
from collections import defaultdict, OrderedDict from collections import defaultdict, OrderedDict
@ -10,7 +11,7 @@ import src.settings as var
from src.utilities import * from src.utilities import *
from src.messages import messages from src.messages import messages
from src.functions import get_players, get_all_players, get_main_role from src.functions import get_players, get_all_players, get_main_role
from src.decorators import handle_error from src.decorators import handle_error, command
from src import events, channels, users from src import events, channels, users
def game_mode(name, minp, maxp, likelihood = 0): def game_mode(name, minp, maxp, likelihood = 0):
@ -877,17 +878,16 @@ class SleepyMode(GameMode):
self.having_nightmare = None self.having_nightmare = None
def startup(self): def startup(self):
from src import decorators
events.add_listener("dullahan_targets", self.dullahan_targets) events.add_listener("dullahan_targets", self.dullahan_targets)
events.add_listener("transition_night_begin", self.setup_nightmares) events.add_listener("transition_night_begin", self.setup_nightmares)
events.add_listener("chk_nightdone", self.prolong_night) events.add_listener("chk_nightdone", self.prolong_night)
events.add_listener("transition_day_begin", self.nightmare_kill) events.add_listener("transition_day_begin", self.nightmare_kill)
events.add_listener("del_player", self.happy_fun_times) events.add_listener("del_player", self.happy_fun_times)
events.add_listener("rename_player", self.rename_player) events.add_listener("rename_player", self.rename_player)
self.north_cmd = decorators.cmd("north", "n", chan=False, pm=True, playing=True, phases=("night",))(self.north) self.north_cmd = command("north", "n", chan=False, pm=True, playing=True, phases=("night",))(functools.partial(self.move, "n"))
self.east_cmd = decorators.cmd("east", "e", chan=False, pm=True, playing=True, phases=("night",))(self.east) self.east_cmd = command("east", "e", chan=False, pm=True, playing=True, phases=("night",))(functools.partial(self.move, "e"))
self.south_cmd = decorators.cmd("south", "s", chan=False, pm=True, playing=True, phases=("night",))(self.south) self.south_cmd = command("south", "s", chan=False, pm=True, playing=True, phases=("night",))(functools.partial(self.move, "s"))
self.west_cmd = decorators.cmd("west", "w", chan=False, pm=True, playing=True, phases=("night",))(self.west) self.west_cmd = command("west", "w", chan=False, pm=True, playing=True, phases=("night",))(functools.partial(self.move, "w"))
def teardown(self): def teardown(self):
from src import decorators from src import decorators
@ -919,7 +919,7 @@ class SleepyMode(GameMode):
if random.random() < 1/5: if random.random() < 1/5:
self.having_nightmare = True self.having_nightmare = True
with var.WARNING_LOCK: with var.WARNING_LOCK:
t = threading.Timer(60, self.do_nightmare, (cli, var, random.choice(list_players()), var.NIGHT_COUNT)) t = threading.Timer(60, self.do_nightmare, (var, random.choice(get_players()), var.NIGHT_COUNT))
t.daemon = True t.daemon = True
t.start() t.start()
else: else:
@ -930,14 +930,14 @@ class SleepyMode(GameMode):
self.having_nightmare = nick self.having_nightmare = nick
@handle_error @handle_error
def do_nightmare(self, cli, var, target, night): def do_nightmare(self, var, target, night):
if var.PHASE != "night" or var.NIGHT_COUNT != night: if var.PHASE != "night" or var.NIGHT_COUNT != night:
return return
if target not in list_players(): if target not in get_players():
return return
self.having_nightmare = target self.having_nightmare = target
pm(cli, self.having_nightmare, messages["sleepy_nightmare_begin"]) target.send(messages["sleepy_nightmare_begin"])
pm(cli, self.having_nightmare, messages["sleepy_nightmare_navigate"]) target.send(messages["sleepy_nightmare_navigate"])
self.correct = [None, None, None] self.correct = [None, None, None]
self.fake1 = [None, None, None] self.fake1 = [None, None, None]
self.fake2 = [None, None, None] self.fake2 = [None, None, None]
@ -963,9 +963,9 @@ class SleepyMode(GameMode):
self.prev_direction = "n" self.prev_direction = "n"
self.start_direction = "n" self.start_direction = "n"
self.on_path = set() self.on_path = set()
self.nightmare_step(cli) self.nightmare_step()
def nightmare_step(self, cli): def nightmare_step(self):
if self.prev_direction == "n": if self.prev_direction == "n":
directions = "north, east, and west" directions = "north, east, and west"
elif self.prev_direction == "e": elif self.prev_direction == "e":
@ -976,155 +976,60 @@ class SleepyMode(GameMode):
directions = "north, south, and west" directions = "north, south, and west"
if self.step == 0: if self.step == 0:
pm(cli, self.having_nightmare, messages["sleepy_nightmare_0"].format(directions)) self.having_nightmare.send(messages["sleepy_nightmare_0"].format(directions))
elif self.step == 1: elif self.step == 1:
pm(cli, self.having_nightmare, messages["sleepy_nightmare_1"].format(directions)) self.having_nightmare.send(messages["sleepy_nightmare_1"].format(directions))
elif self.step == 2: elif self.step == 2:
pm(cli, self.having_nightmare, messages["sleepy_nightmare_2"].format(directions)) self.having_nightmare.send(messages["sleepy_nightmare_2"].format(directions))
elif self.step == 3: elif self.step == 3:
if "correct" in self.on_path: if "correct" in self.on_path:
pm(cli, self.having_nightmare, messages["sleepy_nightmare_wake"]) self.having_nightmare.send(messages["sleepy_nightmare_wake"])
self.having_nightmare = None self.having_nightmare = None
elif "fake1" in self.on_path: elif "fake1" in self.on_path:
pm(cli, self.having_nightmare, messages["sleepy_nightmare_fake_1"]) self.having_nightmare.send(messages["sleepy_nightmare_fake_1"])
self.step = 0 self.step = 0
self.on_path = set() self.on_path = set()
self.prev_direction = self.start_direction self.prev_direction = self.start_direction
self.nightmare_step(cli) self.nightmare_step()
elif "fake2" in self.on_path: elif "fake2" in self.on_path:
pm(cli, self.having_nightmare, messages["sleepy_nightmare_fake_2"]) self.having_nightmare.send(messages["sleepy_nightmare_fake_2"])
self.step = 0 self.step = 0
self.on_path = set() self.on_path = set()
self.prev_direction = self.start_direction self.prev_direction = self.start_direction
self.nightmare_step(cli) self.nightmare_step()
def north(self, cli, nick, chan, rest): def move(self, direction, var, wrapper, message):
if nick != self.having_nightmare: if self.having_nightmare is not wrapper.source:
return return
if self.prev_direction == "s": opposite = {"n": "s", "e": "w", "s": "n", "w": "e"}
pm(cli, nick, messages["sleepy_nightmare_invalid_direction"]) if self.prev_direction == opposite[direction]:
wrapper.pm(messages["sleepy_nightmare_invalid_direction"])
return return
advance = False advance = False
if ("correct" in self.on_path or self.step == 0) and self.correct[self.step] == "n": if ("correct" in self.on_path or self.step == 0) and self.correct[self.step] == direction:
self.on_path.add("correct") self.on_path.add("correct")
advance = True advance = True
else: else:
self.on_path.discard("correct") self.on_path.discard("correct")
if ("fake1" in self.on_path or self.step == 0) and self.fake1[self.step] == "n": if ("fake1" in self.on_path or self.step == 0) and self.fake1[self.step] == direction:
self.on_path.add("fake1") self.on_path.add("fake1")
advance = True advance = True
else: else:
self.on_path.discard("fake1") self.on_path.discard("fake1")
if ("fake2" in self.on_path or self.step == 0) and self.fake2[self.step] == "n": if ("fake2" in self.on_path or self.step == 0) and self.fake2[self.step] == direction:
self.on_path.add("fake2") self.on_path.add("fake2")
advance = True advance = True
else: else:
self.on_path.discard("fake2") self.on_path.discard("fake2")
if advance: if advance:
self.step += 1 self.step += 1
self.prev_direction = "n" self.prev_direction = direction
else: else:
self.step = 0 self.step = 0
self.on_path = set() self.on_path = set()
self.prev_direction = self.start_direction self.prev_direction = self.start_direction
pm(cli, self.having_nightmare, messages["sleepy_nightmare_restart"]) wrapper.pm(messages["sleepy_nightmare_restart"])
self.nightmare_step(cli) self.nightmare_step()
def east(self, cli, nick, chan, rest):
if nick != self.having_nightmare:
return
if self.prev_direction == "w":
pm(cli, nick, messages["sleepy_nightmare_invalid_direction"])
return
advance = False
if ("correct" in self.on_path or self.step == 0) and self.correct[self.step] == "e":
self.on_path.add("correct")
advance = True
else:
self.on_path.discard("correct")
if ("fake1" in self.on_path or self.step == 0) and self.fake1[self.step] == "e":
self.on_path.add("fake1")
advance = True
else:
self.on_path.discard("fake1")
if ("fake2" in self.on_path or self.step == 0) and self.fake2[self.step] == "e":
self.on_path.add("fake2")
advance = True
else:
self.on_path.discard("fake2")
if advance:
self.step += 1
self.prev_direction = "e"
else:
self.step = 0
self.on_path = set()
self.prev_direction = self.start_direction
pm(cli, self.having_nightmare, messages["sleepy_nightmare_restart"])
self.nightmare_step(cli)
def south(self, cli, nick, chan, rest):
if nick != self.having_nightmare:
return
if self.prev_direction == "n":
pm(cli, nick, messages["sleepy_nightmare_invalid_direction"])
return
advance = False
if ("correct" in self.on_path or self.step == 0) and self.correct[self.step] == "s":
self.on_path.add("correct")
advance = True
else:
self.on_path.discard("correct")
if ("fake1" in self.on_path or self.step == 0) and self.fake1[self.step] == "s":
self.on_path.add("fake1")
advance = True
else:
self.on_path.discard("fake1")
if ("fake2" in self.on_path or self.step == 0) and self.fake2[self.step] == "s":
self.on_path.add("fake2")
advance = True
else:
self.on_path.discard("fake2")
if advance:
self.step += 1
self.prev_direction = "s"
else:
self.step = 0
self.on_path = set()
self.prev_direction = self.start_direction
pm(cli, self.having_nightmare, messages["sleepy_nightmare_restart"])
self.nightmare_step(cli)
def west(self, cli, nick, chan, rest):
if nick != self.having_nightmare:
return
if self.prev_direction == "e":
pm(cli, nick, messages["sleepy_nightmare_invalid_direction"])
return
advance = False
if ("correct" in self.on_path or self.step == 0) and self.correct[self.step] == "w":
self.on_path.add("correct")
advance = True
else:
self.on_path.discard("correct")
if ("fake1" in self.on_path or self.step == 0) and self.fake1[self.step] == "w":
self.on_path.add("fake1")
advance = True
else:
self.on_path.discard("fake1")
if ("fake2" in self.on_path or self.step == 0) and self.fake2[self.step] == "w":
self.on_path.add("fake2")
advance = True
else:
self.on_path.discard("fake2")
if advance:
self.step += 1
self.prev_direction = "w"
else:
self.step = 0
self.on_path = set()
self.prev_direction = self.start_direction
pm(cli, self.having_nightmare, messages["sleepy_nightmare_restart"])
self.nightmare_step(cli)
def prolong_night(self, evt, var): def prolong_night(self, evt, var):
if self.having_nightmare is not None: if self.having_nightmare is not None:
@ -1132,11 +1037,9 @@ class SleepyMode(GameMode):
def nightmare_kill(self, evt, var): def nightmare_kill(self, evt, var):
# if True, it means night ended before 1 minute # if True, it means night ended before 1 minute
if self.having_nightmare is not None and self.having_nightmare is not True: if self.having_nightmare is not None and self.having_nightmare in get_players():
user = users._get(self.having_nightmare) # FIXME var.DYING.add(self.having_nightmare)
if user in get_players(): self.having_nightmare.send(messages["sleepy_nightmare_death"])
var.DYING.add(user)
user.send(messages["sleepy_nightmare_death"])
def happy_fun_times(self, evt, var, user, mainrole, allroles, death_triggers): def happy_fun_times(self, evt, var, user, mainrole, allroles, death_triggers):
if death_triggers: if death_triggers:

View File

@ -15,10 +15,7 @@ from src.messages import messages
from src.utilities import reply from src.utilities import reply
from src.functions import get_participants, get_all_roles from src.functions import get_participants, get_all_roles
from src.dispatcher import MessageDispatcher from src.dispatcher import MessageDispatcher
from src.decorators import handle_error from src.decorators import handle_error, command, hook
cmd = decorators.cmd
hook = decorators.hook
@handle_error @handle_error
def on_privmsg(cli, rawnick, chan, msg, *, notice=False, force_role=None): def on_privmsg(cli, rawnick, chan, msg, *, notice=False, force_role=None):
@ -132,14 +129,14 @@ def unhandled(cli, prefix, cmd, *args):
def ping_server(cli): def ping_server(cli):
cli.send("PING :{0}".format(time.time())) cli.send("PING :{0}".format(time.time()))
@cmd("latency", pm=True) @command("latency", pm=True)
def latency(cli, nick, chan, rest): def latency(var, wrapper, message):
ping_server(cli) ping_server(wrapper.client)
@hook("pong", hookid=300) @hook("pong", hookid=300)
def latency_pong(cli, server, target, ts): def latency_pong(cli, server, target, ts):
lat = round(time.time() - float(ts), 3) lat = round(time.time() - float(ts), 3)
reply(cli, nick, chan, messages["latency"].format(lat, "" if lat == 1 else "s")) wrapper.reply(messages["latency"].format(lat, "" if lat == 1 else "s"))
hook.unhook(300) hook.unhook(300)
def connect_callback(cli): def connect_callback(cli):

View File

@ -5,7 +5,7 @@ import botconfig
import src.settings as var import src.settings as var
from src import channels, db, users from src import channels, db, users
from src.utilities import * from src.utilities import *
from src.decorators import cmd, COMMANDS from src.decorators import command, COMMANDS
from src.events import Event from src.events import Event
from src.messages import messages from src.messages import messages
@ -212,21 +212,21 @@ def add_warning(cli, target, amount, actor, reason, notes=None, expires=None, sa
return sid return sid
@cmd("stasis", chan=True, pm=True) @command("stasis", chan=True, pm=True)
def stasis(cli, nick, chan, rest): def stasis(var, wrapper, message):
st = is_user_stasised(nick) st = is_user_stasised(wrapper.source.nick) # FIXME
if st: if st:
msg = messages["your_current_stasis"].format(st, "" if st == 1 else "s") msg = messages["your_current_stasis"].format(st, "" if st == 1 else "s")
else: else:
msg = messages["you_not_in_stasis"] msg = messages["you_not_in_stasis"]
reply(cli, nick, chan, msg, prefix_nick=True) wrapper.reply(msg, prefix_nick=True)
@cmd("fstasis", flag="A", chan=True, pm=True) @command("fstasis", flag="A", chan=True, pm=True)
def fstasis(cli, nick, chan, rest): def fstasis(var, wrapper, message):
"""Removes or views stasis penalties.""" """Removes or views stasis penalties."""
data = rest.split() data = message.split()
msg = None msg = None
if data: if data:
@ -237,33 +237,33 @@ def fstasis(cli, nick, chan, rest):
if len(data) == 1: if len(data) == 1:
if acc is not None and var.STASISED_ACCS[acc] == cur: if acc is not None and var.STASISED_ACCS[acc] == cur:
plural = "" if cur == 1 else "s" plural = "" if cur == 1 else "s"
reply(cli, nick, chan, messages["account_in_stasis"].format(data[0], acc, cur, plural)) wrapper.reply(messages["account_in_stasis"].format(data[0], acc, cur, plural))
elif hostmask is not None and var.STASISED[hostmask] == cur: elif hostmask is not None and var.STASISED[hostmask] == cur:
plural = "" if cur == 1 else "s" plural = "" if cur == 1 else "s"
reply(cli, nick, chan, messages["hostmask_in_stasis"].format(data[0], hostmask, cur, plural)) wrapper.reply(messages["hostmask_in_stasis"].format(data[0], hostmask, cur, plural))
elif acc is not None: elif acc is not None:
reply(cli, nick, chan, messages["account_not_in_stasis"].format(data[0], acc)) wrapper.reply(messages["account_not_in_stasis"].format(data[0], acc))
else: else:
reply(cli, nick, chan, messages["hostmask_not_in_stasis"].format(data[0], hostmask)) wrapper.reply(messages["hostmask_not_in_stasis"].format(data[0], hostmask))
else: else:
try: try:
amt = int(data[1]) amt = int(data[1])
except ValueError: except ValueError:
reply(cli, nick, chan, messages["stasis_not_negative"]) wrapper.reply(messages["stasis_not_negative"])
return return
if amt < 0: if amt < 0:
reply(cli, nick, chan, messages["stasis_not_negative"]) wrapper.reply(messages["stasis_not_negative"])
return return
elif amt > cur and var.RESTRICT_FSTASIS: elif amt > cur and var.RESTRICT_FSTASIS:
reply(cli, nick, chan, messages["stasis_cannot_increase"]) wrapper.reply(messages["stasis_cannot_increase"])
return return
elif cur == 0: elif cur == 0:
if acc is not None: if acc is not None:
reply(cli, nick, chan, messages["account_not_in_stasis"].format(data[0], acc)) wrapper.reply(messages["account_not_in_stasis"].format(data[0], acc))
return return
else: else:
reply(cli, nick, chan, messages["hostmask_not_in_stasis"].format(data[0], hostmask)) wrapper.reply(messages["hostmask_not_in_stasis"].format(data[0], hostmask))
return return
db.set_stasis(amt, acc, hostmask) db.set_stasis(amt, acc, hostmask)
@ -271,13 +271,13 @@ def fstasis(cli, nick, chan, rest):
if amt > 0: if amt > 0:
plural = "" if amt == 1 else "s" plural = "" if amt == 1 else "s"
if acc is not None: if acc is not None:
reply(cli, nick, chan, messages["fstasis_account_add"].format(data[0], acc, amt, plural)) wrapper.reply(messages["fstasis_account_add"].format(data[0], acc, amt, plural))
else: else:
reply(cli, nick, chan, messages["fstasis_hostmask_add"].format(data[0], hostmask, amt, plural)) wrapper.reply(messages["fstasis_hostmask_add"].format(data[0], hostmask, amt, plural))
elif acc is not None: elif acc is not None:
reply(cli, nick, chan, messages["fstasis_account_remove"].format(data[0], acc)) wrapper.reply(messages["fstasis_account_remove"].format(data[0], acc))
else: else:
reply(cli, nick, chan, messages["fstasis_hostmask_remove"].format(data[0], hostmask)) wrapper.reply(messages["fstasis_hostmask_remove"].format(data[0], hostmask))
elif var.STASISED or var.STASISED_ACCS: elif var.STASISED or var.STASISED_ACCS:
stasised = {} stasised = {}
for hostmask in var.STASISED: for hostmask in var.STASISED:
@ -291,18 +291,18 @@ def fstasis(cli, nick, chan, rest):
msg = messages["currently_stasised"].format(", ".join( msg = messages["currently_stasised"].format(", ".join(
"\u0002{0}\u0002 ({1})".format(usr, number) "\u0002{0}\u0002 ({1})".format(usr, number)
for usr, number in stasised.items())) for usr, number in stasised.items()))
reply(cli, nick, chan, msg) wrapper.reply(msg)
else: else:
reply(cli, nick, chan, messages["noone_stasised"]) wrapper.reply(messages["noone_stasised"])
@cmd("warn", pm=True) @command("warn", pm=True)
def warn(cli, nick, chan, rest): def warn(var, wrapper, message):
"""View and acknowledge your warnings.""" """View and acknowledge your warnings."""
# !warn list [-all] [page] - lists all active warnings, or all warnings if all passed # !warn list [-all] [page] - lists all active warnings, or all warnings if all passed
# !warn view <id> - views details on warning id # !warn view <id> - views details on warning id
# !warn ack <id> - acknowledges warning id # !warn ack <id> - acknowledges warning id
# Default if only !warn is given is to do !warn list. # Default if only !warn is given is to do !warn list.
params = re.split(" +", rest) params = re.split(" +", message)
try: try:
command = params.pop(0) command = params.pop(0)
@ -312,19 +312,19 @@ def warn(cli, nick, chan, rest):
command = "list" command = "list"
if command not in ("list", "view", "ack", "help"): if command not in ("list", "view", "ack", "help"):
reply(cli, nick, chan, messages["warn_usage"]) wrapper.reply(messages["warn_usage"])
return return
if command == "help": if command == "help":
try: try:
subcommand = params.pop(0) subcommand = params.pop(0)
except IndexError: except IndexError:
reply(cli, nick, chan, messages["warn_help_syntax"]) wrapper.reply(messages["warn_help_syntax"])
return return
if subcommand not in ("list", "view", "ack", "help"): if subcommand not in ("list", "view", "ack", "help"):
reply(cli, nick, chan, messages["warn_usage"]) wrapper.reply(messages["warn_usage"])
return return
reply(cli, nick, chan, messages["warn_{0}_syntax".format(subcommand)]) wrapper.reply(messages["warn_{0}_syntax".format(subcommand)])
return return
if command == "list": if command == "list":
@ -337,7 +337,7 @@ def warn(cli, nick, chan, rest):
except IndexError: except IndexError:
pass pass
except ValueError: except ValueError:
reply(cli, nick, chan, messages["fwarn_page_invalid"]) wrapper.reply(messages["fwarn_page_invalid"])
return return
try: try:
@ -347,13 +347,13 @@ def warn(cli, nick, chan, rest):
elif list_all == "-all": elif list_all == "-all":
list_all = True list_all = True
except ValueError: except ValueError:
reply(cli, nick, chan, messages["fwarn_page_invalid"]) wrapper.reply(messages["fwarn_page_invalid"])
return return
acc, hm = parse_warning_target(nick) acc, hm = parse_warning_target(wrapper.source.nick)
warnings = db.list_warnings(acc, hm, expired=list_all, skip=(page-1)*10, show=11) warnings = db.list_warnings(acc, hm, expired=list_all, skip=(page-1)*10, show=11)
points = db.get_warning_points(acc, hm) points = db.get_warning_points(acc, hm)
reply(cli, nick, chan, messages["warn_list_header"].format(points, "" if points == 1 else "s"), private=True) wrapper.pm(messages["warn_list_header"].format(points, "" if points == 1 else "s"))
i = 0 i = 0
for warn in warnings: for warn in warnings:
@ -363,7 +363,7 @@ def warn(cli, nick, chan, rest):
if list_all: if list_all:
parts.append("-all") parts.append("-all")
parts.append(str(page + 1)) parts.append(str(page + 1))
reply(cli, nick, chan, messages["warn_list_footer"].format(" ".join(parts)), private=True) wrapper.pm(messages["warn_list_footer"].format(" ".join(parts)))
break break
start = "" start = ""
end = "" end = ""
@ -380,11 +380,11 @@ def warn(cli, nick, chan, rest):
end = " [\u00037{0}\u000314]\u0003".format(messages["fwarn_expired"]) end = " [\u00037{0}\u000314]\u0003".format(messages["fwarn_expired"])
if not warn["ack"]: if not warn["ack"]:
ack = "\u0002!\u0002 " ack = "\u0002!\u0002 "
reply(cli, nick, chan, messages["warn_list"].format( wrapper.pm(messages["warn_list"].format(
start, ack, warn["id"], warn["issued"], warn["reason"], warn["amount"], start, ack, warn["id"], warn["issued"], warn["reason"], warn["amount"],
"" if warn["amount"] == 1 else "s", expires, end), private=True) "" if warn["amount"] == 1 else "s", expires, end))
if i == 0: if i == 0:
reply(cli, nick, chan, messages["fwarn_list_empty"], private=True) wrapper.pm(messages["fwarn_list_empty"])
return return
if command == "view": if command == "view":
@ -394,13 +394,13 @@ def warn(cli, nick, chan, rest):
warn_id = warn_id[1:] warn_id = warn_id[1:]
warn_id = int(warn_id) warn_id = int(warn_id)
except (IndexError, ValueError): except (IndexError, ValueError):
reply(cli, nick, chan, messages["warn_view_syntax"]) wrapper.reply(messages["warn_view_syntax"])
return return
acc, hm = parse_warning_target(nick) acc, hm = parse_warning_target(wrapper.source.nick)
warning = db.get_warning(warn_id, acc, hm) warning = db.get_warning(warn_id, acc, hm)
if warning is None: if warning is None:
reply(cli, nick, chan, messages["fwarn_invalid_warning"]) wrapper.reply(messages["fwarn_invalid_warning"])
return return
if warning["expired"]: if warning["expired"]:
@ -410,10 +410,10 @@ def warn(cli, nick, chan, rest):
else: else:
expires = messages["fwarn_view_active"].format(messages["fwarn_view_expires"].format(warning["expires"])) expires = messages["fwarn_view_active"].format(messages["fwarn_view_expires"].format(warning["expires"]))
reply(cli, nick, chan, messages["warn_view_header"].format( wrapper.pm(messages["warn_view_header"].format(
warning["id"], warning["issued"], warning["amount"], warning["id"], warning["issued"], warning["amount"],
"" if warning["amount"] == 1 else "s", expires), private=True) "" if warning["amount"] == 1 else "s", expires))
reply(cli, nick, chan, warning["reason"], private=True) wrapper.pm(warning["reason"])
sanctions = [] sanctions = []
if not warning["ack"]: if not warning["ack"]:
@ -428,7 +428,7 @@ def warn(cli, nick, chan, rest):
if "deny" in warning["sanctions"]: if "deny" in warning["sanctions"]:
sanctions.append(messages["fwarn_view_deny"].format(", ".join(warning["sanctions"]["deny"]))) sanctions.append(messages["fwarn_view_deny"].format(", ".join(warning["sanctions"]["deny"])))
if sanctions: if sanctions:
reply(cli, nick, chan, " ".join(sanctions), private=True) wrapper.pm(" ".join(sanctions))
return return
if command == "ack": if command == "ack":
@ -438,13 +438,13 @@ def warn(cli, nick, chan, rest):
warn_id = warn_id[1:] warn_id = warn_id[1:]
warn_id = int(warn_id) warn_id = int(warn_id)
except (IndexError, ValueError): except (IndexError, ValueError):
reply(cli, nick, chan, messages["warn_ack_syntax"]) wrapper.reply(messages["warn_ack_syntax"])
return return
acc, hm = parse_warning_target(nick) acc, hm = parse_warning_target(wrapper.source.nick)
warning = db.get_warning(warn_id, acc, hm) warning = db.get_warning(warn_id, acc, hm)
if warning is None: if warning is None:
reply(cli, nick, chan, messages["fwarn_invalid_warning"]) wrapper.reply(messages["fwarn_invalid_warning"])
return return
# only add stasis if this is the first time this warning is being acknowledged # only add stasis if this is the first time this warning is being acknowledged
@ -452,11 +452,11 @@ def warn(cli, nick, chan, rest):
db.set_stasis(warning["sanctions"]["stasis"], acc, hm, relative=True) db.set_stasis(warning["sanctions"]["stasis"], acc, hm, relative=True)
db.init_vars() db.init_vars()
db.acknowledge_warning(warn_id) db.acknowledge_warning(warn_id)
reply(cli, nick, chan, messages["fwarn_done"]) wrapper.reply(messages["fwarn_done"])
return return
@cmd("fwarn", flag="F", pm=True) @command("fwarn", flag="F", pm=True)
def fwarn(cli, nick, chan, rest): def fwarn(var, wrapper, message):
"""Issues a warning to someone or views warnings.""" """Issues a warning to someone or views warnings."""
# !fwarn list [-all] [nick] [page] # !fwarn list [-all] [nick] [page]
# -all => Shows all warnings, if omitted only shows active (non-expired and non-deleted) ones. # -all => Shows all warnings, if omitted only shows active (non-expired and non-deleted) ones.
@ -480,7 +480,7 @@ def fwarn(cli, nick, chan, rest):
# If specified, must be prefixed with |. This means | is not a valid character for use # If specified, must be prefixed with |. This means | is not a valid character for use
# in reasons (no escaping is performed). # in reasons (no escaping is performed).
params = rest.split() params = message.split()
target = None target = None
points = None points = None
expires = None expires = None
@ -491,7 +491,7 @@ def fwarn(cli, nick, chan, rest):
try: try:
command = params.pop(0) command = params.pop(0)
except IndexError: except IndexError:
reply(cli, nick, chan, messages["fwarn_usage"]) wrapper.reply(messages["fwarn_usage"])
return return
if command not in ("list", "view", "add", "del", "set", "help"): if command not in ("list", "view", "add", "del", "set", "help"):
@ -520,12 +520,12 @@ def fwarn(cli, nick, chan, rest):
try: try:
subcommand = params.pop(0) subcommand = params.pop(0)
except IndexError: except IndexError:
reply(cli, nick, chan, messages["fwarn_usage"]) wrapper.reply(messages["fwarn_usage"])
return return
if subcommand not in ("list", "view", "add", "del", "set", "help"): if subcommand not in ("list", "view", "add", "del", "set", "help"):
reply(cli, nick, chan, messages["fwarn_usage"]) wrapper.reply(messages["fwarn_usage"])
return return
reply(cli, nick, chan, messages["fwarn_{0}_syntax".format(subcommand)]) wrapper.reply(messages["fwarn_{0}_syntax".format(subcommand)])
return return
if command == "list": if command == "list":
@ -538,7 +538,7 @@ def fwarn(cli, nick, chan, rest):
except IndexError: except IndexError:
pass pass
except ValueError: except ValueError:
reply(cli, nick, chan, messages["fwarn_page_invalid"]) wrapper.reply(messages["fwarn_page_invalid"])
return return
try: try:
@ -550,7 +550,7 @@ def fwarn(cli, nick, chan, rest):
elif list_all == "-all": elif list_all == "-all":
list_all = True list_all = True
except ValueError: except ValueError:
reply(cli, nick, chan, messages["fwarn_page_invalid"]) wrapper.reply(messages["fwarn_page_invalid"])
return return
try: try:
@ -562,11 +562,11 @@ def fwarn(cli, nick, chan, rest):
if target is not None: if target is not None:
acc, hm = parse_warning_target(target) acc, hm = parse_warning_target(target)
if acc is None and hm is None: if acc is None and hm is None:
reply(cli, nick, chan, messages["fwarn_nick_invalid"]) wrapper.reply(messages["fwarn_nick_invalid"])
return return
warnings = db.list_warnings(acc, hm, expired=list_all, deleted=list_all, skip=(page-1)*10, show=11) warnings = db.list_warnings(acc, hm, expired=list_all, deleted=list_all, skip=(page-1)*10, show=11)
points = db.get_warning_points(acc, hm) points = db.get_warning_points(acc, hm)
reply(cli, nick, chan, messages["fwarn_list_header"].format(target, points, "" if points == 1 else "s"), private=True) wrapper.pm(messages["fwarn_list_header"].format(target, points, "" if points == 1 else "s"))
else: else:
warnings = db.list_all_warnings(list_all=list_all, skip=(page-1)*10, show=11) warnings = db.list_all_warnings(list_all=list_all, skip=(page-1)*10, show=11)
@ -580,7 +580,7 @@ def fwarn(cli, nick, chan, rest):
if target is not None: if target is not None:
parts.append(target) parts.append(target)
parts.append(str(page + 1)) parts.append(str(page + 1))
reply(cli, nick, chan, messages["fwarn_list_footer"].format(" ".join(parts)), private=True) wrapper.pm(messages["fwarn_list_footer"].format(" ".join(parts)))
break break
start = "" start = ""
end = "" end = ""
@ -600,12 +600,12 @@ def fwarn(cli, nick, chan, rest):
end = " [\u00037{0}\u000314]\u0003".format(messages["fwarn_expired"]) end = " [\u00037{0}\u000314]\u0003".format(messages["fwarn_expired"])
if not warn["ack"]: if not warn["ack"]:
ack = "\u0002!\u0002 " ack = "\u0002!\u0002 "
reply(cli, nick, chan, messages["fwarn_list"].format( wrapper.pm(messages["fwarn_list"].format(
start, ack, warn["id"], warn["issued"], warn["target"], start, ack, warn["id"], warn["issued"], warn["target"],
warn["sender"], warn["reason"], warn["amount"], warn["sender"], warn["reason"], warn["amount"],
"" if warn["amount"] == 1 else "s", expires, end), private=True) "" if warn["amount"] == 1 else "s", expires, end))
if i == 0: if i == 0:
reply(cli, nick, chan, messages["fwarn_list_empty"], private=True) wrapper.pm(messages["fwarn_list_empty"])
return return
if command == "view": if command == "view":
@ -615,12 +615,12 @@ def fwarn(cli, nick, chan, rest):
warn_id = warn_id[1:] warn_id = warn_id[1:]
warn_id = int(warn_id) warn_id = int(warn_id)
except (IndexError, ValueError): except (IndexError, ValueError):
reply(cli, nick, chan, messages["fwarn_view_syntax"]) wrapper.reply(messages["fwarn_view_syntax"])
return return
warning = db.get_warning(warn_id) warning = db.get_warning(warn_id)
if warning is None: if warning is None:
reply(cli, nick, chan, messages["fwarn_invalid_warning"]) wrapper.reply(messages["fwarn_invalid_warning"])
return return
if warning["deleted"]: if warning["deleted"]:
@ -632,14 +632,14 @@ def fwarn(cli, nick, chan, rest):
else: else:
expires = messages["fwarn_view_active"].format(messages["fwarn_view_expires"].format(warning["expires"])) expires = messages["fwarn_view_active"].format(messages["fwarn_view_expires"].format(warning["expires"]))
reply(cli, nick, chan, messages["fwarn_view_header"].format( wrapper.pm(messages["fwarn_view_header"].format(
warning["id"], warning["target"], warning["issued"], warning["sender"], warning["id"], warning["target"], warning["issued"], warning["sender"],
warning["amount"], "" if warning["amount"] == 1 else "s", expires), private=True) warning["amount"], "" if warning["amount"] == 1 else "s", expires))
reason = [warning["reason"]] reason = [warning["reason"]]
if warning["notes"] is not None: if warning["notes"] is not None:
reason.append(warning["notes"]) reason.append(warning["notes"])
reply(cli, nick, chan, " | ".join(reason), private=True) wrapper.pm(" | ".join(reason))
sanctions = [] sanctions = []
if not warning["ack"]: if not warning["ack"]:
@ -656,7 +656,7 @@ def fwarn(cli, nick, chan, rest):
if "tempban" in warning["sanctions"]: if "tempban" in warning["sanctions"]:
sanctions.append(messages["fwarn_view_tempban"].format(warning["sanctions"]["tempban"])) sanctions.append(messages["fwarn_view_tempban"].format(warning["sanctions"]["tempban"]))
if sanctions: if sanctions:
reply(cli, nick, chan, " ".join(sanctions), private=True) wrapper.pm(" ".join(sanctions))
return return
if command == "del": if command == "del":
@ -666,22 +666,23 @@ def fwarn(cli, nick, chan, rest):
warn_id = warn_id[1:] warn_id = warn_id[1:]
warn_id = int(warn_id) warn_id = int(warn_id)
except (IndexError, ValueError): except (IndexError, ValueError):
reply(cli, nick, chan, messages["fwarn_del_syntax"]) wrapper.reply(messages["fwarn_del_syntax"])
return return
warning = db.get_warning(warn_id) warning = db.get_warning(warn_id)
if warning is None: if warning is None:
reply(cli, nick, chan, messages["fwarn_invalid_warning"]) wrapper.reply(messages["fwarn_invalid_warning"])
return return
acc, hm = parse_warning_target(nick) acc, hm = parse_warning_target(wrapper.source.nick)
db.del_warning(warn_id, acc, hm) db.del_warning(warn_id, acc, hm)
reply(cli, nick, chan, messages["fwarn_done"]) wrapper.reply(messages["fwarn_done"])
if var.LOG_CHANNEL: if var.LOG_CHANNEL:
cli.msg(var.LOG_PREFIX + var.LOG_CHANNEL, messages["fwarn_log_del"].format(warn_id, warning["target"], hm, msg = messages["fwarn_log_del"].format(
warning["reason"], (" | " + warning["notes"]) if warning["notes"] else "")) warn_id, warning["target"], hm,
warning["reason"], (" | " + warning["notes"]) if warning["notes"] else "")
channels.get(var.LOG_CHANNEL).send(msg, prefix=var.LOG_PREFIX)
return return
if command == "set": if command == "set":
@ -691,12 +692,12 @@ def fwarn(cli, nick, chan, rest):
warn_id = warn_id[1:] warn_id = warn_id[1:]
warn_id = int(warn_id) warn_id = int(warn_id)
except (IndexError, ValueError): except (IndexError, ValueError):
reply(cli, nick, chan, messages["fwarn_set_syntax"]) wrapper.reply(messages["fwarn_set_syntax"])
return return
warning = db.get_warning(warn_id) warning = db.get_warning(warn_id)
if warning is None: if warning is None:
reply(cli, nick, chan, messages["fwarn_invalid_warning"]) wrapper.reply(messages["fwarn_invalid_warning"])
return return
rsp = " ".join(params).split("|", 1) rsp = " ".join(params).split("|", 1)
@ -722,11 +723,11 @@ def fwarn(cli, nick, chan, rest):
try: try:
amount = int(expires[:-1]) amount = int(expires[:-1])
except ValueError: except ValueError:
reply(cli, nick, chan, messages["fwarn_expiry_invalid"]) wrapper.reply(messages["fwarn_expiry_invalid"])
return return
if amount <= 0: if amount <= 0:
reply(cli, nick, chan, messages["fwarn_expiry_invalid"]) wrapper.reply(messages["fwarn_expiry_invalid"])
return return
issued = datetime.strptime(warning["issued"], "%Y-%m-%d %H:%M:%S") issued = datetime.strptime(warning["issued"], "%Y-%m-%d %H:%M:%S")
@ -737,7 +738,7 @@ def fwarn(cli, nick, chan, rest):
elif suffix == "m": elif suffix == "m":
expires = issued + timedelta(minutes=amount) expires = issued + timedelta(minutes=amount)
else: else:
reply(cli, nick, chan, messages["fwarn_expiry_invalid"]) wrapper.reply(messages["fwarn_expiry_invalid"])
return return
round_add = 0 round_add = 0
@ -759,7 +760,7 @@ def fwarn(cli, nick, chan, rest):
notes = warning["notes"] notes = warning["notes"]
db.set_warning(warn_id, expires, reason, notes) db.set_warning(warn_id, expires, reason, notes)
reply(cli, nick, chan, messages["fwarn_done"]) wrapper.reply(messages["fwarn_done"])
if var.LOG_CHANNEL: if var.LOG_CHANNEL:
changes = [] changes = []
@ -775,8 +776,8 @@ def fwarn(cli, nick, chan, rest):
else: else:
changes.append(messages["fwarn_log_set_notes_new"].format(notes)) changes.append(messages["fwarn_log_set_notes_new"].format(notes))
if changes: if changes:
log_msg = messages["fwarn_log_set"].format(warn_id, warning["target"], nick, " | ".join(changes)) log_msg = messages["fwarn_log_set"].format(warn_id, warning["target"], wrapper.source.nick, " | ".join(changes))
cli.msg(var.LOG_PREFIX + var.LOG_CHANNEL, log_msg) channels.get(var.LOG_CHANNEL).send(log_msg, prefix=var.LOG_PREFIX)
return return
@ -790,10 +791,10 @@ def fwarn(cli, nick, chan, rest):
try: try:
points = int(p) points = int(p)
except ValueError: except ValueError:
reply(cli, nick, chan, messages["fwarn_points_invalid"]) wrapper.reply(messages["fwarn_points_invalid"])
return return
if points < 0: if points < 0:
reply(cli, nick, chan, messages["fwarn_points_invalid"]) wrapper.reply(messages["fwarn_points_invalid"])
return return
elif notes is not None: elif notes is not None:
notes += " " + p notes += " " + p
@ -809,7 +810,7 @@ def fwarn(cli, nick, chan, rest):
reason = p[1:] reason = p[1:]
elif p[0] == "~": elif p[0] == "~":
if p == "~": if p == "~":
reply(cli, nick, chan, messages["fwarn_syntax"]) wrapper.reply(messages["fwarn_syntax"])
return return
expires = p[1:] expires = p[1:]
else: else:
@ -830,18 +831,18 @@ def fwarn(cli, nick, chan, rest):
if normalized == "warn": if normalized == "warn":
normalized = None normalized = None
if normalized is None: if normalized is None:
reply(cli, nick, chan, messages["fwarn_deny_invalid_command"].format(cmd)) wrapper.reply(messages["fwarn_deny_invalid_command"].format(cmd))
return return
normalized_cmds.add(normalized) normalized_cmds.add(normalized)
sanctions["deny"] = normalized_cmds sanctions["deny"] = normalized_cmds
except IndexError: except IndexError:
reply(cli, nick, chan, messages["fwarn_deny_invalid"]) wrapper.reply(messages["fwarn_deny_invalid"])
return return
elif sanc[0] == "stasis": elif sanc[0] == "stasis":
try: try:
sanctions["stasis"] = int(sanc[1]) sanctions["stasis"] = int(sanc[1])
except (IndexError, ValueError): except (IndexError, ValueError):
reply(cli, nick, chan, messages["fwarn_stasis_invalid"]) wrapper.reply(messages["fwarn_stasis_invalid"])
return return
elif sanc[0] == "tempban": elif sanc[0] == "tempban":
try: try:
@ -858,14 +859,14 @@ def fwarn(cli, nick, chan, rest):
elif suffix == "m": elif suffix == "m":
sanctions["tempban"] = datetime.utcnow() + timedelta(minutes=banamt) sanctions["tempban"] = datetime.utcnow() + timedelta(minutes=banamt)
except (IndexError, ValueError): except (IndexError, ValueError):
reply(cli, nick, chan, messages["fwarn_tempban_invalid"]) wrapper.reply(messages["fwarn_tempban_invalid"])
return return
else: else:
# not a valid sanction, assume this is the start of the reason # not a valid sanction, assume this is the start of the reason
reason = p reason = p
if target is None or points is None or reason is None: if target is None or points is None or reason is None:
reply(cli, nick, chan, messages["fwarn_add_syntax"]) wrapper.reply(messages["fwarn_add_syntax"])
return return
reason = reason.strip() reason = reason.strip()
@ -880,15 +881,15 @@ def fwarn(cli, nick, chan, rest):
expires = None expires = None
try: try:
warn_id = add_warning(cli, target, points, nick, reason, notes, expires, sanctions) warn_id = add_warning(wrapper.client, target, points, wrapper.source.nick, reason, notes, expires, sanctions) # FIXME
except ValueError: except ValueError:
reply(cli, nick, chan, messages["fwarn_expiry_invalid"]) wrapper.reply(messages["fwarn_expiry_invalid"])
return return
if warn_id is False: if warn_id is False:
reply(cli, nick, chan, messages["fwarn_cannot_add"]) wrapper.reply(messages["fwarn_cannot_add"])
else: else:
reply(cli, nick, chan, messages["fwarn_added"].format(warn_id)) wrapper.reply(messages["fwarn_added"].format(warn_id))
# Log to ops/log channel (even if the warning was placed in that channel) # Log to ops/log channel (even if the warning was placed in that channel)
if var.LOG_CHANNEL: if var.LOG_CHANNEL:
log_reason = reason log_reason = reason
@ -898,9 +899,8 @@ def fwarn(cli, nick, chan, rest):
log_length = messages["fwarn_log_add_noexpiry"] log_length = messages["fwarn_log_add_noexpiry"]
else: else:
log_length = messages["fwarn_log_add_expiry"].format(expires) log_length = messages["fwarn_log_add_expiry"].format(expires)
log_msg = messages["fwarn_log_add"].format(warn_id, target, nick, log_reason, points, log_msg = messages["fwarn_log_add"].format(warn_id, target, wrapper.source.nick, log_reason, points,
"" if points == 1 else "s", log_length) "" if points == 1 else "s", log_length)
cli.msg(var.LOG_PREFIX + var.LOG_CHANNEL, log_msg) channels.get(var.LOG_CHANNEL).send(log_msg, prefix=var.LOG_PREFIX)
# vim: set sw=4 expandtab: # vim: set sw=4 expandtab: