Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dax/jmc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src/jmc
diff options
context:
space:
mode:
authorDavid Rousselie <dax@happycoders.org>2007-10-22 22:25:23 +0400
committerDavid Rousselie <dax@happycoders.org>2007-10-22 22:25:23 +0400
commit98510aa128b0848dcbb3cd1e9acbb8a7fc5a8460 (patch)
tree5317cf7fa60130655ed963f896c6183aeabb5961 /src/jmc
parent95564d826ed562d54ce7dc61e055dc716def428f (diff)
Browse IMAP folders in service discovery
darcs-hash:20071022182523-86b55-444ef63ae52e5a0f274a1ab3bea89d9fc91ae1fb.gz
Diffstat (limited to 'src/jmc')
-rw-r--r--src/jmc/jabber/disco.py25
-rw-r--r--src/jmc/jabber/tests/component.py4
-rw-r--r--src/jmc/model/account.py58
-rw-r--r--src/jmc/model/tests/account.py42
4 files changed, 108 insertions, 21 deletions
diff --git a/src/jmc/jabber/disco.py b/src/jmc/jabber/disco.py
index 3ba004e..e398fbb 100644
--- a/src/jmc/jabber/disco.py
+++ b/src/jmc/jabber/disco.py
@@ -110,20 +110,17 @@ class IMAPAccountDiscoGetItemsHandler(DiscoHandler):
if account_class is not None and _account is not None:
disco_items = DiscoItems()
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,
- JID(unicode(_account.jid) + "/" + account_type
- + "/INBOX"),
- account_type + "/" + account_name + "/INBOX",
- "INBOX")
- else:
- 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)
+ JID(unicode(_account.jid) + "/" + account_type + \
+ "/" + imap_dir + subdir),
+ account_type + "/" + account_name + "/" + imap_dir
+ + subdir,
+ subdir)
return [disco_items]
return []
-# TODO : implement get_info on imap_Dir
+
diff --git a/src/jmc/jabber/tests/component.py b/src/jmc/jabber/tests/component.py
index 88893af..a99b265 100644
--- a/src/jmc/jabber/tests/component.py
+++ b/src/jmc/jabber/tests/component.py
@@ -145,7 +145,9 @@ class MockIMAPAccount(MockMailAccount, IMAPAccount):
MockMailAccount._init(self)
def ls_dir(self, imap_dir):
- if imap_dir == "INBOX":
+ if imap_dir == "":
+ return ["INBOX"]
+ elif imap_dir == "INBOX":
return ["dir1", "dir2"]
elif imap_dir == "INBOX/dir1":
return ["subdir1", "subdir2"]
diff --git a/src/jmc/model/account.py b/src/jmc/model/account.py
index 4502e44..abdcc02 100644
--- a/src/jmc/model/account.py
+++ b/src/jmc/model/account.py
@@ -21,6 +21,7 @@
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
+import re
import sys
import logging
import email
@@ -394,6 +395,9 @@ class IMAPAccount(MailAccount):
def _init(self, *args, **kw):
MailAccount._init(self, *args, **kw)
self.__logger = logging.getLogger("jmc.IMAPConnection")
+ self._regexp_list = re.compile("\((.*)\) \"(.)\" \"?([^\"]*)\"?$")
+ self.__cached_folders = {}
+ self.default_delimiter = "."
def get_type(self):
if self.ssl:
@@ -404,15 +408,15 @@ class IMAPAccount(MailAccount):
return MailAccount.get_status(self) + "/" + self.mailbox
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.mailbox + "). SSL="
+ str(self.ssl))
- if self.ssl:
- self.connection = MYIMAP4_SSL(self.host, self.port)
- else:
- self.connection = MYIMAP4(self.host, self.port)
- self.connection.login(self.login, self.password)
+ if self.ssl:
+ self.connection = MYIMAP4_SSL(self.host, self.port)
+ else:
+ self.connection = MYIMAP4(self.host, self.port)
+ self.connection.login(self.login, self.password)
self.connected = True
def disconnect(self):
@@ -458,6 +462,48 @@ class IMAPAccount(MailAccount):
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):
nb_mail = IntCol(default=0)
lastmail = IntCol(default=0)
diff --git a/src/jmc/model/tests/account.py b/src/jmc/model/tests/account.py
index e27da20..a99b88d 100644
--- a/src/jmc/model/tests/account.py
+++ b/src/jmc/model/tests/account.py
@@ -314,6 +314,48 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
(u"From : None\nSubject : None\n\nbody text\r\n\n", \
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):
def setUp(self):
JCLTestCase.setUp(self, tables=[Account, ExampleAccount, User,