diff --git a/Bantracker/plugin.py b/Bantracker/plugin.py index fc77432..87479a8 100644 --- a/Bantracker/plugin.py +++ b/Bantracker/plugin.py @@ -119,8 +119,11 @@ def readTimeDelta(s): # completed an unit, add to seconds string = string.strip() if string: - mult = timeUnits[string] - seconds += number * mult + try: + unit = timeUnits[string] + except KeyError: + raise ValueError(string) + seconds += number * unit string = '' string += c else: @@ -139,8 +142,11 @@ def readTimeDelta(s): else: string = string.strip() if string: - mult = timeUnits[string] - seconds += number * mult + try: + unit = timeUnits[string] + except KeyError: + raise ValueError(string) + seconds += number * unit return seconds @@ -1466,12 +1472,54 @@ class Bantracker(callbacks.Plugin): updatebt = wrap(updatebt, [optional('anything', default=None)]) - def comment(self, irc, msg, args, id, kickmsg): - """ [] + def _getBan(self, id): + """gets mask, channel and removal date of ban""" + L = self.db_run("SELECT mask, channel, removal FROM bans WHERE id = %s", + id, expect_result=True) + if not L: + raise ValueError + return L[0] + + def _setBanDuration(self, id, duration): + # check if ban has already a duration time + for idx, br in enumerate(self.managedBans): + if id == br.ban.id: + ban = br.ban + del self.managedBans.shelf[idx] + break + else: + # ban obj ins't in self.managedBans + try: + mask, channel, removal = self._getBan(id) + except ValueError: + raise Exception("unknow id") + + type = guessBanType(mask) + if type not in ('ban', 'quiet'): + raise Exception("not a ban or quiet") + + if removal: + raise Exception("ban was removed") + + for ban in self.bans[channel]: + if mask == ban.mask: + if ban.id is None: + ban.id = id + break + else: + # ban not in sync it seems, shouldn't happen normally. + raise Exception("bans not in sync") + + # add ban duration + self.managedBans.add(BanRemoval(ban, duration)) + + def comment(self, irc, msg, args, ids, kickmsg): + """[, ...] [][, ] Reads or adds the for the ban with , use @bansearch to find the id of a ban """ + def addComment(id, nick, msg): n = now() self.db_run("INSERT INTO comments (ban_id, who, comment, time) values(%s,%s,%s,%s)", (id, nick, msg, n)) @@ -1479,74 +1527,74 @@ class Bantracker(callbacks.Plugin): return self.db_run("SELECT who, comment, time FROM comments WHERE ban_id=%i", (id,), True) nick = msg.nick - if kickmsg: - addComment(id, nick, kickmsg) - irc.replySuccess() - else: - data = readComment(id) - if data: - for c in data: - irc.reply("%s %s: %s" % (cPickle.loads(c[2]).astimezone(pytz.timezone('UTC')).strftime("%b %d %Y %H:%M:%S"), c[0], c[1].strip()) ) + duration, banset = None, [] + if kickmsg and ',' in kickmsg: + s = kickmsg[kickmsg.rfind(','):] + try: + duration = readTimeDelta(s) + except ValueError: + pass + + for id in [ int(i) for i in ids.split(',') if i.isdigit() and int(i) > 0 ]: + try: + mask, channel, removal = self._getBan(id) + except ValueError: + irc.reply("I don't know any ban with id %s." % id) + continue + + if kickmsg: + addComment(id, nick, kickmsg) + if duration is not None: + # set duration time + type = guessBanType(mask) + if type not in ('ban', 'quiet'): + continue + + try: + self._setBanDuration(id, duration) + banset.append(str(id)) + except Exception as exc: + irc.reply("Failed to set duration time on ban %s (%s)" % (id, exc)) else: - irc.error("No comments recorded for ban %i" % id) - comment = wrap(comment, ['id', optional('text')]) + data = readComment(id) + if data: + for c in data: + date = cPickle.loads(c[2]).astimezone(pytz.timezone('UTC')).strftime("%b %d %Y %H:%M") + irc.reply("%s %s: %s" % (date, c[0], c[1].strip())) + else: + irc.reply("No comments recorded for ban %s" % id) + + # success reply. If duration time used, say which ones. + if kickmsg: + if duration is not None: + if banset: + irc.reply("Ban set for auto removal: %s" % ', '.join(banset)) + else: + irc.replySuccess() + + comment = wrap(comment, ['something', optional('text')]) def banremove(self, irc, msg, args, ids, timespec): - """[, ...]