From 55430ed68f992a04c5aecd4a7d0a21537c5a49ac Mon Sep 17 00:00:00 2001 From: David Rousselie Date: Mon, 30 Jan 2006 23:07:42 +0100 Subject: [PATCH] Utils convert and dump - addition of backend converter utility - dump utility darcs-hash:20060130220742-86b55-0cba39429e4251ff9cce34a1dcd9df4515b973f1.gz --- README | 27 +++++++++++++- TODO | 2 -- jabber/component.py | 2 +- jabber/storage.py | 28 +++++++++------ tests/test_storage.py | 33 +++++++++-------- utils/backend_converter.py | 73 ++++++++++++++++++++++++++++++++++++++ utils/backend_dump.py | 58 ++++++++++++++++++++++++++++++ 7 files changed, 195 insertions(+), 28 deletions(-) create mode 100644 utils/backend_converter.py create mode 100644 utils/backend_dump.py diff --git a/README b/README index db8cc36..63d60fc 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ Installation : -- Get pyxmpp from http://pyxmpp.jabberstudio.org/ (work with snapshot pyxmpp-0.5.s20050506) +- Get pyxmpp from http://pyxmpp.jabberstudio.org/ (version 1.0) - edit jmc.xml to match jabber server configuration : - for jabberd2, port must match router.xml port @@ -22,4 +22,29 @@ Feedback : Send me feedback and comments to dax at happycoders dot org +Utils : +- backend_converter.py convert from one storage type to another. + +$ python utils/backend_converter.py + +give you the list of supported types. +example of usage : + +$ python utils/backend_converter.py \ + DBM \ + registered.db \ + SQLite \ + registered.sqlite + +converts a DBM file (registered.db) to a SQLite file +(registered.sqlite). Once converted, the new file copied in +${spool_dir}/${service}/registered.db where ${spool_dir} and +${service} are defined in jmc.xml configuration file. + +- backend_dump.py dump a db file. example : + +$ python utils/backend_dump.py DBM registered.db + + + diff --git a/TODO b/TODO index f9a4fa3..9e7557e 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,3 @@ -* Database backend (default SQLLite) - * Support for attachements with size limit and file format limit (e.g. only png, jpeg,... but no exe, bat,...). diff --git a/jabber/component.py b/jabber/component.py index 4e6048f..ea25650 100644 --- a/jabber/component.py +++ b/jabber/component.py @@ -79,7 +79,7 @@ class MailComponent(Component): except: print >>sys.stderr, "Cannot find " \ + config.get_content("config/storage") + "Storage class" - exit(1) + sys.exit(1) # dump registered accounts (save) every hour self.__count = 60 self.running = False diff --git a/jabber/storage.py b/jabber/storage.py index 89e97d5..93b61e8 100644 --- a/jabber/storage.py +++ b/jabber/storage.py @@ -31,12 +31,17 @@ from pysqlite2 import dbapi2 as sqlite class Storage(UserDict): - def __init__(self, nb_pk_fields = 1, spool_dir = "."): + def __init__(self, nb_pk_fields = 1, spool_dir = ".", db_file = None): UserDict.__init__(self) - self._spool_dir = "" - self.set_spool_dir(spool_dir) self.nb_pk_fields = nb_pk_fields - self.file = self._spool_dir + "/registered.db" + 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): @@ -98,9 +103,9 @@ class Storage(UserDict): class DBMStorage(Storage): - def __init__(self, nb_pk_fields = 1, spool_dir = "."): + def __init__(self, nb_pk_fields = 1, spool_dir = ".", db_file = None): # print "DBM INIT" - Storage.__init__(self, nb_pk_fields, spool_dir) + Storage.__init__(self, nb_pk_fields, spool_dir, db_file) def __del__(self): # print "DBM STOP" @@ -159,9 +164,9 @@ class DBMStorage(Storage): class SQLiteStorage(Storage): - def __init__(self, nb_pk_fields = 1, spool_dir = "."): + def __init__(self, nb_pk_fields = 1, spool_dir = ".", db_file = None): self.__connection = None - Storage.__init__(self, nb_pk_fields, spool_dir) + Storage.__init__(self, nb_pk_fields, spool_dir, db_file) def create(self): # print "creating new Table" @@ -219,6 +224,9 @@ class SQLiteStorage(Storage): 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) @@ -237,10 +245,10 @@ class SQLiteStorage(Storage): obj.dnd_action, obj.offline_action, obj.interval, - obj.mailbox)) + mailbox)) self.__connection.commit() cursor.close() def __delitem__(self, pk_tuple): Storage.__delitem__(self, pk_tuple) - + # TODO diff --git a/tests/test_storage.py b/tests/test_storage.py index ce026f2..ff6f413 100644 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -60,12 +60,11 @@ class DBMStorage_TestCase(unittest.TestCase): self._account1.dnd_action = mailconnection.DO_NOTHING self._account1.offline_action = mailconnection.DO_NOTHING self._account1.interval = 4 - self._account2 = IMAPConnection(login = "login2", + self._account2 = POP3Connection(login = "login2", password = "password2", host = "host2", - port = 1993, - ssl = False, - mailbox = "INBOX.box2") + port = 1110, + ssl = False) self._account2.chat_action = mailconnection.DO_NOTHING self._account2.online_action = mailconnection.DO_NOTHING self._account2.away_action = mailconnection.DO_NOTHING @@ -75,21 +74,26 @@ class DBMStorage_TestCase(unittest.TestCase): self._account2.interval = 4 def tearDown(self): - os.remove(self._storage.file) + db_file = self._storage.file self._storage = None + os.remove(db_file) def test_set_get(self): self._storage[("test@localhost", "account1")] = self._account1 self._storage[("test@localhost", "account2")] = self._account2 - self.assertEquals(self._storage[("test@localhost", "account1")], self._account1) - self.assertEquals(self._storage[("test@localhost", "account2")], self._account2) + self.assertEquals(self._storage[("test@localhost", "account1")], + self._account1) + self.assertEquals(self._storage[("test@localhost", "account2")], + self._account2) def test_set_sync_get(self): self._storage[("test@localhost", "account1")] = self._account1 self._storage[("test@localhost", "account2")] = self._account2 loaded_storage = DBMStorage(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) + self.assertEquals(loaded_storage[("test@localhost", "account1")], + self._account1) + self.assertEquals(loaded_storage[("test@localhost", "account2")], + self._account2) def test_set_del_get(self): self._storage[("test@localhost", "account2")] = self._account2 @@ -174,12 +178,11 @@ class SQLiteStorage_TestCase(DBMStorage_TestCase): self._account1.dnd_action = mailconnection.DO_NOTHING self._account1.offline_action = mailconnection.DO_NOTHING self._account1.interval = 4 - self._account2 = IMAPConnection(login = "login2", + self._account2 = POP3Connection(login = "login2", password = "password2", host = "host2", port = 1993, - ssl = False, - mailbox = "INBOX.box2") + ssl = False) self._account2.chat_action = mailconnection.DO_NOTHING self._account2.online_action = mailconnection.DO_NOTHING self._account2.away_action = mailconnection.DO_NOTHING @@ -197,5 +200,7 @@ class SQLiteStorage_TestCase(DBMStorage_TestCase): 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) + self.assertEquals(loaded_storage[("test@localhost", "account1")], + self._account1) + self.assertEquals(loaded_storage[("test@localhost", "account2")], + self._account2) diff --git a/utils/backend_converter.py b/utils/backend_converter.py new file mode 100644 index 0000000..28d49b0 --- /dev/null +++ b/utils/backend_converter.py @@ -0,0 +1,73 @@ +## +## jmc_backend_converter.py +## Login : David Rousselie +## Started on Sun Jan 29 18:46:29 2006 David Rousselie +## $Id$ +## +## Copyright (C) 2006 David Rousselie +## 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 sys +sys.path.insert(0, "..") +import types +import jabber.storage +import os.path +import re + +if len(sys.argv) != 5: + print >>sys.stderr, "Usage: " + sys.argv[0] + " from_type from_db_file to_type to_db_file" + print >>sys.stderr, "Supported DB type are :" + for var in [aclass + for aclass in dir(jabber.storage) + if type(getattr(jabber.storage, aclass)) == types.ClassType \ + and re.compile(".+Storage$").match(aclass) is not None]: + print >>sys.stderr, "\t" + var + sys.exit(1) + +from_storage_class = sys.argv[1] +from_file = sys.argv[2] +to_storage_class = sys.argv[3] +to_file = sys.argv[4] + +if not os.path.exists(from_file): + print >>sys.stderr, from_file + " does not exist." + sys.exit(1) + +from jabber.storage import * + +from_storage = None +to_storage = None +try: + from_storage = globals()[from_storage_class + "Storage"](2, db_file = from_file) +except Exception,e: + print >>sys.stderr, e + print >>sys.stderr, "Cannot find " + from_storage_class + "Storage class" + sys.exit(1) +try: + to_storage = globals()[to_storage_class + "Storage"](2, db_file = to_file) +except Exception,e: + print >>sys.stderr, e + print >>sys.stderr, "Cannot find " + to_storage_class + "Storage class" + sys.exit(1) + + +for jid, name in from_storage.keys(): + print "Converting " + jid + "/" + name + " from " + from_storage_class + \ + " to " + to_storage_class + "." + to_storage[(jid, name)] = from_storage[(jid, name)] + +to_storage.sync() + diff --git a/utils/backend_dump.py b/utils/backend_dump.py new file mode 100644 index 0000000..9f706b4 --- /dev/null +++ b/utils/backend_dump.py @@ -0,0 +1,58 @@ +## +## dump.py +## Login : David Rousselie +## Started on Mon Jan 30 21:43:38 2006 David Rousselie +## $Id$ +## +## Copyright (C) 2006 +## 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 sys +sys.path.insert(0, "..") +import types +import jabber.storage +import os.path +import re + + +if len(sys.argv) != 3: + print >>sys.stderr, "Usage: " + sys.argv[0] + " db_type db_file" + print >>sys.stderr, "Supported DB type are :" + for var in [aclass + for aclass in dir(jabber.storage) + if type(getattr(jabber.storage, aclass)) == types.ClassType \ + and re.compile(".+Storage$").match(aclass) is not None]: + print >>sys.stderr, "\t" + var + sys.exit(1) + +from_storage_class = sys.argv[1] +from_file = sys.argv[2] + +if not os.path.exists(from_file): + print >>sys.stderr, from_file + " does not exist." + sys.exit(1) + +from jabber.storage import * + +try: + from_storage = globals()[from_storage_class + "Storage"](2, db_file = from_file) +except Exception,e: + print >>sys.stderr, e + print >>sys.stderr, "Cannot find " + from_storage_class + "Storage class" + sys.exit(1) + +for jid, name in from_storage.keys(): + print jid + "/" + name + " from " + from_storage_class + " = " + str(from_storage[(jid, name)])