SQLite backend

darcs-hash:20060129173720-86b55-cb365b2e6e6c652e885d88594e0e5c36deebf364.gz
This commit is contained in:
David Rousselie
2006-01-29 18:37:20 +01:00
parent 06fd569537
commit 7d78e0d892
5 changed files with 188 additions and 88 deletions

5
TODO
View File

@@ -1,8 +1,3 @@
* i18n support in the same way as ejabberd and
PyMSNt, PyICQ-t and PyAIM-t: using xml:lang, but have an option in
the config to set the default language to show, when the client do
not support xml:lang.i18n support (use xml:lang + default)
* Database backend (default SQLLite)
* Support for attachements with size limit and file format limit

View File

@@ -221,9 +221,6 @@ class MailConnection(object):
def format_message_summary(self, email_msg):
return self.format_message(email_msg, False)
def get_type(self):
return "UNKNOWN"
def get_status_msg(self):
return self.get_type() + "://" + self.login + "@" + self.host + ":" + \
unicode(self.port)
@@ -324,6 +321,8 @@ class IMAPConnection(MailConnection):
return self.format_message_summary(email.message_from_string(data[0][1]))
return u"Error while fetching mail " + str(index)
type = property(get_type)
class POP3Connection(MailConnection):
def __init__(self, login = "", password = "", host = "", \
port = None, ssl = False):
@@ -377,3 +376,5 @@ class POP3Connection(MailConnection):
if ret[0:3] == '+OK':
return self.format_message_summary(email.message_from_string('\n'.join(data)))
return u"Error while fetching mail " + str(index)
type = property(get_type)

View File

@@ -27,6 +27,8 @@ import sys
import anydbm
import mailconnection_factory
from UserDict import UserDict
from pysqlite2 import dbapi2 as sqlite
class Storage(UserDict):
def __init__(self, nb_pk_fields = 1, spool_dir = "."):
@@ -35,39 +37,70 @@ class Storage(UserDict):
self.set_spool_dir(spool_dir)
self.nb_pk_fields = nb_pk_fields
self.file = self._spool_dir + "/registered.db"
self._registered = self.load()
# return hash of hash (jid and name)
def load(self):
pass
def __setitem__(self, pk_tuple, obj):
# print "Adding " + "#".join(pk_tuple) + " = " + str(obj)
self._registered[str("#".join(pk_tuple))] = obj
def sync(self):
pass
def store(self, nb_pk_fields, registered, pk):
pass
def add(self, key_list, obj):
pass
def __getitem__(self, pk_tuple):
# print "Getting " + "#".join(pk_tuple)
if len(pk_tuple) == self.nb_pk_fields:
return self._registered[str("#".join(pk_tuple))]
else:
partial_key = str("#".join(pk_tuple))
regexp = re.compile(partial_key)
return [self._registered[key]
for key in self._registered.keys()
if regexp.search(key)]
def __delitem__(self, pk_tuple):
# print "Deleting " + "#".join(pk_tuple)
del self._registered[str("#".join(pk_tuple))]
def remove(self, key_list):
pass
def get_spool_dir(self):
return self._spool_dir
def set_spool_dir(self, spool_dir):
print "setting spool dir to " + spool_dir
self._spool_dir = spool_dir
if not os.path.isdir(self._spool_dir):
os.makedirs(self._spool_dir)
spool_dir = property(get_spool_dir, set_spool_dir)
def has_key(self, pk_tuple):
if len(pk_tuple) == self.nb_pk_fields:
return self._registered.has_key(str("#".join(pk_tuple)))
else:
partial_key = str("#".join(pk_tuple))
regexp = re.compile("^" + partial_key)
for key in self._registered.keys():
if regexp.search(key):
return True
return False
def keys(self, pk_tuple = None):
if pk_tuple is None:
return [tuple(key.split("#")) for key in self._registered.keys()]
else:
level = len(pk_tuple)
partial_key = str("#".join(pk_tuple))
regexp = re.compile("^" + partial_key)
result = {}
for key in self._registered.keys():
if regexp.search(key):
result[key.split("#")[level]] = None
return result.keys()
def dump(self):
for pk in self._registered.keys():
print pk + " = " + str(self._registered[pk])
class DBMStorage(Storage):
def __init__(self, nb_pk_fields = 1, spool_dir = "."):
# print "DBM INIT"
Storage.__init__(self, nb_pk_fields, spool_dir)
self.__registered = self.load()
def __del__(self):
# print "DBM STOP"
@@ -109,80 +142,105 @@ class DBMStorage(Storage):
try:
str_registered = anydbm.open(self.file, \
'c')
for pk in self.__registered.keys():
str_registered[pk] = str(self.__registered[pk])
for pk in self._registered.keys():
str_registered[pk] = str(self._registered[pk])
except Exception, e:
print >>sys.stderr, "Cannot save to registered.db : "
print >>sys.stderr, e
str_registered.close()
def __setitem__(self, pk_tuple, obj):
# print "Adding " + "#".join(pk_tuple) + " = " + str(obj)
self.__registered[str("#".join(pk_tuple))] = obj
self.sync()
def __getitem__(self, pk_tuple):
# print "Getting " + "#".join(pk_tuple)
if len(pk_tuple) == self.nb_pk_fields:
return self.__registered[str("#".join(pk_tuple))]
else:
partial_key = str("#".join(pk_tuple))
regexp = re.compile(partial_key)
return [self.__registered[key]
for key in self.__registered.keys()
if regexp.search(key)]
def __setitem__(self, pk_tuple, obj):
Storage.__setitem__(self, pk_tuple, obj)
self.sync()
def __delitem__(self, pk_tuple):
# print "Deleting " + "#".join(pk_tuple)
del self.__registered[str("#".join(pk_tuple))]
Storage.__delitem__(self, pk_tuple)
self.sync()
def has_key(self, pk_tuple):
if len(pk_tuple) == self.nb_pk_fields:
return self.__registered.has_key(str("#".join(pk_tuple)))
else:
partial_key = str("#".join(pk_tuple))
regexp = re.compile("^" + partial_key)
for key in self.__registered.keys():
if regexp.search(key):
return True
return False
def keys(self, pk_tuple = None):
if pk_tuple is None:
return [tuple(key.split("#")) for key in self.__registered.keys()]
else:
level = len(pk_tuple)
partial_key = str("#".join(pk_tuple))
regexp = re.compile("^" + partial_key)
result = {}
for key in self.__registered.keys():
if regexp.search(key):
result[key.split("#")[level]] = None
return result.keys()
def dump(self):
# print "dumping"
for pk in self.__registered.keys():
print pk + " = " + str(self.__registered[pk])
class SQLiteStorage(Storage):
def __init__(self, nb_pk_fields = 1, spool_dir = "."):
pass
self.__connection = None
Storage.__init__(self, nb_pk_fields, spool_dir)
def load(self):
pass
def create(self):
# print "creating new Table"
cursor = self.__connection.cursor()
cursor.execute("""
create table account(
jid STRING,
name STRING,
type STRING,
login STRING,
password STRING,
host STRING,
port INTEGER,
chat_action INTEGER,
online_action INTEGER,
away_action INTEGER,
xa_action INTEGER,
dnd_action INTEGER,
offline_action INTEGER,
interval INTEGER,
mailbox STRING,
PRIMARY KEY(jid, name)
)
""")
self.__connection.commit()
cursor.close()
def __del__(self):
self.__connection.close()
def sync(self):
pass
def store(self, nb_pk_fields, registered, pk):
pass
def add(self, key_list, obj):
pass
def remove(self, key_list):
pass
def load(self):
if not os.path.exists(self.file):
self.__connection = sqlite.connect(self.file)
self.create()
else:
self.__connection = sqlite.connect(self.file)
cursor = self.__connection.cursor()
cursor.execute("""select * from account""")
result = {}
for row in cursor.fetchall():
# print "Creating new " + row[self.nb_pk_fields] + " connection."
account = result["#".join(row[0:self.nb_pk_fields])] = mailconnection_factory.get_new_mail_connection(row[self.nb_pk_fields])
for field_index in range(self.nb_pk_fields + 1, len(row)):
# print "\tSetting " + str(cursor.description[field_index][0]) + \
# " to " + str(row[field_index])
setattr(account,
cursor.description[field_index][0],
row[field_index])
cursor.close()
return result
def __setitem__(self, pk_tuple, obj):
Storage.__setitem__(self, pk_tuple, obj)
cursor = self.__connection.cursor()
cursor.execute("""
insert or replace into account values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(pk_tuple[0],
pk_tuple[1],
obj.type,
obj.login,
obj.password,
obj.host,
obj.port,
obj.chat_action,
obj.online_action,
obj.away_action,
obj.xa_action,
obj.dnd_action,
obj.offline_action,
obj.interval,
obj.mailbox))
self.__connection.commit()
cursor.close()
def __delitem__(self, pk_tuple):
Storage.__delitem__(self, pk_tuple)

View File

@@ -54,6 +54,8 @@ if __name__ == '__main__':
"test")
dbmstorage_suite = unittest.makeSuite(DBMStorage_TestCase, \
"test")
sqlitestorage_suite = unittest.makeSuite(SQLiteStorage_TestCase, \
"test")
jmc_suite = unittest.TestSuite((mail_connection_suite, \
pop3_connection_suite, \
@@ -62,8 +64,9 @@ if __name__ == '__main__':
component_suite, \
component2_suite, \
storage_suite, \
dbmstorage_suite))
test_support.run_suite(mc_factory_suite)
dbmstorage_suite, \
sqlitestorage_suite))
test_support.run_suite(sqlitestorage_suite)
# coverage.stop()
# coverage.analysis(jabber.mailconnection_factory)

View File

@@ -54,7 +54,7 @@ class DBMStorage_TestCase(unittest.TestCase):
ssl = True,
mailbox = "INBOX.box1")
self._account1.chat_action = mailconnection.DO_NOTHING
self._account1.onlline_action = mailconnection.DO_NOTHING
self._account1.online_action = mailconnection.DO_NOTHING
self._account1.away_action = mailconnection.DO_NOTHING
self._account1.xa_action = mailconnection.DO_NOTHING
self._account1.dnd_action = mailconnection.DO_NOTHING
@@ -67,7 +67,7 @@ class DBMStorage_TestCase(unittest.TestCase):
ssl = False,
mailbox = "INBOX.box2")
self._account2.chat_action = mailconnection.DO_NOTHING
self._account2.onlline_action = mailconnection.DO_NOTHING
self._account2.online_action = mailconnection.DO_NOTHING
self._account2.away_action = mailconnection.DO_NOTHING
self._account2.xa_action = mailconnection.DO_NOTHING
self._account2.dnd_action = mailconnection.DO_NOTHING
@@ -156,3 +156,46 @@ class DBMStorage_TestCase(unittest.TestCase):
self.assertEquals(len(result), 2)
self.assertEquals(result[0], "account2")
self.assertEquals(result[1], "account1")
class SQLiteStorage_TestCase(DBMStorage_TestCase):
def setUp(self):
spool_dir = "./spool/test"
self._storage = SQLiteStorage(nb_pk_fields = 2, spool_dir = spool_dir)
self._account1 = IMAPConnection(login = "login1",
password = "password1",
host = "host1",
port = 993,
ssl = True,
mailbox = "INBOX.box1")
self._account1.chat_action = mailconnection.DIGEST
self._account1.online_action = mailconnection.DIGEST
self._account1.away_action = mailconnection.DO_NOTHING
self._account1.xa_action = mailconnection.DO_NOTHING
self._account1.dnd_action = mailconnection.DO_NOTHING
self._account1.offline_action = mailconnection.DO_NOTHING
self._account1.interval = 4
self._account2 = IMAPConnection(login = "login2",
password = "password2",
host = "host2",
port = 1993,
ssl = False,
mailbox = "INBOX.box2")
self._account2.chat_action = mailconnection.DO_NOTHING
self._account2.online_action = mailconnection.DO_NOTHING
self._account2.away_action = mailconnection.DO_NOTHING
self._account2.xa_action = mailconnection.DO_NOTHING
self._account2.dnd_action = mailconnection.DO_NOTHING
self._account2.offline_action = mailconnection.DO_NOTHING
self._account2.interval = 4
# def tearDown(self):
# os.remove(self._storage.file)
# self._storage = None
def test_set_sync_get(self):
self._storage[("test@localhost", "account1")] = self._account1
self._storage[("test@localhost", "account2")] = self._account2
loaded_storage = SQLiteStorage(nb_pk_fields = 2, spool_dir = "./spool/test")
self.assertEquals(loaded_storage[("test@localhost", "account1")], self._account1)
self.assertEquals(loaded_storage[("test@localhost", "account2")], self._account2)