save ban autoremoval information in a csv files, so it isn't lost during plugin reloads.

This commit is contained in:
Elián Hanisch 2012-07-05 02:31:53 -03:00
parent e3f6aacdf5
commit e3dd878cf3
2 changed files with 77 additions and 4 deletions

View File

@ -58,6 +58,7 @@ import sqlite
import pytz
import cPickle
import datetime
import csv
import time
import random
import hashlib
@ -255,6 +256,23 @@ class Ban(object):
return 'ban'
return 'removal'
def serialize(self):
id = self.id
if id is None:
id = ''
return (id, self.channel, self.mask, self.who, self.when)
def deserialize(self, L):
id = L[0]
if id == '':
id = None
else:
id = int(id)
self.id = id
self.channel, self.mask, self.who = L[1:4]
self.when = float(L[4])
self.ascwhen = time.asctime(time.gmtime(self.when))
class ReviewStore(dict):
def __init__(self, filename):
@ -317,8 +335,6 @@ class BanRemoval(object):
ban: ban object
expires: time in seconds for it to expire
"""
assert isinstance(ban, Ban), "ban is not a Ban object"
assert isinstance(expires, int), "expire time isn't an integer"
self.ban = ban
self.expires = expires
self.notified = False
@ -329,10 +345,22 @@ class BanRemoval(object):
return True
return False
def serialize(self):
notified = self.notified and 1 or 0
L = [ self.expires, notified ]
L.extend(self.ban.serialize())
return tuple(L)
def deserialize(self, L):
self.expires = int(L[0])
self.notified = bool(int(L[1]))
self.ban = Ban(args=(None, None, None, None, 0))
self.ban.deserialize(L[2:])
class BanStore(object):
def __init__(self, filename):
# this should be stored into a file
self.filename = conf.supybot.directories.data.dirize(filename)
self.shelf = []
def __iter__(self):
@ -341,6 +369,26 @@ class BanStore(object):
def __len__(self):
return len(self.shelf)
def open(self):
try:
reader = csv.reader(open(self.filename, 'rb'))
except IOError:
return
for row in reader:
ban = BanRemoval(None, None)
ban.deserialize(row)
self.add(ban)
def close(self):
try:
writer = csv.writer(open(self.filename, 'wb'))
except IOError:
return
for ban in self:
writer.writerow(ban.serialize())
def add(self, obj):
self.shelf.append(obj)
@ -408,7 +456,8 @@ class Bantracker(callbacks.Plugin):
self._banreviewfix()
# init autoremove stuff
self.managedBans = BanStore('FIXME')
self.managedBans = BanStore('bt.autoremove.db')
self.managedBans.open()
# add our scheduled events for check bans for reviews or removal
schedule.addPeriodicEvent(lambda: self.reviewBans(irc), 60*60,
@ -545,6 +594,7 @@ class Bantracker(callbacks.Plugin):
schedule.removeEvent(self.name() + '_review')
schedule.removeEvent(self.name() + '_autoremove')
self.pendingReviews.close()
self.managedBans.close()
def reset(self):
global queue

View File

@ -406,5 +406,28 @@ class BantrackerTestCase(ChannelPluginTestCase):
finally:
del pluginConf.autoremove.notify.channels()[:]
def testAutoremoveStore(self):
self.feedBan('asd!*@*')
self.feedBan('qwe!*@*')
self.feedBan('zxc!*@*', mode='q')
self.assertNotError('banremove 1 10m')
self.assertNotError('banremove 2 1d')
self.assertNotError('banremove 3 1w')
cb = self.getCallback()
cb.managedBans.shelf[1].notified = True
cb.managedBans.close()
cb.managedBans.shelf = []
cb.managedBans.open()
L = cb.managedBans.shelf
for i, n in enumerate((600, 86400, 604800)):
self.assertEqual(L[i].expires, n)
for i, n in enumerate((False, True, False)):
self.assertEqual(L[i].notified, n)
for i, n in enumerate((1, 2, 3)):
self.assertEqual(L[i].ban.id, n)
for i, n in enumerate(('asd!*@*', 'qwe!*@*', '%zxc!*@*')):
self.assertEqual(L[i].ban.mask, n)
self.assertEqual(L[0].ban.channel, '#test')