SQLite backend
darcs-hash:20060129173720-86b55-cb365b2e6e6c652e885d88594e0e5c36deebf364.gz
This commit is contained in:
5
TODO
5
TODO
@@ -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)
|
* Database backend (default SQLLite)
|
||||||
|
|
||||||
* Support for attachements with size limit and file format limit
|
* Support for attachements with size limit and file format limit
|
||||||
|
|||||||
@@ -221,9 +221,6 @@ class MailConnection(object):
|
|||||||
def format_message_summary(self, email_msg):
|
def format_message_summary(self, email_msg):
|
||||||
return self.format_message(email_msg, False)
|
return self.format_message(email_msg, False)
|
||||||
|
|
||||||
def get_type(self):
|
|
||||||
return "UNKNOWN"
|
|
||||||
|
|
||||||
def get_status_msg(self):
|
def get_status_msg(self):
|
||||||
return self.get_type() + "://" + self.login + "@" + self.host + ":" + \
|
return self.get_type() + "://" + self.login + "@" + self.host + ":" + \
|
||||||
unicode(self.port)
|
unicode(self.port)
|
||||||
@@ -324,6 +321,8 @@ class IMAPConnection(MailConnection):
|
|||||||
return self.format_message_summary(email.message_from_string(data[0][1]))
|
return self.format_message_summary(email.message_from_string(data[0][1]))
|
||||||
return u"Error while fetching mail " + str(index)
|
return u"Error while fetching mail " + str(index)
|
||||||
|
|
||||||
|
type = property(get_type)
|
||||||
|
|
||||||
class POP3Connection(MailConnection):
|
class POP3Connection(MailConnection):
|
||||||
def __init__(self, login = "", password = "", host = "", \
|
def __init__(self, login = "", password = "", host = "", \
|
||||||
port = None, ssl = False):
|
port = None, ssl = False):
|
||||||
@@ -377,3 +376,5 @@ class POP3Connection(MailConnection):
|
|||||||
if ret[0:3] == '+OK':
|
if ret[0:3] == '+OK':
|
||||||
return self.format_message_summary(email.message_from_string('\n'.join(data)))
|
return self.format_message_summary(email.message_from_string('\n'.join(data)))
|
||||||
return u"Error while fetching mail " + str(index)
|
return u"Error while fetching mail " + str(index)
|
||||||
|
|
||||||
|
type = property(get_type)
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import sys
|
|||||||
import anydbm
|
import anydbm
|
||||||
import mailconnection_factory
|
import mailconnection_factory
|
||||||
from UserDict import UserDict
|
from UserDict import UserDict
|
||||||
|
from pysqlite2 import dbapi2 as sqlite
|
||||||
|
|
||||||
|
|
||||||
class Storage(UserDict):
|
class Storage(UserDict):
|
||||||
def __init__(self, nb_pk_fields = 1, spool_dir = "."):
|
def __init__(self, nb_pk_fields = 1, spool_dir = "."):
|
||||||
@@ -35,39 +37,70 @@ class Storage(UserDict):
|
|||||||
self.set_spool_dir(spool_dir)
|
self.set_spool_dir(spool_dir)
|
||||||
self.nb_pk_fields = nb_pk_fields
|
self.nb_pk_fields = nb_pk_fields
|
||||||
self.file = self._spool_dir + "/registered.db"
|
self.file = self._spool_dir + "/registered.db"
|
||||||
|
self._registered = self.load()
|
||||||
|
|
||||||
# return hash of hash (jid and name)
|
def __setitem__(self, pk_tuple, obj):
|
||||||
def load(self):
|
# print "Adding " + "#".join(pk_tuple) + " = " + str(obj)
|
||||||
pass
|
self._registered[str("#".join(pk_tuple))] = obj
|
||||||
|
|
||||||
def sync(self):
|
def __getitem__(self, pk_tuple):
|
||||||
pass
|
# print "Getting " + "#".join(pk_tuple)
|
||||||
|
if len(pk_tuple) == self.nb_pk_fields:
|
||||||
def store(self, nb_pk_fields, registered, pk):
|
return self._registered[str("#".join(pk_tuple))]
|
||||||
pass
|
else:
|
||||||
|
partial_key = str("#".join(pk_tuple))
|
||||||
def add(self, key_list, obj):
|
regexp = re.compile(partial_key)
|
||||||
pass
|
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):
|
def get_spool_dir(self):
|
||||||
return self._spool_dir
|
return self._spool_dir
|
||||||
|
|
||||||
def set_spool_dir(self, spool_dir):
|
def set_spool_dir(self, spool_dir):
|
||||||
print "setting spool dir to " + spool_dir
|
|
||||||
self._spool_dir = spool_dir
|
self._spool_dir = spool_dir
|
||||||
if not os.path.isdir(self._spool_dir):
|
if not os.path.isdir(self._spool_dir):
|
||||||
os.makedirs(self._spool_dir)
|
os.makedirs(self._spool_dir)
|
||||||
|
|
||||||
spool_dir = property(get_spool_dir, set_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):
|
class DBMStorage(Storage):
|
||||||
def __init__(self, nb_pk_fields = 1, spool_dir = "."):
|
def __init__(self, nb_pk_fields = 1, spool_dir = "."):
|
||||||
# print "DBM INIT"
|
# print "DBM INIT"
|
||||||
Storage.__init__(self, nb_pk_fields, spool_dir)
|
Storage.__init__(self, nb_pk_fields, spool_dir)
|
||||||
self.__registered = self.load()
|
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
# print "DBM STOP"
|
# print "DBM STOP"
|
||||||
@@ -109,80 +142,105 @@ class DBMStorage(Storage):
|
|||||||
try:
|
try:
|
||||||
str_registered = anydbm.open(self.file, \
|
str_registered = anydbm.open(self.file, \
|
||||||
'c')
|
'c')
|
||||||
for pk in self.__registered.keys():
|
for pk in self._registered.keys():
|
||||||
str_registered[pk] = str(self.__registered[pk])
|
str_registered[pk] = str(self._registered[pk])
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print >>sys.stderr, "Cannot save to registered.db : "
|
print >>sys.stderr, "Cannot save to registered.db : "
|
||||||
print >>sys.stderr, e
|
print >>sys.stderr, e
|
||||||
str_registered.close()
|
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):
|
def __setitem__(self, pk_tuple, obj):
|
||||||
# print "Getting " + "#".join(pk_tuple)
|
Storage.__setitem__(self, pk_tuple, obj)
|
||||||
if len(pk_tuple) == self.nb_pk_fields:
|
self.sync()
|
||||||
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):
|
def __delitem__(self, pk_tuple):
|
||||||
# print "Deleting " + "#".join(pk_tuple)
|
Storage.__delitem__(self, pk_tuple)
|
||||||
del self.__registered[str("#".join(pk_tuple))]
|
|
||||||
self.sync()
|
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):
|
class SQLiteStorage(Storage):
|
||||||
def __init__(self, nb_pk_fields = 1, spool_dir = "."):
|
def __init__(self, nb_pk_fields = 1, spool_dir = "."):
|
||||||
pass
|
self.__connection = None
|
||||||
|
Storage.__init__(self, nb_pk_fields, spool_dir)
|
||||||
|
|
||||||
def load(self):
|
def create(self):
|
||||||
pass
|
# 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):
|
def sync(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def store(self, nb_pk_fields, registered, pk):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def add(self, key_list, obj):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def remove(self, key_list):
|
def load(self):
|
||||||
pass
|
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)
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ if __name__ == '__main__':
|
|||||||
"test")
|
"test")
|
||||||
dbmstorage_suite = unittest.makeSuite(DBMStorage_TestCase, \
|
dbmstorage_suite = unittest.makeSuite(DBMStorage_TestCase, \
|
||||||
"test")
|
"test")
|
||||||
|
sqlitestorage_suite = unittest.makeSuite(SQLiteStorage_TestCase, \
|
||||||
|
"test")
|
||||||
|
|
||||||
jmc_suite = unittest.TestSuite((mail_connection_suite, \
|
jmc_suite = unittest.TestSuite((mail_connection_suite, \
|
||||||
pop3_connection_suite, \
|
pop3_connection_suite, \
|
||||||
@@ -62,8 +64,9 @@ if __name__ == '__main__':
|
|||||||
component_suite, \
|
component_suite, \
|
||||||
component2_suite, \
|
component2_suite, \
|
||||||
storage_suite, \
|
storage_suite, \
|
||||||
dbmstorage_suite))
|
dbmstorage_suite, \
|
||||||
test_support.run_suite(mc_factory_suite)
|
sqlitestorage_suite))
|
||||||
|
test_support.run_suite(sqlitestorage_suite)
|
||||||
|
|
||||||
# coverage.stop()
|
# coverage.stop()
|
||||||
# coverage.analysis(jabber.mailconnection_factory)
|
# coverage.analysis(jabber.mailconnection_factory)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class DBMStorage_TestCase(unittest.TestCase):
|
|||||||
ssl = True,
|
ssl = True,
|
||||||
mailbox = "INBOX.box1")
|
mailbox = "INBOX.box1")
|
||||||
self._account1.chat_action = mailconnection.DO_NOTHING
|
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.away_action = mailconnection.DO_NOTHING
|
||||||
self._account1.xa_action = mailconnection.DO_NOTHING
|
self._account1.xa_action = mailconnection.DO_NOTHING
|
||||||
self._account1.dnd_action = mailconnection.DO_NOTHING
|
self._account1.dnd_action = mailconnection.DO_NOTHING
|
||||||
@@ -67,7 +67,7 @@ class DBMStorage_TestCase(unittest.TestCase):
|
|||||||
ssl = False,
|
ssl = False,
|
||||||
mailbox = "INBOX.box2")
|
mailbox = "INBOX.box2")
|
||||||
self._account2.chat_action = mailconnection.DO_NOTHING
|
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.away_action = mailconnection.DO_NOTHING
|
||||||
self._account2.xa_action = mailconnection.DO_NOTHING
|
self._account2.xa_action = mailconnection.DO_NOTHING
|
||||||
self._account2.dnd_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(len(result), 2)
|
||||||
self.assertEquals(result[0], "account2")
|
self.assertEquals(result[0], "account2")
|
||||||
self.assertEquals(result[1], "account1")
|
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user