adkfasdyfb

This commit is contained in:
Dennis Kaarsemaker
2006-12-27 15:33:59 +01:00
parent 167d4b8005
commit c625bf3697
7 changed files with 216 additions and 151 deletions

View File

@ -14,7 +14,7 @@
###
import sys
sys.path.append('/home/dennis/public_html')
sys.path.append('/var/www/bots.ubuntulinux.nl')
from commoncgi import *
import lp_auth
import sha
@ -30,6 +30,10 @@ cur = con.cursor()
# Login check
person = None
error = ''
anonymous = form.has_key('anonymous')
anonlink = ''
if anonymous:
anonlink = '&anonymous=1';
# Delete old sessions
cur.execute("""DELETE FROM sessions WHERE time < %d""", int(time.time()) - 2592000 * 3)
@ -127,12 +131,10 @@ if not person and form.has_key('user') and form.has_key('pw'):
error = "You are not in the '%s' group on launchpad" % lp_group
# Not authenticated.
if not person or not person.authenticated:
if not (person and person.authenticated) and not anonymous:
if error:
print """<span style="color:red">%s</span>""" % error
print """<form action="/bans.cgi" method="post">
<b>The old launchpad based authentication system has been
disabled!</b><br /><br />
Login:<br />
<input class="input" type="text" name="user" /><br />
Password:<br />
@ -148,6 +150,7 @@ if not person or not person.authenticated:
<input class="input" type="text" name="lpmail" /><br /><br />
<input class="submit" type="submit" value="Request password" />
</form>
<a href="/bans.cgi?anonymous=1">Browse the bantracker anonymously</a>
"""
send_page('bans.tmpl')
@ -161,7 +164,7 @@ if form.has_key('log'):
# Main page
# Process comments
if form.has_key('comment') and form.has_key('comment_id'):
if form.has_key('comment') and form.has_key('comment_id') and not anonymous:
cur.execute("""SELECT ban_id FROM comments WHERE ban_id=%s and comment=%s""", (form['comment_id'].value, form['comment'].value))
comm = cur.fetchall()
if not len(comm):
@ -171,9 +174,14 @@ if form.has_key('comment') and form.has_key('comment_id'):
# Write the page
print '<form action="bans.cgi" method="POST">'
if anonymous:
print '<input type="hidden" name="anonymous" value="1" />'
# Personal data
print '<div class="pdata"> Logged in as: %s <br /> Timezone: ' % person.name
print '<div class="pdata">'
if not anonymous:
print 'Logged in as: %s <br /> ' % person.name
print 'Timezone: '
if form.has_key('tz') and form['tz'].value in pytz.common_timezones:
tz = form['tz'].value
elif cookie.has_key('tz') and cookie['tz'].value in pytz.common_timezones:
@ -188,28 +196,32 @@ for zone in pytz.common_timezones:
print ' selected="selected"'
print ">%s</option>" % zone
print '</select><input class="submit" type="submit" value="change" /></form><br />'
if form.has_key('pw1') and form.has_key('pw2'):
pw1 = form['pw1'].value; pw2 = form['pw2'].value
if pw1 and pw2:
if pw1 != pw2:
print "Passwords don't match!<br />"
else:
cur.execute("SELECT salt FROM users WHERE username = %s", person.nick)
salt = cur.fetchall()[0][0]
cur.execute("UPDATE USERS SET password = %s WHERE username = %s",
(sha.new(salt + sha.new(pw1 + salt).hexdigest().lower()).hexdigest().lower(), person.nick))
con.commit()
print '<form action="bans.cgi" method="POST">'
print 'Password: '
print '<input class="input" type="password" name="pw1" size="10"/>'
print '<input class="input" type="password" name="pw2" size="10"/>'
print '<input class="submit" type="submit" value="change" /></form></div>'
if not anonymous:
if form.has_key('pw1') and form.has_key('pw2'):
pw1 = form['pw1'].value; pw2 = form['pw2'].value
if pw1 and pw2:
if pw1 != pw2:
print "Passwords don't match!<br />"
else:
cur.execute("SELECT salt FROM users WHERE username = %s", person.nick)
salt = cur.fetchall()[0][0]
cur.execute("UPDATE USERS SET password = %s WHERE username = %s",
(sha.new(salt + sha.new(pw1 + salt).hexdigest().lower()).hexdigest().lower(), person.nick))
con.commit()
print '<form action="bans.cgi" method="POST">'
print 'Password: '
print '<input class="input" type="password" name="pw1" size="10"/>'
print '<input class="input" type="password" name="pw2" size="10"/>'
print '<input class="submit" type="submit" value="change" /></form>'
print '</div>'
tz = pytz.timezone(tz)
# Search form
print '<div class="search">'
print '<form action="/bans.cgi" method="GET">'
if anonymous:
print '<input type="hidden" name="anonymous" value="1" />'
print '<input class="input" type="text" name="query"'
if form.has_key('query'):
print 'value="%s" ' % form['query'].value
@ -254,7 +266,7 @@ if not form.has_key('query'):
cur.execute('SELECT COUNT(id) FROM bans')
nump = math.ceil(int(cur.fetchall()[0][0]) / float(num_per_page))
for i in range(nump):
print '<a href="bans.cgi?page=%d%s">%d</a> &middot;' % (i, sort, i+1)
print '<a href="bans.cgi?page=%d%s%s">%d</a> &middot;' % (i, sort, anonlink, i+1)
print '</div>'
# Empty log div, will be filled with AJAX
@ -270,7 +282,7 @@ for h in [['Channel',0], ['Nick/Mask',1], ['Operator',2], ['Time',6]]:
if v < 10: h[1] += 10
except:
pass
print '<th><a href="bans.cgi?sort=%s">%s</a></th>' % (h[1],h[0])
print '<th><a href="bans.cgi?sort=%s%s">%s</a></th>' % (h[1],anonlink,h[0])
print '<th>Log</th></tr>'
# Select and filter bans
@ -373,11 +385,12 @@ for b in bans[start:end]:
print q(c[1])
print u' <span class="removal"><br />%s, %s</span><br />' % \
(c[0],pickle.loads(c[2]).astimezone(tz).strftime("%b %d %Y %H:%M:%S"))
print """<span class="pseudolink" onclick="toggle('%s','comment')">Add comment</span>""" % b[6]
print """<div class="invisible" id="comment_%s"><br />""" % b[6]
print """<form action="bans.cgi" method="POST"><textarea cols="50" rows="5" class="input" name="comment"></textarea><br />"""
print """<input type="hidden" name="comment_id" value="%s" />""" % b[6]
print """<input class="submit" type="submit" value="Send" /></form>"""
if not anonymous:
print """<span class="pseudolink" onclick="toggle('%s','comment')">Add comment</span>""" % b[6]
print """<div class="invisible" id="comment_%s"><br />""" % b[6]
print """<form action="bans.cgi" method="POST"><textarea cols="50" rows="5" class="input" name="comment"></textarea><br />"""
print """<input type="hidden" name="comment_id" value="%s" />""" % b[6]
print """<input class="submit" type="submit" value="Send" /></form>"""
print '</td></tr>'
print '</table>'

View File

@ -21,3 +21,5 @@ def configure(advanced):
Bantracker = conf.registerPlugin('Bantracker')
conf.registerChannelValue(conf.supybot.plugins.BanTracker, 'enabled',
registry.Boolean(False, """Enable the bantracker"""))
conf.registerChannelValue(conf.supybot.plugins.BanTracker, 'stats',
registry.Boolean(False, """Enable join/part stats"""))

View File

@ -50,6 +50,7 @@ import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
import supybot.ircmsgs as ircmsgs
import supybot.conf as conf
import supybot.world as world
import sqlite, pytz, cPickle, datetime, time
@ -84,6 +85,8 @@ class Bantracker(callbacks.Plugin):
self.lastMsgs = {}
self.lastStates = {}
self.logs = {}
for channel in irc.state.channels:
self.doStatsLog(irc, channel, "START")
def __call__(self, irc, msg):
try:
@ -115,11 +118,14 @@ class Bantracker(callbacks.Plugin):
s = time.strftime(format) + " " + ircutils.stripFormatting(s)
self.logs[channel] = self.logs[channel][-199:] + [s.strip()]
def doStatsLog(self, irc, msg, type):
#format = conf.supybot.log.timestampFormat()
#print "%15s %s %s %s %s" % (msg.args[0], time.strftime(format), type,
# msg.prefix, len(irc.state.channels[msg.args[0]].users))
pass
def doStatsLog(self, irc, chan, type):
if not self.registryValue('stats', chan):
return
num = len(irc.state.channels[chan].users)
format = conf.supybot.log.timestampFormat()
statslog = open('/home/dennis/ubugtu/data/statslog','a')
statslog.write("%-20s %f %s %-6s %d\n" % (chan, time.time(), time.strftime(format), type, num))
statslog.close()
def doKickban(self, irc, channel, nick, target, kickmsg = None):
if not self.registryValue('enabled', channel):
@ -165,7 +171,8 @@ class Bantracker(callbacks.Plugin):
for channel in msg.args[0].split(','):
self.doLog(irc, channel,
'*** %s has joined %s\n' % (msg.nick or msg.prefix, channel))
self.doStatsLog(irc, msg, "JOIN")
if irc.prefix != msg.prefix:
self.doStatsLog(irc, msg.args[0], "JOIN")
def doKick(self, irc, msg):
if len(msg.args) == 3:
@ -180,7 +187,7 @@ class Bantracker(callbacks.Plugin):
self.doLog(irc, channel,
'*** %s was kicked by %s\n' % (target, msg.nick))
self.doKickban(irc, channel, msg.nick, target, kickmsg)
self.doStatsLog(irc, msg, "KICK")
self.doStatsLog(irc, msg.args[0], "KICK")
def doPart(self, irc, msg):
for channel in msg.args[0].split(','):
@ -188,7 +195,8 @@ class Bantracker(callbacks.Plugin):
if msg.args[1].startswith('requested by'):
args = msg.args[1].split()
self.doKickban(irc, channel, args[2].replace(':',''), msg.nick, ' '.join(args[3:])[1:-1].strip())
self.doStatsLog(irc, msg, "PART")
if irc.prefix != msg.prefix:
self.doStatsLog(irc, msg.args[0], "PART")
def doMode(self, irc, msg):
channel = msg.args[0]
@ -224,7 +232,7 @@ class Bantracker(callbacks.Plugin):
for (channel, chan) in self.lastStates[irc].channels.iteritems():
if msg.nick in chan.users:
self.doLog(irc, channel, '*** %s has quit IRC (%s)\n' % (msg.nick, msg.args[0]))
self.doStatsLog(irc, msg, "QUIT")
self.doStatsLog(irc, channel, "QUIT")
def outFilter(self, irc, msg):
# Gotta catch my own messages *somehow* :)
@ -234,5 +242,8 @@ class Bantracker(callbacks.Plugin):
m = ircmsgs.IrcMsg(msg=msg, prefix=irc.prefix)
self(irc, m)
return msg
def do366(self, irc, msg):
self.doStatsLog(irc, msg.args[1], "START")
Class = Bantracker

View File

@ -46,3 +46,7 @@ conf.registerGlobalValue(conf.supybot.plugins.Bugtracker, 'bugtrackers',
conf.registerGlobalValue(conf.supybot.plugins.Bugtracker, 'replyWhenNotFound',
registry.Boolean(False, """Whether to send a message when a bug could not be
found"""))
conf.registerChannelValue(conf.supybot.plugins.Bugtracker, 'repeatdelay',
registry.Integer(60, """Number of seconds to wait between repeated bug calls"""))
conf.registerChannelValue(conf.supybot.plugins.Bugtracker, 'showassignee',
registry.Boolean(False, """Whether to show th assignee in bug reports"""))

View File

@ -22,11 +22,16 @@ import supybot.conf as conf
import supybot.registry as registry
import supybot.schedule as schedule
import re, os, time
import re, os, time, imaplib, commands
import xml.dom.minidom as minidom
from htmlentitydefs import entitydefs as entities
import email.FeedParser
bugreporter_base = '/home/dennis/ubugtu/data/bugmail'
imap_server = 'localhost'
imap_user = commands.getoutput('cat /home/dennis/ubugtu/imap_user')
imap_password = commands.getoutput('cat /home/dennis/ubugtu/imap_password')
def registerBugtracker(name, url='', description='', trackertype=''):
conf.supybot.plugins.Bugtracker.bugtrackers().add(name)
group = conf.registerGroup(conf.supybot.plugins.Bugtracker.bugtrackers, name)
@ -98,10 +103,16 @@ class Bugtracker(callbacks.PluginRegexp):
self.shown = {}
self.nomailtime = 0
def die(self):
try:
schedule.removeEvent(self.name())
except:
pass
def is_ok(self, channel, tracker, bug):
now = time.time()
for k in self.shown.keys():
if self.shown[k] < now - 60:
if self.shown[k] < now - self.registryValue('repeatdelay', channel):
self.shown.pop(k)
if (channel, tracker, bug) not in self.shown:
self.shown[(channel, tracker, bug)] = now
@ -110,76 +121,64 @@ class Bugtracker(callbacks.PluginRegexp):
def reportnewbugs(self,irc):
# Compile list of bugs
#print "Reporting new bugs"
print "Reporting new bugs"
tracker = self.db['malone']
bugs = {}
fixed = {}
for c in irc.state.channels:
dir = self.registryValue('bugReporter', channel=c)
if not dir:
sc = imaplib.IMAP4_SSL(imap_server)
sc.login(imap_user, imap_password)
sc.select('INBOX')
new_mail = sc.search(None, '(UNSEEN)')[1][0].split()[:20]
for m in new_mail:
print "Loading %s" % m
msg = sc.fetch(m, 'RFC822')[1][0][1]
#print msg
fp = email.FeedParser.FeedParser()
fp.feed(msg)
bug = fp.close()
#print "Mail parsed"
# Determine bug number, component and tag
try:
id = int(bug['Reply-To'].split()[1])
except:
continue
#print "Reporting in %s (%s)" % (c, dir)
if dir not in bugs:
#print "Reloading info from %s" % dir
bugs[dir] = {}
if dir.endswith('bugmail'):
if len(os.listdir(os.path.join(dir,'Maildir','new'))) == 0:
self.nomailtime += 1
if self.nomailtime == 30:
irc.queueMsg(ircmsgs.privmsg(c,'WARNING: No bugmail received in 30 minutes. Please poke Seveas.'))
self.nomailtime = 0
else:
#irc.queueMsg(ircmsgs.privmsg('#ubuntu-bots','Seveas: your lucky number is %d' % self.nomailtime))
self.nomailtime = 0
for file in os.listdir(os.path.join(dir,'Maildir','new')):
#print "Checking %s" % file
fd = open(os.path.join(dir,'Maildir','new',file))
_data = fd.readlines()
fd.close()
os.unlink(os.path.join(dir,'Maildir','new',file))
component = ''
data = []
for line in _data:
if line[0] in ' \t':
data[-1] += '%s ' % line.strip()
tag = bug['Delivered-To']
tag = tag[tag.find('+')+1:tag.find('@')]
component = bug['X-Launchpad-Bug']
if 'component' in component:
component = component[component.find('component=')+10:]
component = component[:component.find(';')].replace('None','')
else:
component = ''
if tag not in bugs:
bugs[tag] = {}
#print "Data extracted"
if id not in bugs[tag]:
try:
os.makedirs(os.path.join(bugreporter_base,tag,str(int(id/1000))))
except:
pass
print os.path.join(bugreporter_base,tag,str(int(id/1000)),str(id))
if id > 58184 and not os.path.exists(os.path.join(bugreporter_base,tag,str(int(id/1000)),str(id))):
print "New bug: %d" % id
fd2 = open(os.path.join(bugreporter_base,tag,str(int(id/1000)),str(id)),'w')
fd2.close()
try:
if component:
bugs[tag][id] = self.get_bug(tracker, id, False)[0].replace('"','(%s) "' % component, 1)
else:
data.append('%s ' % line.strip())
for line in data:
if line.startswith('X-Launchpad-Bug:') and not component:
if 'component' in line:
component = line[line.find('component=')+10:]
component = component[:component.find(';')]
if component == 'None':
component = ''
if line.startswith('Reply-To:'):
#print line
try:
bug = int(line.split()[2])
try:
os.makedirs(os.path.join(dir,str(int(bug/1000))))
except:
pass
if bug > 58184 and not os.path.exists(os.path.join(dir,str(int(bug/1000)),str(bug))):
#print "New bug: %d" % bug
fd2 = open(os.path.join(dir,str(int(bug/1000)),str(bug)),'w')
fd2.close()
if bug not in bugs[dir]:
try:
if component:
bugs[dir][bug] = self.get_bug(tracker, bug).replace('"','(%s) "' % component, 1)
else:
bugs[dir][bug] = self.get_bug(tracker, bug)
except:
#print "Unable to get bug %d" % b
pass
except:
#raise
pass # Ignore errors. Iz wrong mail
break
#print "New bugs in %s (%s): %s" % (c, dir, str(bugs[dir].keys()))
# Now show them
for b in sorted(bugs[dir].keys()):
irc.queueMsg(ircmsgs.privmsg(c,'New bug: #%s' % bugs[dir][b][bugs[dir][b].find('bug ')+4:]))
bugs[tag][id] = self.get_bug(tracker, id, False)[0]
except:
print "Cannot get bug %d" % id
for c in irc.state.channels:
tag = self.registryValue('bugReporter', channel=c)
if not tag:
continue
if tag not in bugs.keys():
print "No new bugs in %s" % tag
continue
print "New bugs in %s (%s): %s" % (c, tag, str(bugs[tag].keys()))
for b in sorted(bugs[tag].keys()):
irc.queueMsg(ircmsgs.privmsg(c,'New bug: #%s' % bugs[tag][b][bugs[tag][b].find('bug ')+4:]))
def add(self, irc, msg, args, name, trackertype, url, description):
"""<name> <type> <url> [<description>]
@ -286,7 +285,7 @@ class Bugtracker(callbacks.PluginRegexp):
name = ''
pass
if not name:
snarfTarget = self.registryValue('snarfTarget', msg.args[0])
snarfTarget = self.registryValue('snarfTarget', msg.args[0]).lower()
if not snarfTarget:
return
try:
@ -305,7 +304,7 @@ class Bugtracker(callbacks.PluginRegexp):
if not self.is_ok(msg.args[0],tracker, bugid):
continue
try:
report = self.get_bug(tracker,bugid)
report = self.get_bug(tracker,bugid,self.registryValue('showassignee', msg.args[0]))
except BugtrackerError, e:
if 'private' in str(e):
irc.reply("Bug %d on http://launchpad.net/bugs/%d is private" % (bugid, bugid))
@ -314,7 +313,8 @@ class Bugtracker(callbacks.PluginRegexp):
return
irc.error(str(e))
else:
irc.reply(report, prefixNick=False)
for r in report:
irc.reply(r, prefixNick=False)
#show_bug.cgi?id=|bugreport.cgi?bug=|(bugs|+bug)/|ticket/|tracker/.*aid=
#&group_id=\d+&at_id=\d+
@ -328,11 +328,12 @@ class Bugtracker(callbacks.PluginRegexp):
return
if not self.is_ok(msg.args[0],tracker, int(match.group('bug'))):
return
report = self.get_bug(tracker,int(match.group('bug')), do_url = False)
report = self.get_bug(tracker,int(match.group('bug')),self.registryValue('showassignee', msg.args[0]), do_url = False)
except BugtrackerError, e:
irc.error(str(e))
else:
irc.reply(report, prefixNick=False)
for r in report:
irc.reply(r, prefixNick=False)
turlSnarfer = urlSnarfer(turlSnarfer)
# Only useful for launchpad developers
@ -367,16 +368,23 @@ class Bugtracker(callbacks.PluginRegexp):
return tracker
return None
def get_bug(self, tracker, id, do_url = True):
(product, title, severity, status, url) = tracker.get_bug(id)
severity = severity[0].upper() + severity[1:].lower()
status = status[0].upper() + status[1:].lower()
if not do_url:
url = ''
if product:
return "%s bug %s in %s \"%s\" [%s,%s] %s" % (tracker.description, id, product,
title, severity, status, url)
return "%s bug %s \"%s\" [%s,%s] %s" % (tracker.description, id, title, severity, status, url)
def get_bug(self, tracker, id, do_assignee, do_url = True):
reports = []
for r in tracker.get_bug(id):
print r
(bid, product, title, severity, status, assignee, url) = r
severity = severity[0].upper() + severity[1:].lower()
status = status[0].upper() + status[1:].lower()
if not do_url:
url = ''
if product:
reports.append("%s bug %s in %s \"%s\" [%s,%s] %s" % (tracker.description, bid, product,
title, severity, status, url))
else:
reports.append("%s bug %s \"%s\" [%s,%s] %s" % (tracker.description, bid, title, severity, status, url))
if do_assignee and assignee:
reports[-1] = reports[-1] + (" - Assigned to %s" % assignee)
return reports
# Define all bugtrackers
class IBugtracker:
@ -431,10 +439,11 @@ class Bugzilla(IBugtracker):
pass
component = _getnodetxt(bug_n.getElementsByTagName('component')[0])
severity = _getnodetxt(bug_n.getElementsByTagName('bug_severity')[0])
assignee = _getnodetxt(bug_n.getElementsByTagName('assigned_to')[0])
except Exception, e:
s = 'Could not parse XML returned by %s bugzilla: %s' % (self.description, e)
raise BugtrackerError, s
return (component, title, severity, status, "%s/show_bug.cgi?id=%d" % (self.url, id))
return [(id, component, title, severity, status, assignee, "%s/show_bug.cgi?id=%d" % (self.url, id))]
class Issuezilla(IBugtracker):
def get_bug(self, id):
@ -458,10 +467,11 @@ class Issuezilla(IBugtracker):
pass
component = _getnodetxt(bug_n.getElementsByTagName('component')[0])
severity = _getnodetxt(bug_n.getElementsByTagName('issue_type')[0])
assignee = _getnodetxt(bug_n.getElementsByTagName('assigned_to')[0])
except Exception, e:
s = 'Could not parse XML returned by %s bugzilla: %s' % (self.description, e)
raise BugtrackerError, s
return (component, title, severity, status, "%s/show_bug.cgi?id=%d" % (self.url, id))
return [(id, component, title, severity, status, assignee, "%s/show_bug.cgi?id=%d" % (self.url, id))]
class Malone(IBugtracker):
def _parse(self, task):
@ -516,11 +526,16 @@ class Malone(IBugtracker):
except Exception, e:
s = 'Could not parse data returned by %s: %s' % (self.description, e)
raise BugtrackerError, s
# Try and find duplicates
t = taskdata['task']
if '(' in t:
t = t[:t.rfind('(') -1]
return (t, bugdata['title'], taskdata['importance'],
taskdata['status'], "%s/bugs/%s" % (self.url.replace('/malone',''), id))
if bugdata['duplicate-of']:
dupbug = self.get_bug(int(bugdata['duplicate-of']))
return [(id, t, bugdata['title'] + (' (dup-of: %d)' % dupbug[0][0]), taskdata['importance'],
taskdata['status'], "%s/bugs/%s" % (self.url.replace('/malone',''), id))] + dupbug
return [(id, t, bugdata['title'], taskdata['importance'],
taskdata['status'], taskdata['assignee'], "%s/bugs/%s" % (self.url.replace('/malone',''), id))]
# <rant>
# Debbugs sucks donkeyballs
@ -591,7 +606,7 @@ class Debbugs(IBugtracker):
except Exception, e:
s = 'Could not parse data returned by %s bugtracker: %s' % (self.description, e)
raise BugtrackerError, s
return (data['package'], data['title'], data['severity'], data['status'], "%s/%s" % (self.url, id))
return [(id, data['package'], data['title'], data['severity'], data['status'], '', "%s/%s" % (self.url, id))]
# For trac based trackers we also need to do some screenscraping - should be
# doable unless a certain track instance uses weird templates.
@ -614,7 +629,9 @@ class Trac(IBugtracker):
package = l[l.find('>')+1:l.find('</')]
if 'headers="h_severity"' in l:
severity = l[l.find('>')+1:l.find('</')]
return (package, title, severity, status, "%s/%s" % (self.url, id))
if 'headers="h_owner"' in l:
assignee = l[l.find('>')+1:l.find('</')]
return [(id, package, title, severity, status, assignee, "%s/%s" % (self.url, id))]
class WikiForms(IBugtracker):
def get_bug(self, id):
@ -624,7 +641,6 @@ class WikiForms(IBugtracker):
return s
url = "%s/%05d" % (self.url, id)
#print url
try:
bugdata = utils.web.getUrl(url)
except Exception, e:
@ -640,12 +656,14 @@ class WikiForms(IBugtracker):
status = strip_tags(l[l.find('<dd>')+4:])
if '<dt>category</dt>' in l2:
package = strip_tags(l[l.find('<dd>')+4:])
return (package, title, severity, status, "%s/%05d" % (self.url, id))
return [(id, package, title, severity, status, '', "%s/%05d" % (self.url, id))]
sfre = re.compile(r"""
.*?
<h2>\[.*?\]\s*(?P<title>.*?)</h2>
.*?
Assigned To.*?<br>\s+(?P<assignee>\S+)
.*?
Priority.*?(?P<priority>\d+)
.*?
Status.*?<br>\s+(?P<status>\S+)
@ -669,7 +687,7 @@ class Sourceforge(IBugtracker):
resolution = reo.group('resolution')
if not (resolution.lower() == 'none'):
status += ' ' + resolution
return (None, reo.group('title'), "Pri: %s" % reo.group('priority'), status, self._sf_url % id)
return [(id, None, reo.group('title'), "Pri: %s" % reo.group('priority'), status, reo.group('assignee'),self._sf_url % id)]
except:
raise BugtrackerError, "Bug not found"

View File

@ -97,14 +97,14 @@ class Encyclopedia(callbacks.PluginRegexp):
except KeyError:
irc.queueMsg(ircmsgs.privmsg('#ubuntu-ops', "In %s, %s said: %s" % (msg.args[0], msg.nick, msg.args[1])))
irc.reply("Your edit request has been forwarded to #ubuntu-ops. Thank you for your attention to detail",private=True)
lfd = open('/home/dennis/public_html/botlogs/lock','a')
lfd = open('/var/www/bots.ubuntulinux.nl/botlogs/lock','a')
fcntl.lockf(lfd, fcntl.LOCK_EX)
fd = open('/home/dennis/public_html/botlogs/%s.log' % datetime.date.today().strftime('%Y-%m-%d'),'a')
fd = open('/var/www/bots.ubuntulinux.nl/botlogs/%s.log' % datetime.date.today().strftime('%Y-%m-%d'),'a')
fd.write("%s %-20s %-16s %s\n" % (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),msg.args[0], msg.nick, msg.args[1]))
fd.close()
fcntl.lockf(lfd,fcntl.LOCK_UN)
lfd.close()
os.chmod('/home/dennis/public_html/botlogs/%s.log' % datetime.date.today().strftime('%Y-%m-%d'),0644)
os.chmod('/var/www/bots.ubuntulinux.nl/botlogs/%s.log' % datetime.date.today().strftime('%Y-%m-%d'),0644)
return False
if timeout:
for key in self.times.keys():

View File

@ -20,7 +20,8 @@ apt_pkg.init()
datadir = '/home/dennis/ubugtu/data/facts'
aptdir = '/home/dennis/ubugtu/data/apt'
distros = ('dapper','breezy','edgy','hoary','warty','dapper-commercial','dapper-seveas','breezy-seveas','dapper-imbrandon','edgy-imbrandon', 'dapper-backports','edgy-seveas')
logdir = '/var/www/bots.ubuntulinux.nl/'
distros = ('dapper','edgy','feisty','breezy','edgy','dapper-commercial','dapper-seveas','breezy-seveas','dapper-imbrandon','edgy-imbrandon', 'dapper-backports','edgy-seveas')
# Simple wrapper class for factoids
class Factoid:
@ -186,19 +187,6 @@ class Encyclopedia(callbacks.Plugin):
# Big action 1: editing factoids
if '=~' in text:
# Editing
if not capab(msg.prefix, 'editfactoids'):
irc.reply("Your edit request has been forwarded to %s. Thank you for your attention to detail"%self.registryValue('relaychannel'),private=True)
irc.queueMsg(ircmsgs.privmsg(self.registryValue('relaychannel'), "In %s, %s said: %s" % (msg.args[0], msg.nick, msg.args[1])))
lfd = open('/home/dennis/public_html/botlogs/lock','a')
fcntl.lockf(lfd, fcntl.LOCK_EX)
fd = open('/home/dennis/public_html/botlogs/%s.log' % datetime.date.today().strftime('%Y-%m-%d'),'a')
fd.write("%s %-20s %-16s %s\n" % (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), channel, msg.nick, msg.args[1]))
fd.close()
fcntl.lockf(lfd,fcntl.LOCK_UN)
lfd.close()
os.chmod('/home/dennis/public_html/botlogs/%s.log' % datetime.date.today().strftime('%Y-%m-%d'),0644)
return
# All clear!
# Find factoid
p = text.find('=~')
name, value = text[:p].strip(), text[p+2:].strip()
@ -206,6 +194,22 @@ class Encyclopedia(callbacks.Plugin):
if value.startswith('also '):
name += '-also'
value = value[5:].strip()
if len(name) > 20:
irc.error("I am only a bot, please don't think I'm intelligent :)")
return
if not capab(msg.prefix, 'editfactoids'):
irc.reply("Your edit request has been forwarded to %s. Thank you for your attention to detail"%self.registryValue('relaychannel'),private=True)
irc.queueMsg(ircmsgs.privmsg(self.registryValue('relaychannel'), "In %s, %s said: %s" % (msg.args[0], msg.nick, msg.args[1])))
lfd = open(logdir + '/botlogs/lock','a')
fcntl.lockf(lfd, fcntl.LOCK_EX)
fd = open(logdir + '/botlogs/%s.log' % datetime.date.today().strftime('%Y-%m-%d'),'a')
fd.write("%s %-20s %-16s %s\n" % (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), channel, msg.nick, msg.args[1]))
fd.close()
fcntl.lockf(lfd,fcntl.LOCK_UN)
lfd.close()
os.chmod(logdir + '/botlogs/%s.log' % datetime.date.today().strftime('%Y-%m-%d'),0644)
return
# All clear!
#irc.reply(str((name, value)))
####
# Find existing factoid
@ -281,6 +285,7 @@ class Encyclopedia(callbacks.Plugin):
irc.error("Unresolvable alias: %s" % alias)
return
# Finally, save
log("(%s) UPDATE facts SET value = %s WHERE name = %s" % (msg.prefix, f.value, f.name))
cur.execute("UPDATE facts SET value = %s WHERE name = %s", (f.value, f.name))
db.commit()
irc.reply("I'll remember that, %s" % msg.nick)
@ -339,8 +344,14 @@ class Encyclopedia(callbacks.Plugin):
if not i.startswith('Package'):
queue(irc, target, i)
else:
if len(text) > 16:
irc.error("I am only a bot, please don't think I'm intelligent :)")
return
irc.reply(self.registryValue('notfoundmsg') % text)
else:
if len(text) > 16:
irc.error("I am only a bot, please don't think I'm intelligent :)")
return
irc.reply(self.registryValue('notfoundmsg') % text)
for key in ('channel_secondary', 'global_secondary'):
if getattr(factoids, key):
@ -364,6 +375,8 @@ def send(irc, to, msg):
def addressed(recipients, text, irc):
if recipients[0] == '#':
text = text.strip()
if text.lower() == '!ubotu':
return 'ubotu'
if text[0] == '!':
text = text[1:]
if text.lower().startswith('ubotu') and (len(text) < 5 or not text[5].isalnum()):
@ -395,10 +408,10 @@ aptcommand = """apt-cache\\
%%s %%s""" % tuple([aptdir]*4)
aptfilecommand = """apt-file -s %s/%%s.list -c %s/apt-file/%%s -l -F search %%s""" % tuple([aptdir]*2)
def findpkg(pkg,checkdists,filelookup=True):
_pkg = ''.join([x for x in pkg.strip().split(None,1)[0] if x.isalnum or x in '.-_'])
_pkg = ''.join([x for x in pkg.strip().split(None,1)[0] if x.isalnum or x in '.-_+'])
distro = checkdists[0]
if len(pkg.strip().split()) > 1:
distro = ''.join([x for x in pkg.strip().split(None,2)[1] if x.isalnum or x in '.-_'])
distro = ''.join([x for x in pkg.strip().split(None,2)[1] if x.isalnum or x in '.-_+'])
if distro not in distros:
distro = checkdists[0]
pkg = _pkg
@ -420,10 +433,10 @@ def findpkg(pkg,checkdists,filelookup=True):
return "Found: %s" % ', '.join(pkgs[:5])
def pkginfo(pkg,checkdists):
_pkg = ''.join([x for x in pkg.strip().split(None,1)[0] if x.isalnum() or x in '.-_'])
_pkg = ''.join([x for x in pkg.strip().split(None,1)[0] if x.isalnum() or x in '.-_+'])
distro = None
if len(pkg.strip().split()) > 1:
distro = ''.join([x for x in pkg.strip().split(None,2)[1] if x.isalnum() or x in '-._'])
distro = ''.join([x for x in pkg.strip().split(None,2)[1] if x.isalnum() or x in '-._+'])
if distro:
if distro not in distros:
checkdists = [checkdists[0]]
@ -554,4 +567,8 @@ def capab(prefix, capability):
except:
pass
return False
def log(msg):
fd = open('/home/dennis/editlog','a')
fd.write('%s\n' % msg)
fd.close()
Class = Encyclopedia