Store mailbox with "/" delimiter and discover when populating account what is the real delimiter
darcs-hash:20071031165547-86b55-50bb56e0db9ff77385656b126d7f0f2a02ff3d3a.gz
This commit is contained in:
@@ -56,9 +56,11 @@ class MailAccountManager(AccountManager):
|
||||
from_jid,
|
||||
account_type,
|
||||
lang_class):
|
||||
"""Handle get_register on an IMAP account.
|
||||
"""
|
||||
Handle get_register on an IMAP account.
|
||||
Return a preinitialized form.
|
||||
account_type contains 'account_type + imap_dir'"""
|
||||
account_type contains 'account_type + imap_dir'
|
||||
"""
|
||||
splitted_node = account_type.split("/")
|
||||
splitted_node_len = len(splitted_node)
|
||||
if splitted_node_len == 1 or \
|
||||
@@ -71,6 +73,7 @@ class MailAccountManager(AccountManager):
|
||||
else:
|
||||
info_query = info_query.make_result_response()
|
||||
model.db_connect()
|
||||
# TODO : "/" is default, "." could be
|
||||
imap_dir = "/".join(splitted_node[1:])
|
||||
bare_from_jid = from_jid.bare()
|
||||
_account = account.get_account_filter(\
|
||||
@@ -80,17 +83,20 @@ class MailAccountManager(AccountManager):
|
||||
account_class=IMAPAccount)
|
||||
query = info_query.new_query("jabber:iq:register")
|
||||
if _account is not None:
|
||||
# update account
|
||||
result = self.generate_registration_form_init(lang_class,
|
||||
_account)
|
||||
else:
|
||||
_account = account.get_account(bare_from_jid, name,
|
||||
IMAPAccount)
|
||||
if _account is not None:
|
||||
# create new account based on current one
|
||||
result = self.generate_registration_form_init(lang_class,
|
||||
_account)
|
||||
result["name"].value = None
|
||||
result["name"].type = "text-single"
|
||||
else:
|
||||
# create new account from scratch
|
||||
result = self.generate_registration_form(\
|
||||
lang_class,
|
||||
IMAPAccount,
|
||||
|
||||
@@ -137,17 +137,17 @@ class Lang(jcl.lang.Lang):
|
||||
send_mail_ok_body = u"Votre email a été envoyé à %s."
|
||||
|
||||
help_message_body = u"Pour envoyer un email avec JMC, vous avez le choix " \
|
||||
+ "entre :\n" \
|
||||
+ " - Envoyer un message à la passerelle JMC: le sujet de l'email" \
|
||||
+ " sera le sujet du message Jabber ou le sujet spécifié avec la " \
|
||||
+ "syntaxe suivant dans le corps du message Jabber :\n" \
|
||||
+ "\tSubject: votre sujet\n" \
|
||||
+ " Pour spécifier les destinataires de l'email, il faut ajouter une" \
|
||||
+ " ligne au corps du message Jabber avec la syntaxe suivante:\n" \
|
||||
+ "\tTo: to_email@test.com\n\n" \
|
||||
+ " - Ajouter un contact à votre roster, avec comme JID " \
|
||||
+ "to_email\%test.com@jmc.test.com, où to_email@test.com est " \
|
||||
+ "l'adresse du destinataire."
|
||||
+ u"entre :\n" \
|
||||
+ u" - Envoyer un message à la passerelle JMC: le sujet de l'email" \
|
||||
+ u" sera le sujet du message Jabber ou le sujet spécifié avec la " \
|
||||
+ u"syntaxe suivant dans le corps du message Jabber :\n" \
|
||||
+ u"\tSubject: votre sujet\n" \
|
||||
+ u" Pour spécifier les destinataires de l'email, il faut ajouter une" \
|
||||
+ u" ligne au corps du message Jabber avec la syntaxe suivante:\n" \
|
||||
+ u"\tTo: to_email@test.com\n\n" \
|
||||
+ u" - Ajouter un contact à votre roster, avec comme JID " \
|
||||
+ u"to_email\%test.com@jmc.test.com, où to_email@test.com est " \
|
||||
+ u"l'adresse du destinataire."
|
||||
|
||||
class nl(jcl.lang.Lang.nl):
|
||||
# TODO: when finish, delete this line and uncomment in tests/lang.py the makeSuite(Language_nl_TestCase, 'test') line
|
||||
|
||||
@@ -373,6 +373,7 @@ class MailAccount(PresenceAccount):
|
||||
|
||||
class IMAPAccount(MailAccount):
|
||||
mailbox = StringCol(default="INBOX")
|
||||
delimiter = StringCol(default=".")
|
||||
|
||||
def _get_register_fields(cls, real_class=None):
|
||||
"""See Account._get_register_fields
|
||||
@@ -397,13 +398,19 @@ class IMAPAccount(MailAccount):
|
||||
self.__logger = logging.getLogger("jmc.IMAPConnection")
|
||||
self._regexp_list = re.compile("\((.*)\) \"(.)\" \"?([^\"]*)\"?$")
|
||||
self.__cached_folders = {}
|
||||
self.default_delimiter = "."
|
||||
|
||||
def get_type(self):
|
||||
if self.ssl:
|
||||
return "imaps"
|
||||
return "imap"
|
||||
|
||||
def _get_real_mailbox(self):
|
||||
"""
|
||||
mailbox attribute is stored with "/" to delimit folders.
|
||||
real mailbox is the folder with the delimiter used by the IMAP server
|
||||
"""
|
||||
return self.mailbox.replace("/", self.delimiter)
|
||||
|
||||
def get_status(self):
|
||||
return MailAccount.get_status(self) + "/" + self.mailbox
|
||||
|
||||
@@ -427,7 +434,7 @@ class IMAPAccount(MailAccount):
|
||||
|
||||
def get_mail_list(self):
|
||||
self.__logger.debug("Getting mail list")
|
||||
typ, data = self.connection.select(self.mailbox)
|
||||
typ, data = self.connection.select(self._get_real_mailbox())
|
||||
typ, data = self.connection.search(None, 'RECENT')
|
||||
if typ == 'OK':
|
||||
return data[0].split(' ')
|
||||
@@ -476,8 +483,8 @@ class IMAPAccount(MailAccount):
|
||||
for line in data:
|
||||
match = self._regexp_list.match(line)
|
||||
if match is not None:
|
||||
self.default_delimiter = match.group(2)
|
||||
subdir = match.group(3).split(self.default_delimiter)
|
||||
delimiter = match.group(2)
|
||||
subdir = match.group(3).split(delimiter)
|
||||
self._add_full_path_to_cache(subdir)
|
||||
return self.__cached_folders
|
||||
|
||||
@@ -485,7 +492,6 @@ class IMAPAccount(MailAccount):
|
||||
"""
|
||||
imap_dir: IMAP directory to list. subdirs must be delimited by '/'
|
||||
"""
|
||||
# TODO : implement with cache (ie. only one connection)
|
||||
self.__logger.debug("Listing IMAP dir '" + str(imap_dir) + "'")
|
||||
if self.__cached_folders == {}:
|
||||
if not self.connected:
|
||||
@@ -504,6 +510,31 @@ class IMAPAccount(MailAccount):
|
||||
current_folder = current_folder[folder]
|
||||
return current_folder.keys()
|
||||
|
||||
def populate_handler(self):
|
||||
"""
|
||||
Handler called when populating account
|
||||
"""
|
||||
# Get delimiter
|
||||
if not self.connected:
|
||||
self.connect()
|
||||
typ, data = self.connection.list(self.mailbox)
|
||||
if typ == 'OK':
|
||||
line = data[0]
|
||||
match = self._regexp_list.match(line)
|
||||
if match is not None:
|
||||
self.delimiter = match.group(2)
|
||||
else:
|
||||
self.disconnect()
|
||||
raise Exception("Cannot find mailbox " + self.mailbox)
|
||||
else:
|
||||
self.disconnect()
|
||||
raise Exception("Cannot find mailbox " + self.mailbox)
|
||||
self.disconnect()
|
||||
# replace any previous delimiter in self.mailbox by "/"
|
||||
if self.delimiter != "/":
|
||||
self.mailbox = self.mailbox.replace(self.delimiter, "/")
|
||||
|
||||
|
||||
class POP3Account(MailAccount):
|
||||
nb_mail = IntCol(default=0)
|
||||
lastmail = IntCol(default=0)
|
||||
|
||||
@@ -242,8 +242,8 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
|
||||
self.imap_account.ssl = False
|
||||
self.account_class = IMAPAccount
|
||||
|
||||
def make_test(responses=None, queries=None, core=None):
|
||||
def inner(self):
|
||||
def make_test(self, responses=None, queries=None, core=None):
|
||||
def inner():
|
||||
self.server = server.DummyServer("localhost", 1143)
|
||||
thread.start_new_thread(self.server.serve, ())
|
||||
self.server.responses = ["* OK [CAPABILITY IMAP4 LOGIN-REFERRALS " + \
|
||||
@@ -261,20 +261,25 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
|
||||
if queries:
|
||||
self.server.queries += queries
|
||||
self.server.queries += ["^[^ ]* LOGOUT"]
|
||||
self.imap_account.connect()
|
||||
if not self.imap_account.connected:
|
||||
self.imap_account.connect()
|
||||
self.failUnless(self.imap_account.connection, \
|
||||
"Cannot establish connection")
|
||||
if core:
|
||||
model.db_connect()
|
||||
core(self)
|
||||
model.db_disconnect()
|
||||
self.imap_account.disconnect()
|
||||
if self.imap_account.connected:
|
||||
self.imap_account.disconnect()
|
||||
self.failUnless(self.server.verify_queries())
|
||||
return inner
|
||||
|
||||
test_connection = make_test()
|
||||
def test_connection(self):
|
||||
test_func = self.make_test()
|
||||
test_func()
|
||||
|
||||
test_get_mail_list = make_test([lambda data: "* 42 EXISTS\n* 1 RECENT\n* OK" +\
|
||||
def test_get_mail_list(self):
|
||||
test_func = self.make_test([lambda data: "* 42 EXISTS\n* 1 RECENT\n* OK" +\
|
||||
" [UNSEEN 9]\n* FLAGS (\Deleted \Seen\*)\n*" +\
|
||||
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\n" + \
|
||||
data.split()[0] + \
|
||||
@@ -285,22 +290,60 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
|
||||
"^[^ ]* SEARCH RECENT"], \
|
||||
lambda self: \
|
||||
self.assertEquals(self.imap_account.get_mail_list(), ['9', '10']))
|
||||
test_func()
|
||||
|
||||
test_get_mail_summary = make_test([lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
|
||||
" [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\
|
||||
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
|
||||
data.split()[0] + \
|
||||
" OK [READ-WRITE] SELECT completed\r\n", \
|
||||
lambda data: "* 1 FETCH ((RFC822) {12}\r\nbody" + \
|
||||
" text\r\n)\r\n" + \
|
||||
data.split()[0] + " OK FETCH completed\r\n"], \
|
||||
["^[^ ]* EXAMINE INBOX", \
|
||||
"^[^ ]* FETCH 1 \(RFC822\)"], \
|
||||
lambda self: self.assertEquals(self.imap_account.get_mail_summary(1), \
|
||||
(u"From : None\nSubject : None\n\n", \
|
||||
u"None")))
|
||||
def test_get_mail_list_delimiter1(self):
|
||||
self.imap_account.mailbox = "INBOX/dir1/subdir2"
|
||||
self.imap_account.delimiter = "."
|
||||
test_func = self.make_test( \
|
||||
[lambda data: "* 42 EXISTS\n* 1 RECENT\n* OK" + \
|
||||
" [UNSEEN 9]\n* FLAGS (\Deleted \Seen\*)\n*" + \
|
||||
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\n" + \
|
||||
data.split()[0] + \
|
||||
" OK [READ-WRITE] SELECT completed\n", \
|
||||
lambda data: "* SEARCH 9 10 \n" + \
|
||||
data.split()[0] + " OK SEARCH completed\n"], \
|
||||
["^[^ ]* SELECT \"?INBOX\.dir1\.subdir2\"?",
|
||||
"^[^ ]* SEARCH RECENT"], \
|
||||
lambda self: \
|
||||
self.assertEquals(self.imap_account.get_mail_list(), ['9', '10']))
|
||||
test_func()
|
||||
|
||||
test_get_mail = make_test([lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
|
||||
def test_get_mail_list_delimiter2(self):
|
||||
self.imap_account.mailbox = "INBOX/dir1/subdir2"
|
||||
self.imap_account.delimiter = "/"
|
||||
test_func = self.make_test( \
|
||||
[lambda data: "* 42 EXISTS\n* 1 RECENT\n* OK" + \
|
||||
" [UNSEEN 9]\n* FLAGS (\Deleted \Seen\*)\n*" + \
|
||||
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\n" + \
|
||||
data.split()[0] + \
|
||||
" OK [READ-WRITE] SELECT completed\n", \
|
||||
lambda data: "* SEARCH 9 10 \n" + \
|
||||
data.split()[0] + " OK SEARCH completed\n"], \
|
||||
["^[^ ]* SELECT \"?INBOX/dir1/subdir2\"?",
|
||||
"^[^ ]* SEARCH RECENT"], \
|
||||
lambda self: \
|
||||
self.assertEquals(self.imap_account.get_mail_list(), ['9', '10']))
|
||||
test_func()
|
||||
|
||||
def test_get_mail_summary(self):
|
||||
test_func = self.make_test([lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
|
||||
" [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\
|
||||
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
|
||||
data.split()[0] + \
|
||||
" OK [READ-WRITE] SELECT completed\r\n", \
|
||||
lambda data: "* 1 FETCH ((RFC822) {12}\r\nbody" + \
|
||||
" text\r\n)\r\n" + \
|
||||
data.split()[0] + " OK FETCH completed\r\n"],
|
||||
["^[^ ]* EXAMINE INBOX",
|
||||
"^[^ ]* FETCH 1 \(RFC822\)"],
|
||||
lambda self: self.assertEquals(self.imap_account.get_mail_summary(1),
|
||||
(u"From : None\nSubject : None\n\n",
|
||||
u"None")))
|
||||
test_func()
|
||||
|
||||
def test_get_mail(self):
|
||||
test_func = self.make_test([lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
|
||||
" [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\
|
||||
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
|
||||
data.split()[0] + \
|
||||
@@ -313,8 +356,10 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
|
||||
lambda self: self.assertEquals(self.imap_account.get_mail(1), \
|
||||
(u"From : None\nSubject : None\n\nbody text\r\n\n", \
|
||||
u"None")))
|
||||
test_func()
|
||||
|
||||
test_build_folder_cache = make_test(\
|
||||
def test_build_folder_cache(self):
|
||||
test_func = self.make_test(\
|
||||
[lambda data: '* LIST () "." "INBOX"\r\n' + \
|
||||
'* LIST () "." "INBOX.dir1"\r\n' + \
|
||||
'* LIST () "." "INBOX.dir1.subdir1"\r\n' + \
|
||||
@@ -328,6 +373,7 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
|
||||
{"subdir1": {},
|
||||
"subdir2": {}},
|
||||
"dir2": {}}}))
|
||||
test_func()
|
||||
|
||||
def test_ls_dir_base(self):
|
||||
self.test_build_folder_cache()
|
||||
@@ -356,6 +402,34 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
|
||||
self.assertEquals(result,
|
||||
["subdir1", "subdir2"])
|
||||
|
||||
def test_populate_handler(self):
|
||||
self.assertEquals(".", self.imap_account.delimiter)
|
||||
self.imap_account.mailbox = "INBOX.dir1.subdir2"
|
||||
def call_func(self):
|
||||
self.imap_account.populate_handler()
|
||||
self.assertEquals("INBOX/dir1/subdir2", self.imap_account.mailbox)
|
||||
test_func = self.make_test(\
|
||||
[lambda data: '* LIST () "." "INBOX.dir1.subdir2"\r\n' + \
|
||||
data.split()[0] + ' OK LIST completed\r\n'],
|
||||
["^[^ ]* LIST \"?INBOX.dir1.subdir2\"? \*"],
|
||||
call_func)
|
||||
test_func()
|
||||
|
||||
def test_populate_handler_wrong_mailbox(self):
|
||||
self.assertEquals(".", self.imap_account.delimiter)
|
||||
self.imap_account.mailbox = "INBOX.dir1.subdir2"
|
||||
def call_func(self):
|
||||
try:
|
||||
self.imap_account.populate_handler()
|
||||
except Exception, e:
|
||||
return
|
||||
self.fail("Exception should have been raised")
|
||||
test_func = self.make_test(\
|
||||
[lambda data: data.split()[0] + ' ERR LIST completed\r\n'],
|
||||
["^[^ ]* LIST \"?INBOX.dir1.subdir2\"? \*"],
|
||||
call_func)
|
||||
test_func()
|
||||
|
||||
class SMTPAccount_TestCase(Account_TestCase):
|
||||
def setUp(self):
|
||||
JCLTestCase.setUp(self, tables=[Account, ExampleAccount, User,
|
||||
|
||||
Reference in New Issue
Block a user