2010-05-19 13:11:16 +00:00
|
|
|
#!/usr/bin/env python
|
2006-10-19 14:39:11 +00:00
|
|
|
###
|
2007-01-23 23:42:45 +00:00
|
|
|
# Copyright (c) 2005-2007 Dennis Kaarsemaker
|
2006-10-19 14:39:11 +00:00
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of version 2 of the GNU General Public License as
|
|
|
|
# published by the Free Software Foundation.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
###
|
|
|
|
|
2011-11-06 12:52:17 +00:00
|
|
|
import os
|
2006-06-26 17:57:20 +00:00
|
|
|
import sys
|
2011-11-05 23:33:33 +00:00
|
|
|
import time
|
2011-11-07 01:36:36 +00:00
|
|
|
import urllib
|
2008-05-05 11:34:57 +00:00
|
|
|
# This needs to be set to the location of the commoncgi.py file
|
2009-10-12 18:26:35 +00:00
|
|
|
sys.path.append('/var/www/bot')
|
2006-06-26 17:57:20 +00:00
|
|
|
from commoncgi import *
|
|
|
|
|
|
|
|
### Variables
|
2011-11-06 12:52:17 +00:00
|
|
|
db = '/home/bot/data/bans.db'
|
2006-06-26 17:57:20 +00:00
|
|
|
num_per_page = 100
|
2011-11-06 12:52:17 +00:00
|
|
|
pagename = os.path.basename(sys.argv[0])
|
2011-11-06 23:11:13 +00:00
|
|
|
disable_anonymous = False # Set this to True to disable anonymous access
|
2008-08-04 10:11:15 +00:00
|
|
|
|
2011-11-05 23:33:33 +00:00
|
|
|
t1 = time.time()
|
|
|
|
|
2006-06-26 17:57:20 +00:00
|
|
|
con = sqlite.connect(db)
|
|
|
|
cur = con.cursor()
|
|
|
|
|
|
|
|
# Login check
|
2011-11-06 23:11:13 +00:00
|
|
|
error = ''
|
2007-02-15 22:16:44 +00:00
|
|
|
user = None
|
2006-06-26 17:57:20 +00:00
|
|
|
|
|
|
|
# Delete old sessions
|
2008-05-05 11:34:57 +00:00
|
|
|
try:
|
2011-05-28 06:33:21 +00:00
|
|
|
session_timeout = int(time.time()) - (2592000 * 3)
|
|
|
|
cur.execute('DELETE FROM sessions WHERE time < %d', (session_timeout,))
|
2008-05-05 11:34:57 +00:00
|
|
|
except:
|
2009-10-12 18:26:35 +00:00
|
|
|
pass
|
2006-06-26 17:57:20 +00:00
|
|
|
|
|
|
|
# Session handling
|
2007-02-15 22:16:44 +00:00
|
|
|
if form.has_key('sess'):
|
|
|
|
cookie['sess'] = form['sess'].value
|
2006-06-26 17:57:20 +00:00
|
|
|
if cookie.has_key('sess'):
|
2011-11-06 23:11:13 +00:00
|
|
|
sess = cookie['sess'].value
|
2006-06-26 17:57:20 +00:00
|
|
|
try:
|
2011-05-28 06:33:21 +00:00
|
|
|
cur.execute('SELECT user FROM sessions WHERE session_id=%s',(sess,))
|
2006-06-26 17:57:20 +00:00
|
|
|
user = cur.fetchall()[0][0]
|
|
|
|
except:
|
|
|
|
con.commit()
|
|
|
|
pass
|
|
|
|
|
2011-11-06 23:11:13 +00:00
|
|
|
if not user and disable_anonymous:
|
|
|
|
print "Sorry, bantracker is not available for anonymous users<br />"
|
2008-11-02 01:29:06 +00:00
|
|
|
print "Join <a href=irc://irc.freenode.net/ubuntu-ops>#ubuntu-ops</a> on irc.freenode.net to discuss bans"
|
2007-10-02 21:05:48 +00:00
|
|
|
send_page('bans.tmpl')
|
2011-11-06 23:11:13 +00:00
|
|
|
sys.exit(0)
|
2007-10-02 21:05:48 +00:00
|
|
|
|
2011-11-07 01:36:36 +00:00
|
|
|
def urlencode(**kwargs):
|
|
|
|
"""Return the url options as a string, inserting additional ones if given."""
|
|
|
|
d = dict([ (i.name, i.value) for i in form.list ])
|
|
|
|
d.update(kwargs)
|
|
|
|
return urllib.urlencode(d.items())
|
|
|
|
|
2006-06-26 17:57:20 +00:00
|
|
|
# Log
|
|
|
|
if form.has_key('log'):
|
2011-11-06 23:11:13 +00:00
|
|
|
log_id = form['log'].value
|
|
|
|
plain = False
|
|
|
|
mark = False
|
|
|
|
mark_value = ''
|
|
|
|
regex = False
|
|
|
|
regex_value = ''
|
|
|
|
|
|
|
|
if form.has_key('plain') and form['plain'].value.lower() in ('1', 'true', 'on'):
|
|
|
|
plain = True
|
|
|
|
|
|
|
|
if form.has_key('mark'):
|
|
|
|
mark = True
|
|
|
|
mark_value = form['mark'].value
|
|
|
|
if form.has_key('regex') and form['regex'].value in ('1', 'true', 'on'):
|
|
|
|
regex = True
|
|
|
|
regex_value = 'checked="checked"'
|
|
|
|
|
|
|
|
con = sqlite.connect(db)
|
|
|
|
cur = con.cursor()
|
|
|
|
cur.execute("SELECT log FROM bans WHERE id=%s", log_id)
|
|
|
|
log = cur.fetchall()
|
|
|
|
con.commit()
|
|
|
|
con.close()
|
|
|
|
|
|
|
|
if not log or not log[0] or not log[0][0]:
|
|
|
|
if plain:
|
|
|
|
print >> sys.stderr, '<div id="error">No such log with ID: %s' % q(log_id)
|
|
|
|
send_page('empty.tmpl')
|
|
|
|
else:
|
|
|
|
print >> sys.stderr, 'No such log with ID: %s' % q(log_id)
|
|
|
|
send_page('log.tmpl')
|
|
|
|
|
|
|
|
log = log[0][0]
|
|
|
|
|
|
|
|
if not plain:
|
|
|
|
print ' <div class="main">'
|
|
|
|
print ' <form id="hform" action="%s" method="get">' % pagename
|
|
|
|
print ' <fieldset>'
|
|
|
|
print ' <input type="hidden" name="log" id="log" value="%s">' % q(log_id)
|
|
|
|
print ' <label for="mark">Highlight:</label>'
|
|
|
|
print ' <input type="text" name="mark" id="mark" value="%s"/>' % q(mark_value)
|
|
|
|
print ' <input type="checkbox" name="regex" id="regex" %s>' % regex_value
|
|
|
|
print ' <label for="regex">Regex</label>'
|
|
|
|
print ' </fieldset>'
|
|
|
|
print ' <input class="input" type="submit" id="hform_submit" value="Update">'
|
|
|
|
print ' </form>'
|
|
|
|
print ' </div>'
|
|
|
|
|
|
|
|
pad = '<br />'
|
|
|
|
if plain:
|
|
|
|
pad = ''
|
|
|
|
print '<pre id="textlog">'
|
|
|
|
else:
|
|
|
|
print '<div id="textlog">'
|
|
|
|
|
|
|
|
if mark:
|
|
|
|
if regex:
|
|
|
|
mark = re.compile(mark_value, re.I)
|
|
|
|
else:
|
|
|
|
escaped = re.escape(mark_value).replace('%', '.*')
|
|
|
|
mark = re.compile(escaped, re.I)
|
|
|
|
|
|
|
|
lines = log.splitlines()
|
|
|
|
for line in lines:
|
|
|
|
if plain:
|
|
|
|
print q(line)
|
|
|
|
elif mark:
|
|
|
|
if mark.search(line):
|
|
|
|
print ' <span class="highlight">%s</span>%s' % (q(line), pad)
|
|
|
|
else:
|
|
|
|
print " <span>%s</span>%s" % (q(line), pad)
|
|
|
|
else:
|
|
|
|
print ' <span>%s</span>%s' % (q(line), pad)
|
|
|
|
|
|
|
|
if plain:
|
|
|
|
print '</pre>'
|
|
|
|
send_page('empty.tmpl')
|
|
|
|
|
|
|
|
print '</div><br />'
|
|
|
|
print '<div>'
|
|
|
|
print ' <form id="comment_form" action="%s" method="post">' % pagename
|
|
|
|
print ' <fieldset>'
|
|
|
|
print ' <legend>Add a comment</legend>'
|
|
|
|
print ' <textarea cols="50" rows="5" class="input" name="comment"></textarea><br />'
|
|
|
|
print ' <input type="hidden" name="comment_id" value="%s" />' % log_id
|
|
|
|
print ' <input class="submit" type="submit" value="Send" />'
|
|
|
|
print ' </fieldset>'
|
|
|
|
print ' </form>'
|
|
|
|
print '</div>'
|
|
|
|
|
|
|
|
send_page('log.tmpl')
|
2006-06-26 17:57:20 +00:00
|
|
|
|
|
|
|
# Main page
|
|
|
|
# Process comments
|
2007-02-15 22:16:44 +00:00
|
|
|
if form.has_key('comment') and form.has_key('comment_id') and user:
|
2011-05-28 06:33:21 +00:00
|
|
|
cur.execute('SELECT ban_id FROM comments WHERE ban_id=%s and comment=%s', (form['comment_id'].value, form['comment'].value))
|
2006-06-26 17:57:20 +00:00
|
|
|
comm = cur.fetchall()
|
|
|
|
if not len(comm):
|
2011-05-28 06:33:21 +00:00
|
|
|
cur.execute('INSERT INTO comments (ban_id, who, comment, time) VALUES (%s, %s, %s, %s)',
|
2007-02-15 22:16:44 +00:00
|
|
|
(form['comment_id'].value,user,form['comment'].value,pickle.dumps(datetime.datetime.now(pytz.UTC))))
|
2009-10-12 18:26:35 +00:00
|
|
|
con.commit()
|
2006-06-26 17:57:20 +00:00
|
|
|
|
|
|
|
# Write the page
|
2011-11-06 12:52:17 +00:00
|
|
|
print '<form action="%s" method="POST">' % pagename
|
2006-06-26 17:57:20 +00:00
|
|
|
|
|
|
|
# Personal data
|
2006-12-27 14:33:59 +00:00
|
|
|
print '<div class="pdata">'
|
2007-02-15 22:16:44 +00:00
|
|
|
if user:
|
|
|
|
print 'Logged in as: %s <br /> ' % user
|
|
|
|
|
2006-12-27 14:33:59 +00:00
|
|
|
print 'Timezone: '
|
2006-06-26 17:57:20 +00:00
|
|
|
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:
|
|
|
|
tz = cookie['tz'].value
|
|
|
|
else:
|
|
|
|
tz = 'UTC'
|
|
|
|
cookie['tz'] = tz
|
|
|
|
print '<select class="input" name="tz">'
|
|
|
|
for zone in pytz.common_timezones:
|
|
|
|
if zone == tz:
|
2011-11-06 23:11:13 +00:00
|
|
|
print '<option value="%s" selected="selected">%s</option>' % (zone, zone)
|
|
|
|
else:
|
|
|
|
print '<option value="%s">%s</option>' % (zone, zone)
|
|
|
|
print '</select>'
|
|
|
|
print '<input class="submit" type="submit" value="change" />'
|
|
|
|
print '</form><br />'
|
2006-12-27 14:33:59 +00:00
|
|
|
print '</div>'
|
2006-08-18 23:22:54 +00:00
|
|
|
|
2006-06-26 17:57:20 +00:00
|
|
|
tz = pytz.timezone(tz)
|
|
|
|
|
2011-11-06 23:11:13 +00:00
|
|
|
haveQuery = form.has_key('query') or form.has_key('channel') or form.has_key('operator')
|
|
|
|
|
|
|
|
def isOn(k):
|
|
|
|
default = not haveQuery
|
|
|
|
if not form.has_key(k):
|
|
|
|
return default
|
|
|
|
if form[k].value.lower() in ('on', '1', 'true', 'yes'):
|
|
|
|
return True
|
|
|
|
if form[k].value.lower() in ('off', '0', 'false', 'no'):
|
|
|
|
return False
|
|
|
|
return default
|
|
|
|
|
|
|
|
def makeInput(name, label, before=False, type="checkbox", extra=''):
|
|
|
|
if before:
|
|
|
|
print '<label for="%s">%s</label>' % (name, label)
|
|
|
|
value = ''
|
|
|
|
if type == "checkbox":
|
|
|
|
if isOn(name):
|
|
|
|
value = ' checked="checked"'
|
|
|
|
else:
|
|
|
|
if form.has_key(name):
|
|
|
|
value = ' value="%s"' % form[name].value,
|
|
|
|
|
|
|
|
print '<input class="input" type="%s" name="%s" id="%s"%s /> %s' \
|
|
|
|
% (type, name, name, value, extra)
|
|
|
|
if not before:
|
|
|
|
print '<label for="%s">%s</label>' % (name, label)
|
|
|
|
print '<br />'
|
|
|
|
|
2006-06-26 17:57:20 +00:00
|
|
|
# Search form
|
|
|
|
print '<div class="search">'
|
2011-11-06 12:52:17 +00:00
|
|
|
print '<form action="%s" method="GET">' % pagename
|
2011-11-06 23:11:13 +00:00
|
|
|
makeInput("channel", "Channel:", True, "text")
|
|
|
|
makeInput("operator", "Operator:", True, "text")
|
|
|
|
makeInput("query", "Search:", True, "text", extra="(% and _ are wildcards)")
|
2006-06-26 17:57:20 +00:00
|
|
|
|
|
|
|
# Search fields
|
|
|
|
print '<div style="float:left">'
|
2011-11-06 23:11:13 +00:00
|
|
|
makeInput("kicks", "Kicks")
|
|
|
|
makeInput("bans", "Bans")
|
|
|
|
makeInput("oldbans", "Removed bans")
|
2006-06-26 17:57:20 +00:00
|
|
|
print '</div>'
|
|
|
|
|
|
|
|
print '<div style="float:left">'
|
2011-11-06 23:11:13 +00:00
|
|
|
makeInput("mutes", "Include mutes")
|
|
|
|
makeInput("floodbots", "Include Floodbots")
|
2006-06-26 17:57:20 +00:00
|
|
|
print '</div>'
|
|
|
|
|
|
|
|
print '<div style="clear:both"><input class="submit" type="submit" value="search" /></div>'
|
|
|
|
print '</form></div>'
|
|
|
|
|
|
|
|
# Select and filter bans
|
2011-11-06 23:11:13 +00:00
|
|
|
def getBans(id=None, mask=None, kicks=True, oldbans=True, bans=True, floodbots=True, operator=None,
|
2011-11-07 01:36:36 +00:00
|
|
|
channel=None, limit=None, offset=0, withCount=False):
|
2011-11-05 23:33:33 +00:00
|
|
|
sql = "SELECT channel, mask, operator, time, removal, removal_op, id FROM bans"
|
|
|
|
args = []
|
|
|
|
where = []
|
|
|
|
if id:
|
|
|
|
where.append("id = %s")
|
|
|
|
args.append(id)
|
|
|
|
if mask:
|
|
|
|
where.append("mask LIKE %s")
|
|
|
|
args.append('%' + mask + '%')
|
2011-11-06 23:11:13 +00:00
|
|
|
if not floodbots:
|
2011-11-05 23:33:33 +00:00
|
|
|
where.append("operator NOT LIKE 'floodbot%%'")
|
|
|
|
if operator:
|
|
|
|
where.append("operator LIKE %s")
|
2011-11-06 12:44:53 +00:00
|
|
|
args.append(operator)
|
2011-11-05 23:33:33 +00:00
|
|
|
if channel:
|
|
|
|
where.append("channel LIKE %s")
|
|
|
|
args.append(channel)
|
|
|
|
if not kicks:
|
|
|
|
where.append("mask LIKE '%%!%%'")
|
|
|
|
if not (oldbans or bans):
|
|
|
|
where.append("mask NOT LIKE '%%!%%'")
|
2009-12-11 17:53:15 +00:00
|
|
|
else:
|
2011-11-05 23:33:33 +00:00
|
|
|
if kicks:
|
|
|
|
s = "(mask NOT LIKE '%%%%!%%%%' OR (mask LIKE '%%%%!%%%%' AND %s))"
|
|
|
|
else:
|
|
|
|
s = "%s"
|
|
|
|
if not oldbans:
|
|
|
|
where.append(s % "removal IS NULL")
|
|
|
|
elif not bans:
|
|
|
|
where.append(s % "removal IS NOT NULL")
|
2011-11-07 01:36:36 +00:00
|
|
|
if where:
|
|
|
|
where = " WHERE " + " AND ".join(where)
|
|
|
|
else:
|
|
|
|
where = ''
|
|
|
|
sql += where
|
2011-11-05 23:33:33 +00:00
|
|
|
sql += " ORDER BY id DESC"
|
2011-11-07 01:36:36 +00:00
|
|
|
if limit:
|
|
|
|
sql += " LIMIT %s OFFSET %s" % (limit, offset)
|
|
|
|
#print sql, "<br/>"
|
|
|
|
#print sql_count, "<br/>"
|
|
|
|
#print args, "<br/>"
|
2011-11-07 21:27:28 +00:00
|
|
|
# Things seems faster if we do the query BEFORE counting. Due to caches probably.
|
2011-11-07 01:36:36 +00:00
|
|
|
cur.execute(sql, args)
|
|
|
|
bans = cur.fetchall()
|
2011-11-07 21:27:28 +00:00
|
|
|
count = None
|
2011-11-07 01:36:36 +00:00
|
|
|
if withCount:
|
2011-11-07 21:27:28 +00:00
|
|
|
sql_count = "SELECT count(*) FROM bans%s" % where
|
|
|
|
cur.execute(sql_count, args)
|
|
|
|
count = int(cur.fetchone()[0])
|
2011-11-07 01:36:36 +00:00
|
|
|
return bans, count
|
|
|
|
return bans
|
2008-09-28 02:11:49 +00:00
|
|
|
|
2011-11-06 12:44:53 +00:00
|
|
|
def filterMutes(item):
|
2008-08-04 10:11:15 +00:00
|
|
|
if item[1][0] == '%':
|
2011-11-06 12:44:53 +00:00
|
|
|
return False
|
|
|
|
return True
|
2008-09-28 02:11:49 +00:00
|
|
|
|
|
|
|
def getQueryTerm(query, term):
|
|
|
|
if term[-1] != ':':
|
|
|
|
term += ':'
|
|
|
|
if term in query:
|
|
|
|
idx = query.index(term) + len(term)
|
|
|
|
ret = query[idx:].split(None, 1)[0]
|
|
|
|
query = query.replace(term + ret, '', 1).strip()
|
|
|
|
return (query, ret)
|
|
|
|
return (query, None)
|
2006-06-26 17:57:20 +00:00
|
|
|
|
2011-11-07 01:36:36 +00:00
|
|
|
page = 0
|
|
|
|
if form.has_key('page'):
|
|
|
|
page = int(form['page'].value)
|
2011-11-06 12:52:17 +00:00
|
|
|
|
2009-12-11 17:53:15 +00:00
|
|
|
bans = []
|
2011-11-07 01:36:36 +00:00
|
|
|
ban_count = 0
|
|
|
|
query = oper = chan = None
|
2006-06-26 17:57:20 +00:00
|
|
|
if form.has_key('query'):
|
2011-11-05 23:33:33 +00:00
|
|
|
query = form['query'].value
|
2011-11-07 01:36:36 +00:00
|
|
|
|
|
|
|
if query and query.isdigit():
|
|
|
|
bans = getBans(id=int(query))
|
|
|
|
ban_count = len(bans)
|
|
|
|
|
|
|
|
if not bans:
|
|
|
|
if form.has_key('channel'):
|
|
|
|
chan = form['channel'].value
|
|
|
|
if form.has_key('operator'):
|
|
|
|
oper = form['operator'].value
|
|
|
|
bans, ban_count = getBans(mask=query, kicks=isOn('kicks'),
|
|
|
|
oldbans=isOn('oldbans'),
|
|
|
|
bans=isOn('bans'),
|
|
|
|
floodbots=isOn('floodbots'),
|
|
|
|
operator=oper,
|
|
|
|
channel=chan,
|
|
|
|
limit=num_per_page,
|
|
|
|
offset=num_per_page * page,
|
|
|
|
withCount=True)
|
|
|
|
|
2011-11-07 21:27:28 +00:00
|
|
|
if not isOn('mutes'):
|
2011-11-07 01:36:36 +00:00
|
|
|
bans = filter(lambda x: filterMutes(x), bans)
|
2006-06-26 17:57:20 +00:00
|
|
|
|
2011-11-07 21:27:28 +00:00
|
|
|
|
2006-06-26 17:57:20 +00:00
|
|
|
# Sort the bans
|
|
|
|
def _sortf(x1,x2,field):
|
|
|
|
if x1[field] < x2[field]: return -1
|
|
|
|
if x1[field] > x2[field]: return 1
|
|
|
|
return 0
|
|
|
|
|
|
|
|
if form.has_key('sort'):
|
|
|
|
try:
|
|
|
|
field = int(form['sort'].value)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
if field in (0,1,2,6,10,11,12,16):
|
|
|
|
bans.sort(lambda x1,x2: _sortf(x1,x2,field%10))
|
|
|
|
if field >= 10:
|
|
|
|
bans.reverse()
|
|
|
|
|
2011-11-07 01:36:36 +00:00
|
|
|
if 'query' in form or 'operator' in form or 'channel' in form:
|
|
|
|
if not ban_count:
|
|
|
|
print '<div style="clear: both">Nothing found.</div>'
|
|
|
|
elif ban_count == 1:
|
|
|
|
print '<div style="clear: both">Found one match.</div>'
|
|
|
|
else:
|
|
|
|
print '<div style="clear: both">Found %s matches.</div>' % ban_count
|
|
|
|
|
|
|
|
# Pagination
|
|
|
|
if bans:
|
|
|
|
print '<div style="clear: both">'
|
|
|
|
print '·'
|
|
|
|
num_pages = int(math.ceil(ban_count / float(num_per_page)))
|
|
|
|
for i in range(num_pages):
|
|
|
|
print '<a href="%s?%s">%d</a> ·' % (pagename, urlencode(page=i), i + 1)
|
|
|
|
print '</div>'
|
|
|
|
else:
|
|
|
|
# nothign to show
|
|
|
|
print '<div style="clear: both"></div>' # if I don't print this the page is messed up.
|
|
|
|
send_page('bans.tmpl')
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
|
|
# Empty log div, will be filled with AJAX
|
|
|
|
print '<div id="log" class="log"> </div>'
|
|
|
|
|
|
|
|
# Main bans table
|
|
|
|
# Table heading
|
|
|
|
print '<div>'
|
|
|
|
print '<table cellspacing="0">'
|
|
|
|
print '<thead>'
|
|
|
|
print '<tr>'
|
2011-11-07 21:27:28 +00:00
|
|
|
for h in [ ('Channel', 0, 45),
|
|
|
|
('Nick/Mask', 1, 25),
|
|
|
|
('Operator', 2, 0),
|
|
|
|
('Time', 6, 15) ]:
|
2011-11-07 01:36:36 +00:00
|
|
|
# Negative integers for backwards searching
|
|
|
|
try:
|
|
|
|
v = int(form['sort'].value)
|
|
|
|
if v < 10: h[1] += 10
|
|
|
|
except:
|
|
|
|
pass
|
2011-11-07 21:27:28 +00:00
|
|
|
#print '<th style="width: %s%%"><a href="%s?sort=%s">%s</a></th>' % (h[2], pagename, h[1], h[0])
|
|
|
|
print '<th style="width: %s%%">%s</th>' % (h[2], h[0])
|
2011-11-07 01:36:36 +00:00
|
|
|
print '<th style="width: 15%">Log</th>'
|
|
|
|
print '<th>ID</th>'
|
|
|
|
print '</tr>'
|
|
|
|
print '</thead>'
|
|
|
|
print '<tbody>'
|
|
|
|
|
2006-06-26 17:57:20 +00:00
|
|
|
# And finally, display them!
|
|
|
|
i = 0
|
2011-11-07 01:36:36 +00:00
|
|
|
for b in bans:
|
2006-06-26 17:57:20 +00:00
|
|
|
if i % 2:
|
2011-11-06 23:11:13 +00:00
|
|
|
print '<tr class="bg2">'
|
|
|
|
else:
|
|
|
|
print "<tr>"
|
2006-06-26 17:57:20 +00:00
|
|
|
# Channel
|
2011-11-06 23:11:13 +00:00
|
|
|
print '<td id="channel-%d">%s %s</td>' % (b[6],'',b[0])
|
2006-06-26 17:57:20 +00:00
|
|
|
# Mask
|
2011-11-06 23:11:13 +00:00
|
|
|
print '<td id="mask-%d">%s' % (b[6], b[1])
|
2006-06-26 17:57:20 +00:00
|
|
|
# Ban removal
|
|
|
|
if b[4]:
|
|
|
|
print '<br /><span class="removal">(Removed)</span>'
|
|
|
|
print'</td>'
|
|
|
|
# Operator
|
2011-11-06 23:11:13 +00:00
|
|
|
print '<td id="operator-%d">%s' % (b[6], b[2])
|
2006-06-26 17:57:20 +00:00
|
|
|
if b[4]: # Ban removal
|
2006-07-02 09:40:22 +00:00
|
|
|
print u'<br /><span class="removal">%s</span>' % b[5]
|
2006-06-26 17:57:20 +00:00
|
|
|
print '</td>'
|
|
|
|
# Time
|
2011-11-06 23:11:13 +00:00
|
|
|
print '<td id="time-%d">%s' % (b[6], pickle.loads(b[3]).astimezone(tz).strftime("%b %d %Y %H:%M:%S"))
|
2006-06-26 17:57:20 +00:00
|
|
|
if b[4]: # Ban removal
|
|
|
|
print '<br /><span class="removal">%s</span>' % pickle.loads(b[4]).astimezone(tz).strftime("%b %d %Y %H:%M:%S")
|
|
|
|
print '</td>'
|
|
|
|
# Log link
|
2011-11-06 23:11:13 +00:00
|
|
|
print """<td>
|
|
|
|
Show log <a class="pseudolink" id="loglink-%s" onclick="showlog('%s')">inline</a>
|
|
|
|
| <a href="%s?log=%d">full</a>
|
|
|
|
</td>""" % (b[6], b[6], pagename, b[6])
|
|
|
|
|
|
|
|
# ID
|
|
|
|
print '<td id="id-%d">%d</td>' % (b[6], b[6])
|
|
|
|
print "</tr>"
|
2006-06-26 17:57:20 +00:00
|
|
|
|
|
|
|
# Comments
|
2011-11-06 23:11:13 +00:00
|
|
|
if i % 2:
|
|
|
|
print '<tr class="bg2">'
|
|
|
|
else:
|
|
|
|
print "<tr>"
|
2011-05-28 06:33:21 +00:00
|
|
|
cur.execute('SELECT who, comment, time FROM comments WHERE ban_id = %d', (b[6],))
|
2006-06-26 17:57:20 +00:00
|
|
|
comments = cur.fetchall()
|
|
|
|
if len(comments) == 0:
|
2011-11-06 23:11:13 +00:00
|
|
|
print '<td colspan="5" class="comment">'
|
|
|
|
print '<div class="invisible" id="comments">%d</div>' % b[6]
|
2006-06-26 17:57:20 +00:00
|
|
|
print '<span class="removal">(No comments) </span>'
|
|
|
|
else:
|
2011-11-06 23:11:13 +00:00
|
|
|
print '<td colspan="5" class="comment" id="comments-%d">' % b[6]
|
|
|
|
print '<div class="invisible" id="comments">%d</div>' % b[6]
|
2006-06-26 17:57:20 +00:00
|
|
|
for c in comments:
|
2011-11-06 23:11:13 +00:00
|
|
|
print q(c[1]).replace('\n', '<br />')
|
2006-07-02 09:40:22 +00:00
|
|
|
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"))
|
2007-02-15 22:16:44 +00:00
|
|
|
if user:
|
2009-10-12 18:26:35 +00:00
|
|
|
print """<span class="pseudolink" onclick="toggle('%s','comment')">Add comment</span>""" % b[6]
|
|
|
|
print """<div class="invisible" id="comment_%s"><br />""" % b[6]
|
2011-11-06 23:11:13 +00:00
|
|
|
print """ <form action="%s" method="POST">""" % pagename
|
|
|
|
print """ <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" />"""
|
|
|
|
print """ </form>"""
|
|
|
|
print """</div>"""
|
|
|
|
print '</td><td></td></tr>'
|
|
|
|
i += 1
|
2006-06-26 17:57:20 +00:00
|
|
|
|
2011-11-07 21:27:28 +00:00
|
|
|
|
2006-06-26 17:57:20 +00:00
|
|
|
print '</table>'
|
2009-10-12 18:26:35 +00:00
|
|
|
|
2011-11-05 23:33:33 +00:00
|
|
|
t2 = time.time()
|
|
|
|
|
|
|
|
print "Generated in %.4f seconds<br/>" % (t2 - t1)
|
2006-06-26 17:57:20 +00:00
|
|
|
|
|
|
|
# Aaaaaaaaaaaaaaaaand send!
|
|
|
|
send_page('bans.tmpl')
|