import BaseHTTPServer import os import time import base64 import re import supybot.utils as utils import sqlite3 import collections import urllib host = 'http://domain.tld' port = 6666 username = 'login' password = 'password' filename = '/home/user/bot/data/networkname/ChanTracker.db' channels = ['#channelA','#channelb'] # empty to allows view of all channels recorded, otherwise restrict the views to channels # usage python server.py base64string = base64.encodestring('%s:%s' % (username,password))[:-1] def timeElapsed(elapsed, short=False, leadingZeroes=False, years=True, weeks=True, days=True, hours=True, minutes=True, seconds=True): """Given seconds, returns a string with an English description of how much time as passed. leadingZeroes determines whether 0 days, 0 hours, etc. will be printed; the others determine what larger time periods should be used. """ ret = [] def Format(s, i): if i or leadingZeroes or ret: if short: ret.append('%s%s' % (i, s[0])) else: ret.append(format('%n', (i, s))) elapsed = int(elapsed) assert years or weeks or days or \ hours or minutes or seconds, 'One flag must be True' if years: (yrs, elapsed) = (elapsed // 31536000, elapsed % 31536000) Format('year', yrs) if weeks: (wks, elapsed) = (elapsed // 604800, elapsed % 604800) Format('week', wks) if days: (ds, elapsed) = (elapsed // 86400, elapsed % 86400) Format('day', ds) if hours: (hrs, elapsed) = (elapsed // 3600, elapsed % 3600) Format('hour', hrs) if minutes or seconds: (mins, secs) = (elapsed // 60, elapsed % 60) if leadingZeroes or mins: Format('minute', mins) if seconds: leadingZeroes = True Format('second', secs) if not ret: raise ValueError, 'Time difference not great enough to be noted.' if short: return ' '.join(ret) else: return format('%L', ret) class MyHandler( BaseHTTPServer.BaseHTTPRequestHandler ): server_version= "Ircd-Seven/1.1" def do_GET( self ): self.page( self.path ) def page (self,query): h = '%s:%s/' % (host,port) if not query: return if query.startswith('/?username='): query = query.replace('/?','') a = query.split('&') u = p = None for item in a: aa = item.split('=') if aa[0] == 'username': u = aa[1] if aa[0] == 'password': p = aa[1] if u and p: raw = base64.encodestring('%s:%s' % (u,p))[:-1] if not raw == base64string: query = '' else: query = '/?hash=%s' % base64string if not query.startswith('/?hash='): body = '\n\nChanTracker\n' body += '\n' body += "\n\n" body += '
\n' % h body += '

Username:

\n' body += '

Password:

\n' body += '\n' body += "
\n" body += "\n\n" self.send_response(200) self.send_header("Content-type","text/html") self.send_header("Content-length",str(len(body))) self.end_headers() self.wfile.write(body) return if query.startswith('/?hash='): a = query.split('&')[0] a = a.replace('/?hash=','') query = query.replace('%3D','=') query = query.replace('/?hash=%s' % base64string,'/') q = '?hash=%s' % base64string query = urllib.unquote( query ) print query body = '\n\nBanTracker - %s\n' % query body += '\n' body += '\n' body += '\n' body += '\n\n' body += '
\n' body += '
\n' % q body += '
' body += '' % base64string body += '\n' body += '\n' body += '
\n' body += '
\n' db = self._getbandb() c = db.cursor() if query: ar = [] if query.startswith('/&id='): search = query.split('/&id=')[1] c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=? ORDER BY id DESC""",(search,)) if c.rowcount: ban = c.fetchall()[0] (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban if not len(channels) or channel in channels: body += '

#%s

\n' % id body += '

#%s by %s in %s : +%s : %s

\n' % (id,oper,channel,kind,mask) body += '

Begin at %s

\n' % time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(begin_at))) was = float(begin_at) == float(end_at) if was: was = 'forever' else: was = timeElapsed(float(end_at) - float(begin_at)) body += '

Original duration : %s

\n' % was if not removed_at: if was != 'forever': body += '

%s

\n' % 'It will expire in %s' % timeElapsed(float(end_at) - time.time()) else: body += '

%s

\n' % 'Removed after %s on %s by %s' % (timeElapsed(float(removed_at)-float(begin_at)),time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(removed_at))),removed_by) c.execute("""SELECT full, log FROM nicks WHERE ban_id=?""",(id,)) if c.rowcount: users = c.fetchall() body += '

Logs

\n' for u in users: (full,log) = u body += '

for %s

\n' % full if log != '': body +='\n' c.execute("""SELECT oper, at, comment FROM comments WHERE ban_id=?""",(id,)) if c.rowcount: body += '

Comments

\n' body += '\n' if query.startswith('/&channel='): search = '#'+query.split('/&channel=')[1] c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE channel=? ORDER BY id DESC""",(search,)) if c.rowcount: bans = c.fetchall() for ban in bans: (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban ar.append([int(id),channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by]) if query.startswith('/&removed_by='): search = query.split('/&removed_by=')[1] c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE removed_by=? ORDER BY id DESC""",(search,)) if c.rowcount: bans = c.fetchall() for ban in bans: (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban ar.append([int(id),channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by]) if query.startswith('/&oper='): search = query.split('/&oper=')[1] c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE oper=? ORDER BY id DESC""",(search,)) if c.rowcount: bans = c.fetchall() for ban in bans: (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban ar.append([int(id),channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by]) if query.startswith('/&mask='): search = query.split('/&mask=')[1] glob = '*%s*' % search like = '%'+search+'%' c.execute("""SELECT ban_id, full FROM nicks WHERE full GLOB ? OR full LIKE ? OR log GLOB ? OR log LIKE ? ORDER BY ban_id DESC""",(glob,like,glob,like)) L = [] a = {} if c.rowcount: bans = c.fetchall() d = {} for ban in bans: (id,full) = ban if not id in d: d[id] = id for id in d: c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=? ORDER BY id DESC""",(int(id),)) if c.rowcount: bans = c.fetchall() for ban in bans: (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban a[str(id)] = ban c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE mask GLOB ? OR mask LIKE ? ORDER BY id DESC""",(glob,like)) if c.rowcount: bans = c.fetchall() for ban in bans: (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban a[str(id)] = ban if len(a): ar = [] for ban in a: (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = a[ban] ar.append([int(id),channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by]) def sort_function (item): return item[0] ar.sort(key=sort_function) ar.sort(reverse=True) if query.startswith('/&search='): search = query.split('/&search=')[1] search = search.replace('+','*') print search if search: s = '*%s*' % search qu = '%'+search+'%' c.execute("""SELECT ban_id, full FROM nicks WHERE full GLOB ? OR full LIKE ? OR log GLOB ? OR log LIKE ? ORDER BY ban_id DESC""",(s,qu,s,qu)) L = [] a = {} if c.rowcount: bans = c.fetchall() d = {} for ban in bans: (id,full) = ban if not id in d: d[id] = id for id in d: c = db.cursor() c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=? ORDER BY id DESC""",(int(id),)) if c.rowcount: bans = c.fetchall() for ban in bans: (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban a[id] = ban c = db.cursor() c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE mask GLOB ? OR mask LIKE ? OR channel GLOB ? OR channel LIKE ? OR oper GLOB ? OR oper LIKE ? ORDER BY id DESC""",(s,qu,s,qu,s,qu)) if c.rowcount: bans = c.fetchall() for ban in bans: (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban a[id] = ban c = db.cursor() c.execute("""SELECT ban_id, comment FROM comments WHERE comment GLOB ? OR comment LIKE ? ORDER BY ban_id DESC""",(s,qu)) d = {} if c.rowcount: bans = c.fetchall() for ban in bans: (id,full) = ban d[id] = id for id in d: if not id in a: c = db.cursor() c.execute("""SELECT id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by FROM bans WHERE id=? ORDER BY id DESC""",(int(id),)) if c.rowcount: bans = c.fetchall() for ban in bans: (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ban a[id] = ban if len(a): ar = [] for ban in a: (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = a[ban] ar.append([int(id),channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by]) def sort_function (item): return item[0] ar.sort(key=sort_function) ar.sort(reverse=True) else: body += '

nothing found

\n' if len(ar): i = 0 body += '

results %s

' % search body += '\n' body += '\n' body += '\n' while i < len(ar): (id,channel,oper,kind,mask,begin_at,end_at,removed_at,removed_by) = ar[i] if not len(channels) or channel in channels: body += '\n' body += '\n' % (h,q,id,id) body += '\n' % (h,q,channel.split('#')[1],channel) body += '\n' % (h,q,urllib.urlencode({'oper':oper}),oper) body += '\n' % kind body += '\n' % (h,q,urllib.urlencode({'mask':mask}),mask) s = time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(begin_at))) body += '\n' % s if end_at and end_at != begin_at: s = time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(end_at))) body += '\n' % s else: body += '' if removed_at: s = time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(float(removed_at))) body += '' % s else: body += '\n' if removed_by: body += '\n' % (h,q,urllib.urlencode({'removed_by':removed_by}),removed_by) else: body += '\n' affected = '' try: c.execute("""SELECT full, log FROM nicks WHERE ban_id=?""",(id,)) affected = len(c.fetchall()) except: affected = '' body += '\n' % affected body += '\n' i = i+1 body += '\n' body += '
IDChannelOperatorKindTargetBegin dateEnd dateRemoved dateRemoved byaffected
%s%s%s+%s%s%s%s%s%s%s
\n' c.close() body += "" self.send_response(200) self.send_header("Content-type","text/html") self.send_header("Content-length",str(len(body))) self.end_headers() self.wfile.write(body) def _getbandb (self): if os.path.exists(filename): db = sqlite3.connect(filename,timeout=10) db.text_factory = str return db db = sqlite3.connect(filename) db.text_factory = str c = db.cursor() c.execute("""CREATE TABLE bans ( id INTEGER PRIMARY KEY, channel VARCHAR(100) NOT NULL, oper VARCHAR(1000) NOT NULL, kind VARCHAR(1) NOT NULL, mask VARCHAR(1000) NOT NULL, begin_at TIMESTAMP NOT NULL, end_at TIMESTAMP NOT NULL, removed_at TIMESTAMP, removed_by VARCHAR(1000) )""") c.execute("""CREATE TABLE nicks ( ban_id INTEGER, ban VARCHAR(1000) NOT NULL, full VARCHAR(1000) NOT NULL, log TEXT NOT NULL )""") c.execute("""CREATE TABLE comments ( ban_id INTEGER, oper VARCHAR(1000) NOT NULL, at TIMESTAMP NOT NULL, comment TEXT NOT NULL )""") db.commit() return db def httpd(handler_class=MyHandler, server_address = ('', port), ): srvr = BaseHTTPServer.HTTPServer(server_address, handler_class) srvr.serve_forever() if __name__ == "__main__": httpd( )