Browse IMAP folders in service discovery
darcs-hash:20071022182523-86b55-444ef63ae52e5a0f274a1ab3bea89d9fc91ae1fb.gz
This commit is contained in:
@@ -110,20 +110,17 @@ class IMAPAccountDiscoGetItemsHandler(DiscoHandler):
|
|||||||
if account_class is not None and _account is not None:
|
if account_class is not None and _account is not None:
|
||||||
disco_items = DiscoItems()
|
disco_items = DiscoItems()
|
||||||
if imap_dir is None:
|
if imap_dir is None:
|
||||||
# TODO : test if INBOX really exist, is it possible to retrieve default dir from IMAP ?
|
imap_dir = ""
|
||||||
|
subdirs = _account.ls_dir(imap_dir)
|
||||||
|
if imap_dir != "":
|
||||||
|
imap_dir += "/"
|
||||||
|
for subdir in subdirs:
|
||||||
DiscoItem(disco_items,
|
DiscoItem(disco_items,
|
||||||
JID(unicode(_account.jid) + "/" + account_type
|
JID(unicode(_account.jid) + "/" + account_type + \
|
||||||
+ "/INBOX"),
|
"/" + imap_dir + subdir),
|
||||||
account_type + "/" + account_name + "/INBOX",
|
account_type + "/" + account_name + "/" + imap_dir
|
||||||
"INBOX")
|
+ subdir,
|
||||||
else:
|
subdir)
|
||||||
for subdir in _account.ls_dir(imap_dir):
|
|
||||||
DiscoItem(disco_items,
|
|
||||||
JID(unicode(_account.jid) + "/" + account_type + \
|
|
||||||
"/" + imap_dir + "/" + subdir),
|
|
||||||
account_type + "/" + account_name + "/" + imap_dir
|
|
||||||
+ "/" + subdir,
|
|
||||||
subdir)
|
|
||||||
return [disco_items]
|
return [disco_items]
|
||||||
return []
|
return []
|
||||||
# TODO : implement get_info on imap_Dir
|
|
||||||
|
|||||||
@@ -145,7 +145,9 @@ class MockIMAPAccount(MockMailAccount, IMAPAccount):
|
|||||||
MockMailAccount._init(self)
|
MockMailAccount._init(self)
|
||||||
|
|
||||||
def ls_dir(self, imap_dir):
|
def ls_dir(self, imap_dir):
|
||||||
if imap_dir == "INBOX":
|
if imap_dir == "":
|
||||||
|
return ["INBOX"]
|
||||||
|
elif imap_dir == "INBOX":
|
||||||
return ["dir1", "dir2"]
|
return ["dir1", "dir2"]
|
||||||
elif imap_dir == "INBOX/dir1":
|
elif imap_dir == "INBOX/dir1":
|
||||||
return ["subdir1", "subdir2"]
|
return ["subdir1", "subdir2"]
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
##
|
##
|
||||||
|
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
import email
|
import email
|
||||||
@@ -394,6 +395,9 @@ class IMAPAccount(MailAccount):
|
|||||||
def _init(self, *args, **kw):
|
def _init(self, *args, **kw):
|
||||||
MailAccount._init(self, *args, **kw)
|
MailAccount._init(self, *args, **kw)
|
||||||
self.__logger = logging.getLogger("jmc.IMAPConnection")
|
self.__logger = logging.getLogger("jmc.IMAPConnection")
|
||||||
|
self._regexp_list = re.compile("\((.*)\) \"(.)\" \"?([^\"]*)\"?$")
|
||||||
|
self.__cached_folders = {}
|
||||||
|
self.default_delimiter = "."
|
||||||
|
|
||||||
def get_type(self):
|
def get_type(self):
|
||||||
if self.ssl:
|
if self.ssl:
|
||||||
@@ -404,15 +408,15 @@ class IMAPAccount(MailAccount):
|
|||||||
return MailAccount.get_status(self) + "/" + self.mailbox
|
return MailAccount.get_status(self) + "/" + self.mailbox
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
self.__logger.debug("Connecting to IMAP server "
|
self.__logger.debug("Connecting to IMAP server "
|
||||||
+ self.login + "@" + self.host + ":" + str(self.port)
|
+ self.login + "@" + self.host + ":" + str(self.port)
|
||||||
+ " (" + self.mailbox + "). SSL="
|
+ " (" + self.mailbox + "). SSL="
|
||||||
+ str(self.ssl))
|
+ str(self.ssl))
|
||||||
if self.ssl:
|
if self.ssl:
|
||||||
self.connection = MYIMAP4_SSL(self.host, self.port)
|
self.connection = MYIMAP4_SSL(self.host, self.port)
|
||||||
else:
|
else:
|
||||||
self.connection = MYIMAP4(self.host, self.port)
|
self.connection = MYIMAP4(self.host, self.port)
|
||||||
self.connection.login(self.login, self.password)
|
self.connection.login(self.login, self.password)
|
||||||
self.connected = True
|
self.connected = True
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
@@ -458,6 +462,48 @@ class IMAPAccount(MailAccount):
|
|||||||
|
|
||||||
type = property(get_type)
|
type = property(get_type)
|
||||||
|
|
||||||
|
def _add_full_path_to_cache(self, folder_array):
|
||||||
|
current_dir = self.__cached_folders
|
||||||
|
for folder in folder_array:
|
||||||
|
if not current_dir.has_key(folder):
|
||||||
|
current_dir[folder] = {}
|
||||||
|
current_dir = current_dir[folder]
|
||||||
|
|
||||||
|
def _build_folder_cache(self):
|
||||||
|
if self.connected:
|
||||||
|
typ, data = self.connection.list()
|
||||||
|
if typ == 'OK':
|
||||||
|
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)
|
||||||
|
self._add_full_path_to_cache(subdir)
|
||||||
|
return self.__cached_folders
|
||||||
|
|
||||||
|
def ls_dir(self, imap_dir):
|
||||||
|
"""
|
||||||
|
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:
|
||||||
|
self.connect()
|
||||||
|
self._build_folder_cache()
|
||||||
|
self.disconnect()
|
||||||
|
if imap_dir == "":
|
||||||
|
folder_array = []
|
||||||
|
else:
|
||||||
|
folder_array = imap_dir.split('/')
|
||||||
|
current_folder = self.__cached_folders
|
||||||
|
for folder in folder_array:
|
||||||
|
if not current_folder.has_key(folder):
|
||||||
|
return []
|
||||||
|
else:
|
||||||
|
current_folder = current_folder[folder]
|
||||||
|
return current_folder.keys()
|
||||||
|
|
||||||
class POP3Account(MailAccount):
|
class POP3Account(MailAccount):
|
||||||
nb_mail = IntCol(default=0)
|
nb_mail = IntCol(default=0)
|
||||||
lastmail = IntCol(default=0)
|
lastmail = IntCol(default=0)
|
||||||
|
|||||||
@@ -314,6 +314,48 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
|
|||||||
(u"From : None\nSubject : None\n\nbody text\r\n\n", \
|
(u"From : None\nSubject : None\n\nbody text\r\n\n", \
|
||||||
u"None")))
|
u"None")))
|
||||||
|
|
||||||
|
test_build_folder_cache = make_test(\
|
||||||
|
[lambda data: '* LIST () "." "INBOX"\r\n' + \
|
||||||
|
'* LIST () "." "INBOX.dir1"\r\n' + \
|
||||||
|
'* LIST () "." "INBOX.dir1.subdir1"\r\n' + \
|
||||||
|
'* LIST () "." "INBOX.dir1.subdir2"\r\n' + \
|
||||||
|
'* LIST () "." "INBOX.dir2"\r\n' + \
|
||||||
|
data.split()[0] + ' OK LIST completed\r\n'],
|
||||||
|
["^[^ ]* LIST \"\" \*"],
|
||||||
|
lambda self: self.assertEquals(self.imap_account._build_folder_cache(),
|
||||||
|
{"INBOX":
|
||||||
|
{"dir1":
|
||||||
|
{"subdir1": {},
|
||||||
|
"subdir2": {}},
|
||||||
|
"dir2": {}}}))
|
||||||
|
|
||||||
|
def test_ls_dir_base(self):
|
||||||
|
self.test_build_folder_cache()
|
||||||
|
self.assertEquals(self.imap_account.ls_dir(""),
|
||||||
|
["INBOX"])
|
||||||
|
|
||||||
|
def test_ls_dir_subdir(self):
|
||||||
|
self.test_build_folder_cache()
|
||||||
|
result = self.imap_account.ls_dir("INBOX")
|
||||||
|
result.sort()
|
||||||
|
self.assertEquals(result,
|
||||||
|
["dir1", "dir2"])
|
||||||
|
|
||||||
|
def test_ls_dir_subsubdir_delim1(self):
|
||||||
|
self.test_build_folder_cache()
|
||||||
|
self.imap_account.default_delimiter = "."
|
||||||
|
result = self.imap_account.ls_dir("INBOX/dir1")
|
||||||
|
result.sort()
|
||||||
|
self.assertEquals(result,
|
||||||
|
["subdir1", "subdir2"])
|
||||||
|
|
||||||
|
def test_ls_dir_subsubdir_delim2(self):
|
||||||
|
self.test_build_folder_cache()
|
||||||
|
result = self.imap_account.ls_dir("INBOX/dir1")
|
||||||
|
result.sort()
|
||||||
|
self.assertEquals(result,
|
||||||
|
["subdir1", "subdir2"])
|
||||||
|
|
||||||
class SMTPAccount_TestCase(Account_TestCase):
|
class SMTPAccount_TestCase(Account_TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
JCLTestCase.setUp(self, tables=[Account, ExampleAccount, User,
|
JCLTestCase.setUp(self, tables=[Account, ExampleAccount, User,
|
||||||
|
|||||||
Reference in New Issue
Block a user