mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-05-21 11:25:24 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user