Files
jmc/jabber/storage.py
David Rousselie 55430ed68f Utils convert and dump
- addition of backend converter utility
- dump utility

darcs-hash:20060130220742-86b55-0cba39429e4251ff9cce34a1dcd9df4515b973f1.gz
2006-01-30 23:07:42 +01:00

255 lines
8.5 KiB
Python

##
## storage.py
## Login : David Rousselie <dax@happycoders.org>
## Started on Wed Jul 20 20:26:53 2005 dax
## $Id: storage.py,v 1.1 2005/09/18 20:24:07 dax Exp $
##
## Copyright (C) 2005 dax
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## 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.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
import os
import re
import os.path
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 = ".", db_file = None):
UserDict.__init__(self)
self.nb_pk_fields = nb_pk_fields
if db_file is None:
self._spool_dir = ""
self.set_spool_dir(spool_dir)
self.file = self._spool_dir + "/registered.db"
else:
spool_dir = os.path.dirname(db_file) or "."
self.set_spool_dir(spool_dir)
self.file = db_file
self._registered = self.load()
def __setitem__(self, pk_tuple, obj):
# print "Adding " + "#".join(pk_tuple) + " = " + str(obj)
self._registered[str("#".join(pk_tuple))] = obj
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 get_spool_dir(self):
return self._spool_dir
def set_spool_dir(self, 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 = ".", db_file = None):
# print "DBM INIT"
Storage.__init__(self, nb_pk_fields, spool_dir, db_file)
def __del__(self):
# print "DBM STOP"
self.sync()
def load(self):
# print "DBM LOAD"
str_registered = anydbm.open(self.file, \
'c')
result = {}
try:
for pk in str_registered.keys():
result[pk] = mailconnection_factory.str_to_mail_connection(str_registered[pk])
except Exception, e:
print >>sys.stderr, "Cannot load registered.db : "
print >>sys.stderr, e
str_registered.close()
return result
def sync(self):
# print "DBM SYNC"
self.store()
def __store(self, nb_pk_fields, registered, pk):
if nb_pk_fields > 0:
for key in registered.keys():
if pk:
self.__store(nb_pk_fields - 1, \
registered[key], pk + "#" + key)
else:
self.__store(nb_pk_fields - 1, \
registered[key], key)
else:
self.__str_registered[pk] = str(registered)
# print "STORING : " + pk + " = " + str(registered)
def store(self):
# print "DBM STORE"
try:
str_registered = anydbm.open(self.file, \
'c')
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):
Storage.__setitem__(self, pk_tuple, obj)
self.sync()
def __delitem__(self, pk_tuple):
Storage.__delitem__(self, pk_tuple)
self.sync()
class SQLiteStorage(Storage):
def __init__(self, nb_pk_fields = 1, spool_dir = ".", db_file = None):
self.__connection = None
Storage.__init__(self, nb_pk_fields, spool_dir, db_file)
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 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()
mailbox = None
if obj.type[0:4] == "imap":
mailbox = obj.mailbox
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,
mailbox))
self.__connection.commit()
cursor.close()
def __delitem__(self, pk_tuple):
Storage.__delitem__(self, pk_tuple)
# TODO