Added methods for PROPFIND

Monotone-Parent: 2b6cf9ec13774912de440dcfe08a03df4a580d4e
Monotone-Revision: 8db3f67f47d18d68431d7ffb603fcf636ac4bc9b

Monotone-Author: crobert@inverse.ca
Monotone-Date: 2009-10-01T20:16:52
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
C Robert
2009-10-01 20:16:52 +00:00
parent bf093a8053
commit 7524610f5c
3 changed files with 251 additions and 1 deletions
+9
View File
@@ -1,3 +1,12 @@
2009-10-01 Cyril Robert <crobert@inverse.ca>
* SoObjects/Mailer/SOGoMailObject.m: Added methods required for PROPFIND /
REPORT: _fetchProperty:, _hasFlag:, _emailAddressesFrom:, davDate,
hasAttachment, read, textDescription, cc, from, inReplyTo, messageId,
received, references, davDisplayName, to
* Tests/test-maildav.py (testPROPFIND): Added tests for the new MailDAV
PROPFIND.
2009-10-01 Cyril Robert <crobert@inverse.ca>
* SoObjects/Mailer/SOGoMailFolder.m
+180
View File
@@ -1269,4 +1269,184 @@ static BOOL debugSoParts = NO;
return response;
}
// For DAV REPORT
- (id) _fetchProperty: (NSString *) property
{
NSArray *parts;
id rc, msgs;
rc = nil;
if (property)
{
parts = [NSArray arrayWithObjects: property, nil];
msgs = [self fetchParts: parts];
msgs = [msgs valueForKey: @"fetch"];
if ([msgs count]) {
rc = [msgs objectAtIndex: 0];
}
}
return rc;
}
- (BOOL) _hasFlag: (NSString *) flag
{
BOOL rc;
NSDictionary *values;
NSArray *flags;
rc = NO;
values = [self _fetchProperty: @"FLAGS"];
if (values)
{
flags = [values objectForKey: @"flags"];
rc = [flags containsObject: flag];
}
return rc;
}
- (NSString *) _emailAddressesFrom: (NSArray *) enveloppeAddresses
{
//voir spec
NSMutableArray *addresses;
NSString *rc;
NGImap4EnvelopeAddress *address;
NSString *email;
int count, max;
rc = nil;
max = [enveloppeAddresses count];
if (max > 0)
{
addresses = [NSMutableArray array];
for (count = 0; count < max; count++)
{
address = [enveloppeAddresses objectAtIndex: count];
email = [NSString stringWithFormat: @"%@", [address email]];
[addresses addObject: email];
}
rc = [addresses componentsJoinedByString: @", "];
}
return rc;
}
// Properties
//{urn:schemas:httpmail:}
// date already exists, but this one is the correct format
- (NSString *) davDate
{
return [[self date]
descriptionWithCalendarFormat: @"%a, %d %b %Y %H:%M:%S %z"];
}
- (BOOL) hasAttachment
{
return ([[self fetchAttachmentIds] count] > 0);
}
- (BOOL) read
{
return [self _hasFlag: @"seen"];
}
- (NSString *) textDescription
{
return [NSString stringWithFormat: @"<![CDATA[%@]]>", [self contentAsString]];
}
//{urn:schemas:mailheader:}
- (NSString *) cc
{
return [self _emailAddressesFrom: [self ccEnvelopeAddresses]];
}
- (NSString *) from
{
return [self _emailAddressesFrom: [self fromEnvelopeAddresses]];
}
- (NSString *) inReplyTo
{
return [[self envelope] inReplyTo];
}
- (NSString *) messageId
{
return [[self envelope] messageID];
}
- (NSString *) received
{
NSDictionary *fetch;
NSData *data;
NSString *value, *rc;
NSRange range;
rc = nil;
fetch = [self _fetchProperty: @"BODY[HEADER.FIELDS (RECEIVED)]"];
if ([fetch count])
{
data = [fetch objectForKey: @"header"];
value = [[NSString alloc] initWithData: data
encoding: NSUTF8StringEncoding];
range = [value rangeOfString: @"received:"
options: NSCaseInsensitiveSearch
range: NSMakeRange (10, [value length]-11)];
if (range.length)
{
// We want to keep the first part
range.length = range.location;
range.location = 0;
rc = [[value substringWithRange: range] stringByTrimmingSpaces];
}
else
rc = [value stringByTrimmingSpaces];
[value release];
}
return rc;
}
- (NSString *) references
{
NSDictionary *fetch;
NSData *data;
NSString *value, *rc;;
rc = nil;
fetch = [self _fetchProperty: @"BODY[HEADER.FIELDS (REFERENCES)]"];
if ([fetch count])
{
data = [fetch objectForKey: @"header"];
value = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
rc = [[value substringFromIndex: 11] stringByTrimmingSpaces];
[value release];
}
return rc;
}
- (NSString *) davDisplayName
{
return [self subject];
}
- (NSString *) to
{
return [self _emailAddressesFrom: [self toEnvelopeAddresses]];
}
@end /* SOGoMailObject */
+62 -1
View File
@@ -26,15 +26,19 @@ message1 = """Return-Path: <cyril@cyril.dev>
Received: from cyril.dev (localhost [127.0.0.1])
by cyril.dev (Cyrus v2.3.8-Debian-2.3.8-1) with LMTPA;
Tue, 29 Sep 2009 07:42:16 -0400
Received: from aloha.dev (localhost [127.0.0.1])
by aloha.dev (Cyrus v2.3.8-Debian-2.3.8-1) with LMTPA;
Tue, 29 Sep 2009 07:42:16 -0400
X-Virus-Scanned: Debian amavisd-new at inverse.ca
Message-ID: <4AC1F296.5060801@cyril.dev>
References: <4AC3BF1B.3010806@inverse.ca>
Date: Tue, 29 Sep 2009 07:42:14 -0400
From: Cyril <cyril@cyril.dev>
Organization: Inverse inc.
User-Agent: Thunderbird 2.0.0.22 (Macintosh/20090605)
MIME-Version: 1.0
To: jacques@cyril.dev
CC: support@inverse.ca
CC: support@inverse.ca, user10@cyril.dev
Subject: Hallo
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
@@ -47,6 +51,9 @@ Can you read me?
--
Cyril <cyril@cyril.dev>
"""
message1_received = """Received: from cyril.dev (localhost [127.0.0.1])
by cyril.dev (Cyrus v2.3.8-Debian-2.3.8-1) with LMTPA;
Tue, 29 Sep 2009 07:42:16 -0400"""
class DAVMailCollectionTest(unittest.TestCase):
resource = '/SOGo/dav/%s/Mail/' % username
@@ -93,6 +100,23 @@ class DAVMailCollectionTest(unittest.TestCase):
" expected status code '%d' (received '%d')"
% (filename, exp_status, put.response["status"]))
def _testProperty (self, url, property, expected):
propfind = webdavlib.WebDAVPROPFIND(url, (property, ), 0)
self.client.execute(propfind)
key = property.replace("{urn:schemas:httpmail:}", "a:")
key = key.replace("{urn:schemas:mailheader:}", "a:")
tmp = propfind.xpath_evaluate("/D:multistatus/D:response/D:propstat/D:prop")
prop = tmp[0].firstChild;
result = None
if prop:
result = prop._get_firstChild()._get_nodeValue()
#print key, result
self.assertEquals(result, expected,
"failure in propfind"
"(%s != %s)" % (result, expected))
def testMKCOL(self):
"""Folder creation"""
self._makeCollection ("test-dav-mail-%40-abc")
@@ -153,5 +177,42 @@ class DAVMailCollectionTest(unittest.TestCase):
self._deleteCollection ("test-dav-mail")
def testPROPFIND(self):
"""Message properties"""
self._deleteCollection ("test-dav-mail")
self._makeCollection ("test-dav-mail")
url = "%s%s" % (self.resource, "foldertest-dav-mail/")
put = webdavlib.HTTPPUT (url, message1)
put.content_type = "message/rfc822"
self.client.execute (put)
self.assertEquals(put.response["status"], 201,
"failure putting message"
"(code = %d)" % put.response["status"])
itemLocation = put.response["headers"]["location"]
tests = (("{urn:schemas:httpmail:}date", "Tue, 29 Sep 2009 11:42:14 GMT"),
("{urn:schemas:httpmail:}hasattachment", "0"),
("{urn:schemas:httpmail:}read", "0"),
("{urn:schemas:httpmail:}textdescription",
"<![CDATA[%s]]>" % message1),
("{urn:schemas:httpmail:}unreadcount", None),
("{urn:schemas:mailheader:}cc","support@inverse.ca, user10@cyril.dev"),
("{urn:schemas:mailheader:}date", "Tue, 29 Sep 2009 11:42:14 GMT"),
("{urn:schemas:mailheader:}from", "Cyril <cyril@cyril.dev>"),
("{urn:schemas:mailheader:}in-reply-to", None),
("{urn:schemas:mailheader:}message-id","<4AC1F296.5060801@cyril.dev>"),
("{urn:schemas:mailheader:}received", message1_received),
("{urn:schemas:mailheader:}references", "<4AC3BF1B.3010806@inverse.ca>"),
("{urn:schemas:mailheader:}subject", "Hallo"),
("{urn:schemas:mailheader:}to", "jacques@cyril.dev"))
for test in tests:
property, expected = test
self._testProperty(itemLocation, property, expected)
self._deleteCollection ("test-dav-mail")
if __name__ == "__main__":
unittest.main()