Component migration to use storage

!! Warning !! Not fully tested.

darcs-hash:20060122125943-86b55-a0cb0c408b0974b18af8613144bb3a7c3f2288bf.gz
This commit is contained in:
David Rousselie
2006-01-22 13:59:43 +01:00
parent edc1a693ae
commit a44b18828e
7 changed files with 269 additions and 256 deletions

View File

@@ -65,7 +65,6 @@ class MailComponent(Component):
self.__interval = int(config.get_content("config/check_interval"))
self.__config = config
# self.__registered = {}
try:
self.__storage = globals()[config.get_content("config/storage") + "Storage"]()
except:
@@ -345,16 +344,17 @@ class MailComponent(Component):
finally:
## TODO : for jid in self.__storage.keys(())
## for name in self.__storage.keys((jid,))
# for jid in self.__storage.keys(()):
# p = Presence(from_jid = str(self.jid), to_jid = jid, \
# stanza_type = "unavailable")
# self.stream.send(p)
# for name in self.__registered[jid].keys():
# if self.__storage[(jid, name)].status != "offline":
# p = Presence(from_jid = name + "@" + str(self.jid), \
# to_jid = jid, \
# stanza_type = "unavailable")
# self.stream.send(p)
if self.stream:
for jid in self.__storage.keys(()):
p = Presence(from_jid = str(self.jid), to_jid = jid, \
stanza_type = "unavailable")
self.stream.send(p)
for jid, name in self.__storage.keys():
if self.__storage[(jid, name)].status != "offline":
p = Presence(from_jid = name + "@" + str(self.jid), \
to_jid = jid, \
stanza_type = "unavailable")
self.stream.send(p)
threads = threading.enumerate()
for th in threads:
try:
@@ -367,7 +367,7 @@ class MailComponent(Component):
except:
pass
self.disconnect()
del self.__storage
del self.__storage
self.__logger.debug("Exitting normally")
""" Stop method handler """
@@ -392,10 +392,14 @@ class MailComponent(Component):
def authenticated(self):
self.__logger.debug("AUTHENTICATED")
Component.authenticated(self)
# for jid in self.__registered.keys():
# p = Presence(from_jid = str(self.jid), \
# to_jid = jid, stanza_type = "probe")
# self.stream.send(p)
for jid, name in self.__storage.keys():
p = Presence(from_jid = name + "@" + str(self.jid), \
to_jid = jid, stanza_type = "probe")
self.stream.send(p)
for jid in self.__storage.keys(()):
p = Presence(from_jid = str(self.jid), \
to_jid = jid, stanza_type = "probe")
self.stream.send(p)
self.stream.set_iq_get_handler("query", "jabber:iq:version", \
self.get_version)
@@ -445,9 +449,9 @@ class MailComponent(Component):
self.__logger.debug("DISCO_GET_ITEMS")
base_from_jid = str(iq.get_from().bare())
di = DiscoItems()
if not node and self.__registered.has_key(base_from_jid):
for name in self.__registered[base_from_jid].keys():
account = self.__registered[base_from_jid][name]
if not node:
for jid, name in self.__storage.keys():
account = self.__storage[(jid, name)]
str_name = account.get_type() + " connection " + name
if account.get_type()[0:4] == "imap":
str_name += " (" + account.mailbox + ")"
@@ -488,18 +492,16 @@ class MailComponent(Component):
remove = iq.xpath_eval("r:query/r:remove", \
{"r" : "jabber:iq:register"})
if remove:
if self.__registered.has_key(base_from_jid):
for name in self.__registered[base_from_jid].keys():
p = Presence(from_jid = name + "@" + str(self.jid), \
to_jid = from_jid, \
stanza_type = "unsubscribe")
self.stream.send(p)
p = Presence(from_jid = name + "@" + str(self.jid), \
to_jid = from_jid, \
stanza_type = "unsubscribed")
self.stream.send(p)
del self.__registered[base_from_jid]
# self.__storage.
for jid, name in self.__storage.keys():
p = Presence(from_jid = name + "@" + str(self.jid), \
to_jid = from_jid, \
stanza_type = "unsubscribe")
self.stream.send(p)
p = Presence(from_jid = name + "@" + str(self.jid), \
to_jid = from_jid, \
stanza_type = "unsubscribed")
self.stream.send(p)
del self.__storage[(jid, name)]
p = Presence(from_jid = self.jid, to_jid = from_jid, \
stanza_type = "unsubscribe")
self.stream.send(p)
@@ -585,9 +587,8 @@ class MailComponent(Component):
iq = iq.make_result_response()
self.stream.send(iq)
if not self.__registered.has_key(base_from_jid):
self.__registered[base_from_jid] = {}
p = Presence(from_jid = self.jid, to_jid = from_jid.bare(), \
if not self.__storage.has_key((base_from_jid,)):
p = Presence(from_jid = self.jid, to_jid = base_from_jid, \
stanza_type="subscribe")
self.stream.send(p)
@@ -596,7 +597,7 @@ class MailComponent(Component):
socket = host + ":" + str(port)
else:
socket = host
if self.__registered[base_from_jid].has_key(name):
if self.__storage.has_key((base_from_jid, name)):
m = Message(from_jid = self.jid, to_jid = from_jid, \
stanza_type = "message", \
body = u"Updated %s connection '%s': Registered with "\
@@ -611,31 +612,28 @@ class MailComponent(Component):
% (type, name, login, password, socket))
self.stream.send(m)
p = Presence(from_jid = name + "@" + str(self.jid), \
to_jid = from_jid.bare(), \
to_jid = base_from_jid, \
stanza_type="subscribe")
self.stream.send(p)
self.__registered[base_from_jid][name] = \
mailconnection_factory.get_new_mail_connection(type)
self.__registered[base_from_jid][name].login = login
self.__registered[base_from_jid][name].password = password
self.__registered[base_from_jid][name].host = host
self.__registered[base_from_jid][name].ffc_action = ffc_action
self.__registered[base_from_jid][name].online_action = online_action
self.__registered[base_from_jid][name].away_action = away_action
self.__registered[base_from_jid][name].ea_action = ea_action
self.__registered[base_from_jid][name].offline_action = offline_action
self.__storage[(base_from_jid, name)] = account = \
mailconnection_factory.get_new_mail_connection(type)
account.login = login
account.password = password
account.host = host
account.ffc_action = ffc_action
account.online_action = online_action
account.away_action = away_action
account.ea_action = ea_action
account.offline_action = offline_action
account.interval = interval
if port:
self.__registered[base_from_jid][name].port = port
if interval:
self.__registered[base_from_jid][name].interval = interval
account.port = port
if type[0:4] == "imap":
self.__registered[base_from_jid][name].mailbox = mailbox
account.mailbox = mailbox
self.__storage.add([base_from_jid, name], self.__registered[base_from_jid][name])
return 1
""" Handle presence availability """
@@ -646,38 +644,28 @@ class MailComponent(Component):
name = stanza.get_to().node
show = stanza.get_show()
self.__logger.debug("SHOW : " + str(show))
if self.__registered.has_key(base_from_jid):
if not name:
p = Presence(from_jid = self.jid, \
to_jid = from_jid, \
status = \
str(len(self.__registered[base_from_jid])) \
+ " accounts registered.", \
show = show, \
stanza_type = "available")
self.stream.send(p)
for name in self.__registered[base_from_jid].keys():
account = self.__registered[base_from_jid][name]
# Make available to receive mail only when online
account.status = "offline" # TODO get real status available = (not show)
p = Presence(from_jid = name + "@" + \
str(self.jid), \
to_jid = from_jid, \
status = account.get_status(), \
show = show, \
stanza_type = "available")
self.stream.send(p)
elif self.__registered[base_from_jid].has_key(name):
account = self.__registered[base_from_jid][name]
# Make available to receive mail only when online
account.status = "offline" # TODO get real status = (not show)
p = Presence(from_jid = name + "@" + \
str(self.jid), \
to_jid = from_jid, \
status = account.get_status(), \
show = show, \
stanza_type = "available")
self.stream.send(p)
if name:
self.__logger.debug("TO : " + name + " " + base_from_jid)
if not name and self.__storage.has_key((base_from_jid,)):
p = Presence(from_jid = self.jid, \
to_jid = from_jid, \
status = \
str(len(self.__storage.keys((base_from_jid,)))) \
+ " accounts registered.", \
show = show, \
stanza_type = "available")
self.stream.send(p)
elif self.__storage.has_key((base_from_jid, name)):
account = self.__storage[(base_from_jid, name)]
# Make available to receive mail only when online
account.status = "online" # TODO get real status = (not show)
p = Presence(from_jid = name + "@" + \
str(self.jid), \
to_jid = from_jid, \
status = account.get_status_msg(), \
show = show, \
stanza_type = "available")
self.stream.send(p)
return 1
""" handle presence unavailability """
@@ -685,10 +673,9 @@ class MailComponent(Component):
self.__logger.debug("PRESENCE_UNAVAILABLE")
from_jid = stanza.get_from()
base_from_jid = str(from_jid.bare())
if stanza.get_to() == str(self.jid) \
and self.__registered.has_key(base_from_jid):
for name in self.__registered[base_from_jid].keys():
self.__registered[base_from_jid][name].status = "offline" # TODO get real status
if stanza.get_to() == str(self.jid):
for jid, name in self.__storage.keys():
self.__storage[(base_from_jid, name)].status = "offline" # TODO get real status
p = Presence(from_jid = name + "@" + str(self.jid), \
to_jid = from_jid, \
stanza_type = "unavailable")
@@ -712,12 +699,11 @@ class MailComponent(Component):
name = stanza.get_to().node
from_jid = stanza.get_from()
base_from_jid = str(from_jid.bare())
if self.__registered.has_key(base_from_jid) \
and self.__registered[base_from_jid].has_key(name):
account = self.__registered[base_from_jid][name]
if name is not None and self.__storage.has_key((base_from_jid, name)):
account = self.__storage[(base_from_jid, name)]
account.status = "online" # TODO retrieve real status
p = Presence(from_jid = stanza.get_to(), to_jid = from_jid, \
status = account.get_status(), \
status = account.get_status_msg(), \
stanza_type = "available")
self.stream.send(p)
return 1
@@ -728,9 +714,8 @@ class MailComponent(Component):
name = stanza.get_to().node
from_jid = stanza.get_from()
base_from_jid = str(from_jid.bare())
if self.__registered.has_key(base_from_jid) \
and self.__registered[base_from_jid].has_key(name):
del self.__registered[base_from_jid][name]
if name is not None and self.__storage.has_key((base_from_jid, name)):
del self.__storage[(base_from_jid, name)]
p = Presence(from_jid = stanza.get_to(), to_jid = from_jid, \
stanza_type = "unsubscribe")
self.stream.send(p)
@@ -752,20 +737,20 @@ class MailComponent(Component):
self.__logger.debug("MESSAGE: " + message.get_body())
name = message.get_to().node
base_from_jid = str(message.get_from().bare())
if name and self.__registered.has_key(base_from_jid):
body = message.get_body()
cmd = body.split(' ')
if cmd[0] == "check":
self.check_mail(base_from_jid, name)
elif cmd[0] == "dump":
body = ""
for jid in self.__registered.keys():
for name in self.__registered[jid].keys():
body += name + " for user " + jid
msg = Message(from_jid = self.jid, to_jid = base_from_jid, \
stanza_type = "message", \
body = body)
self.stream.send(msg)
# if name and self.__registered.has_key(base_from_jid):
# body = message.get_body()
# cmd = body.split(' ')
# if cmd[0] == "check":
# self.check_mail(base_from_jid, name)
# elif cmd[0] == "dump":
# body = ""
# for jid in self.__registered.keys():
# for name in self.__registered[jid].keys():
# body += name + " for user " + jid
# msg = Message(from_jid = self.jid, to_jid = base_from_jid, \
# stanza_type = "message", \
# body = body)
# self.stream.send(msg)
return 1
# """ Store registered sessions """
@@ -863,6 +848,7 @@ class MailComponent(Component):
""" check mail handler """
def check_all_mail(self):
self.__logger.debug("CHECK_ALL_MAIL")
for jid in self.__registered.keys():
for name in self.__registered[jid].keys():
self.check_mail(jid, name)
## TODO
# for jid in self.__registered.keys():
# for name in self.__registered[jid].keys():
# self.check_mail(jid, name)

View File

@@ -156,6 +156,7 @@ class MailConnection(object):
self.away_action = RETRIEVE
self.ea_action = RETRIEVE
self.offline_action = DO_NOTHING
self.interval = 5
def __eq__(self, other):
return self.get_type() == other.get_type() \
@@ -168,8 +169,9 @@ class MailConnection(object):
and self.online_action == other.online_action \
and self.away_action == other.away_action \
and self.ea_action == other.ea_action \
and self.offline_action == other.offline_action
and self.offline_action == other.offline_action \
and self.interval == other.interval
def __str__(self):
return self.get_type() + "#" + self.login + "#" + self.password + "#" \
+ self.host + "#" + str(self.port) + "#" + str(self.ffc_action) + "#" \
@@ -219,7 +221,7 @@ class MailConnection(object):
def get_type(self):
return "UNKNOWN"
def get_status(self):
def get_status_msg(self):
return self.get_type() + "://" + self.login + "@" + self.host + ":" + \
str(self.port)
@@ -246,7 +248,7 @@ class MailConnection(object):
"offline": self.offline_action}
if mapping.has_key(self.status):
return mapping[self.status]
return "nothing"
return NOTHING
action = property(get_action)

View File

@@ -66,38 +66,29 @@ class DBMStorage(Storage):
def __init__(self, nb_pk_fields = 1, spool_dir = "."):
# print "DBM INIT"
Storage.__init__(self, nb_pk_fields, spool_dir)
self.__str_registered = anydbm.open(self.file, \
'c')
self.__registered = self.load()
def __del__(self):
# print "DBM STOP"
self.__str_registered.close()
# print "DBM STOP"
self.sync()
def load(self):
# print "DBM LOAD"
str_registered = anydbm.open(self.file, \
'c')
result = {}
try:
for pk in self.__str_registered.keys():
pk_list = pk.split('#')
obj = result
key = None
while pk_list:
key = pk_list.pop(0)
if pk_list:
if not obj.has_key(key):
obj[key] = {}
obj = obj[key]
obj[key] = mailconnection_factory.str_to_mail_connection(self.__str_registered[pk])
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.__str_registered.close()
self.__str_registered = anydbm.open(self.file, \
'c')
# print "DBM SYNC"
self.store()
def __store(self, nb_pk_fields, registered, pk):
if nb_pk_fields > 0:
@@ -112,52 +103,68 @@ class DBMStorage(Storage):
self.__str_registered[pk] = str(registered)
print "STORING : " + pk + " = " + str(registered)
def store(self, registered):
def store(self):
# print "DBM STORE"
try:
self.__store(self.nb_pk_fields, registered, "")
# Force file synchronisation
self.sync()
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):
# print "Adding " + "#".join(pk_tuple) + " = " + str(obj)
self.__str_registered["#".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 mailconnection_factory.str_to_mail_connection(self.__str_registered["#".join(pk_tuple)])
return self.__registered[str("#".join(pk_tuple))]
else:
partial_key = "#".join(pk_tuple)
partial_key = str("#".join(pk_tuple))
regexp = re.compile(partial_key)
return [mailconnection_factory.str_to_mail_connection(self.__str_registered[key])
for key in self.__str_registered.keys()
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.__str_registered["#".join(pk_tuple)]
del self.__registered[str("#".join(pk_tuple))]
self.sync()
def has_key(self, pk_tuple):
return self.__str_registered.has_key("#".join(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.__str_registered.keys()]
return [tuple(key.split("#")) for key in self.__registered.keys()]
else:
level = len(pk_tuple)
partial_key = "#".join(pk_tuple)
partial_key = str("#".join(pk_tuple))
regexp = re.compile("^" + partial_key)
result = {}
for key in self.__str_registered.keys():
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 = "."):