Merge lp:~m4v/ubuntu-bots/bugfixes into lp:ubuntu-bots

Proposed by m4v
Status: Merged
Merged at revision: 161
Proposed branch: lp:~m4v/ubuntu-bots/bugfixes
Merge into: lp:ubuntu-bots
Diff against target: 197 lines (+91/-10)
2 files modified
Bantracker/config.py (+30/-3)
Bantracker/plugin.py (+61/-7)
To merge this branch: bzr merge lp:~m4v/ubuntu-bots/bugfixes
Reviewer Review Type Date Requested Status
Terence Simpson Approve
Review via email: mp+22316@code.launchpad.net

Description of the change

-implements feature described in bug #521516
-some minor fixes (a typo and syntax error)
-catch except on realname bans

To post a comment you must log in.
Revision history for this message
Terence Simpson (tsimpson) wrote :

Approved for merge

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Bantracker/config.py'
2--- Bantracker/config.py 2009-10-12 18:26:35 +0000
3+++ Bantracker/config.py 2010-03-28 05:00:41 +0000
4@@ -15,13 +15,40 @@
5 import supybot.conf as conf
6 import supybot.registry as registry
7
8+class ValidTypes(registry.OnlySomeStrings):
9+ """Invalid type, valid types are: 'removal', 'ban' or 'quiet'."""
10+ validStrings = ('removal', 'ban', 'quiet')
11+
12+class SpaceSeparatedListOfTypes(registry.SpaceSeparatedListOf):
13+ Value = ValidTypes
14+
15+
16 def configure(advanced):
17 conf.registerPlugin('Bantracker', True)
18
19 Bantracker = conf.registerPlugin('Bantracker')
20-conf.registerChannelValue(conf.supybot.plugins.Bantracker, 'enabled',
21+conf.registerChannelValue(Bantracker, 'enabled',
22 registry.Boolean(False, """Enable the bantracker"""))
23-conf.registerGlobalValue(conf.supybot.plugins.Bantracker, 'database',
24+conf.registerGlobalValue(Bantracker, 'database',
25 registry.String('', "Filename of the bans database", private=True))
26-conf.registerGlobalValue(conf.supybot.plugins.Bantracker, 'bansite',
27+conf.registerGlobalValue(Bantracker, 'bansite',
28 registry.String('', "Web site for the bantracker, without the 'bans.cgi' appended", private=True))
29+
30+conf.registerGroup(Bantracker, 'commentRequest')
31+conf.registerChannelValue(Bantracker.commentRequest, 'type',
32+ SpaceSeparatedListOfTypes(['removal', 'ban', 'quiet'],
33+ "List of events for which the bot should request a comment."))
34+conf.registerChannelValue(Bantracker.commentRequest, 'ignore',
35+ registry.SpaceSeparatedListOfStrings([],
36+ "List of nicks for which the bot won't request to comment a ban/quiet/removal."\
37+ " Is case insensible and wildcards * ? are accepted."))
38+conf.registerChannelValue(Bantracker.commentRequest, 'forward',
39+ registry.SpaceSeparatedListOfStrings([],
40+ "List of nicks for which the bot will forward the request to"\
41+ " the channels/nicks defined in forwards.channels option."\
42+ " Is case insensible and wildcards * ? are accepted."))
43+conf.registerChannelValue(Bantracker.commentRequest.forward, 'channels',
44+ registry.SpaceSeparatedListOfStrings([],
45+ "List of channels/nicks to forward the request if the op that set the ban/quiet"\
46+ " is in the forward list."))
47+
48
49=== modified file 'Bantracker/plugin.py'
50--- Bantracker/plugin.py 2010-03-28 03:34:17 +0000
51+++ Bantracker/plugin.py 2010-03-28 05:00:41 +0000
52@@ -48,6 +48,7 @@
53 import supybot.ircmsgs as ircmsgs
54 import supybot.conf as conf
55 import supybot.ircdb as ircdb
56+from fnmatch import fnmatch
57 import sqlite
58 import pytz
59 import cPickle
60@@ -91,6 +92,16 @@
61 pattern = pattern[1:]
62 return ircutils.hostmaskPatternEqual(pattern, hostmask)
63
64+def nickMatch(nick, pattern):
65+ """Checks if a given nick matches a pattern or in a list of patterns."""
66+ if isinstance(pattern, str):
67+ pattern = [pattern]
68+ nick = nick.lower()
69+ for s in pattern:
70+ if fnmatch(nick, s.lower()):
71+ return True
72+ return False
73+
74 def dequeue(parent, irc):
75 global queue
76 queue.dequeue(parent, irc)
77@@ -116,8 +127,9 @@
78 class Ban(object):
79 """Hold my bans"""
80 def __init__(self, args=None, **kwargs):
81- object.__init__(self)
82+ self.id = None
83 if args:
84+ # in most ircd: args = (nick, channel, mask, who, when)
85 self.mask = args[2]
86 self.who = args[3]
87 self.when = float(args[4])
88@@ -125,6 +137,8 @@
89 self.mask = kwargs['mask']
90 self.who = kwargs['who']
91 self.when = float(kwargs['when'])
92+ if 'id' in kwargs:
93+ self.id = kwargs['id']
94 self.ascwhen = time.asctime(time.gmtime(self.when))
95
96 def __tuple__(self):
97@@ -207,7 +221,7 @@
98 mask = "%s!%s@%s" % (nick, msg.args[2].lower(), msg.args[3].lower())
99 self.nicks[nick] = mask
100 if nick in self.replies:
101- f = getattr(self, "real_%s" % self.replies[nick][0])
102+ f = getattr(self, "%s_real" % self.replies[nick][0])
103 args = self.replies[nick][1]
104 del self.replies[nick]
105 kwargs={'from_reply': True, 'reply': "%s!%s@%s" % (msg.args[1], msg.args[2], msg.args[3])}
106@@ -220,7 +234,7 @@
107 if not nick in self.nicks:
108 self.nicks[nick] = mask
109 if nick in self.replies:
110- f = getattr(self, "real_%s" % self.replies[nick][0])
111+ f = getattr(self, "%s_real" % self.replies[nick][0])
112 args = self.replies[nick][1]
113 del self.replies[nick]
114 kwargs={'from_reply': True, 'reply': "%s!%s@%s" % (msg.args[1], msg.args[2], msg.args[3])}
115@@ -234,7 +248,7 @@
116 """/whowas faild"""
117 nick = msg.args[1].lower()
118 if nick in self.replies:
119- f = getattr(self, "real_%s" % self.replies[nick][0])
120+ f = getattr(self, "%s_real" % self.replies[nick][0])
121 args = self.replies[nick][1]
122 del self.replies[nick]
123 kwargs = {'from_reply': True, 'reply': None}
124@@ -324,6 +338,40 @@
125 self.db.commit()
126 return data
127
128+ def requestComment(self, irc, channel, ban, type=None):
129+ # check if we should request a comment
130+ if nickMatch(ban.who, self.registryValue('commentRequest.ignore', channel=channel)):
131+ return
132+ # check the type of the action taken
133+ mask = ban.mask
134+ if not type:
135+ if mask[0] == '%':
136+ type = 'quiet'
137+ mask = mask[1:]
138+ elif ircutils.isUserHostmask(mask) or mask.endswith('(realname)'):
139+ type = 'ban'
140+ else:
141+ type = 'removal'
142+ # check if type is enabled
143+ if type not in self.registryValue('commentRequest.type', channel=channel):
144+ return
145+ # send msg
146+ prefix = conf.supybot.reply.whenAddressedBy.chars()[0] # prefix char for commands
147+ # check to who send the request
148+ if nickMatch(ban.who, self.registryValue('commentRequest.forward', channel=channel)):
149+ channels = self.registryValue('commentRequest.forward.channels', channel=channel)
150+ if channels:
151+ s = "Please somebody comment on the %s of %s in %s done by %s, use:"\
152+ " %scomment %s <comment>" %(type, mask, channel, ban.who, prefix, ban.id)
153+ for chan in channels:
154+ msg = ircmsgs.notice(chan, s)
155+ irc.queueMsg(msg)
156+ return
157+ # send to op
158+ s = "Please comment on the %s of %s in %s, use: %scomment %s <comment>" \
159+ %(type, mask, channel, prefix, ban.id)
160+ irc.reply(s, to=ban.who, private=True)
161+
162 def doLog(self, irc, channel, s):
163 if not self.registryValue('enabled', channel):
164 return
165@@ -350,7 +398,9 @@
166 self.db_run("INSERT INTO comments (ban_id, who, comment, time) values(%s,%s,%s,%s)", (id, nick, extra_comment, n))
167 if channel not in self.bans:
168 self.bans[channel] = []
169- self.bans[channel].append(Ban(mask=target, who=nick, when=time.mktime(time.gmtime())))
170+ ban = Ban(mask=target, who=nick, when=time.mktime(time.gmtime()), id=id)
171+ self.bans[channel].append(ban)
172+ self.requestComment(irc, channel, ban)
173 return id
174
175 def doUnban(self, irc, channel, nick, mask):
176@@ -448,7 +498,7 @@
177 ' '.join(msg.args[2:])))
178 modes = ircutils.separateModes(msg.args[1:])
179 for param in modes:
180- realname = ''
181+ realname = ''
182 mode = param[0]
183 mask = ''
184 comment=None
185@@ -473,7 +523,11 @@
186 self.lastStates[irc] = irc.state.copy()
187 if mask[0] == '%':
188 mask = mask[1:]
189- (nick, ident, host) = ircutils.splitHostmask(mask)
190+ try:
191+ (nick, ident, host) = ircutils.splitHostmask(mask)
192+ except AssertionError:
193+ # not a hostmask
194+ return None
195 channel = None
196 chan = None
197 if mask[0] not in ('*', '?'): # Nick ban

Subscribers

People subscribed via source and target branches