+2004-10-04 Helge Hess <helge.hess@opengroupware.org>
+
+ * SOGoMailObject.m: added method to fetch core infos of a mail, added
+ various methods to retrieve core info data (like subject or date)
+ (v0.9.22)
+
2004-10-03 Helge Hess <helge.hess@opengroupware.org>
* v0.9.21
commands in NGImap4.
*/
+@class SOGoMailObject;
+
@interface SOGoMailBodyPart : SOGoMailBaseObject
{
}
+/* hierarchy */
+
+- (SOGoMailObject *)mailObject;
+
+/* IMAP4 */
+
+- (NSString *)bodyPartIdentifier;
+
@end
#endif /* __Mailer_SOGoMailBodyPart_H__ */
#include "SOGoMailBodyPart.h"
#include "SOGoMailObject.h"
+#include "SOGoMailManager.h"
#include "common.h"
@implementation SOGoMailBodyPart
return [[self container] mailObject];
}
+/* IMAP4 */
+
+- (NSString *)bodyPartIdentifier {
+ NSMutableString *ms;
+ id obj;
+
+ ms = [NSMutableString stringWithCapacity:16];
+ for (obj = self; [obj isKindOfClass:[SOGoMailBodyPart class]];
+ obj = [obj container]) {
+ NSString *s;
+ NSRange r;
+
+ s = [self nameInContainer];
+ r = [s rangeOfString:@"."]; /* strip extensions */
+ if (r.length > 0)
+ s = [s substringToIndex:r.location];
+
+ if ([ms length] > 0) {
+ [ms insertString:@"." atIndex:0];
+ [ms insertString:s atIndex:0];
+ }
+ else
+ [ms appendString:s];
+ }
+ return ms;
+}
+
+- (NSURL *)imap4URL {
+ /* reuse URL of message */
+ return [[self mailObject] imap4URL];
+}
+
/* name lookup */
- (id)lookupImap4BodyPartKey:(NSString *)_key inContext:(id)_ctx {
return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
}
+/* fetch */
+
+- (NSData *)fetchBLOB {
+ // HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, TEXT
+ return [[self mailManager] fetchContentOfBodyPart:[self bodyPartIdentifier]
+ atURL:[self imap4URL]
+ password:[self imap4Password]];
+}
+
+/* WebDAV */
+
+- (NSString *)davContentType {
+ // TODO: what about the content-type and other headers?
+ // => we could pass them in as the extension? (eg generate 1.gif!)
+ NSString *pe;
+
+ pe = [[self nameInContainer] pathExtension];
+ if ([pe length] == 0)
+ return @"application/octet-stream";
+
+ /* TODO: add some map */
+ if ([pe isEqualToString:@"gif"]) return @"image/gif";
+ if ([pe isEqualToString:@"png"]) return @"image/png";
+ if ([pe isEqualToString:@"jpg"]) return @"image/jpeg";
+ if ([pe isEqualToString:@"txt"]) return @"text/plain";
+
+ return @"application/octet-stream";
+}
+
+/* actions */
+
+- (id)GETAction:(WOContext *)_ctx {
+ WOResponse *r;
+ NSData *data;
+
+ [self debugWithFormat:@"should fetch body part: %@",
+ [self bodyPartIdentifier]];
+
+ if ((data = [self fetchBLOB]) == nil) {
+ return [NSException exceptionWithHTTPStatus:404 /* not found */
+ reason:@"did not find body part"];
+ }
+
+ [self debugWithFormat:@" fetched %d bytes.", [data length]];
+
+ r = [_ctx response];
+ [r setHeader:[self davContentType] forKey:@"content-type"];
+ [r setHeader:[NSString stringWithFormat:@"%d", [data length]]
+ forKey:@"content-length"];
+ [r setContent:data];
+ return r;
+}
+
@end /* SOGoMailBodyPart */
Coordinates access to IMAP4 mailboxes, caches folder hierarchies, etc.
*/
-@class NSString, NSURL, NSArray, NSMutableDictionary, NSTimer;
+@class NSString, NSData, NSURL, NSArray, NSMutableDictionary, NSTimer;
@class NGImap4Client;
@interface SOGoMailManager : NSObject
- (id)fetchURL:(NSURL *)_url parts:(NSArray *)_parts password:(NSString *)_pwd;
+- (NSData *)fetchContentOfBodyPart:(NSString *)_partId
+ atURL:(NSURL *)_url password:(NSString *)_pwd;
+
@end
#endif /* __Mailer_SOGoMailManager_H__ */
return (id)result;
}
+- (NSData *)fetchContentOfBodyPart:(NSString *)_partId
+ atURL:(NSURL *)_url password:(NSString *)_pwd
+{
+ NSString *key;
+ NSArray *parts;
+ id result, fetch, body;
+
+ if (_partId == nil) return nil;
+
+ key = [@"body[" stringByAppendingString:_partId];
+ key = [key stringByAppendingString:@"]"];
+ parts = [NSArray arrayWithObjects:&key count:1];
+
+ /* fetch */
+
+ result = [self fetchURL:_url parts:parts password:_pwd];
+
+ /* process results */
+
+ result = [result objectForKey:@"fetch"];
+ if ([result count] == 0) { /* did not find part */
+ [self logWithFormat:@"ERROR: did not find part: %@", _partId];
+ return nil;
+ }
+
+ fetch = [result objectAtIndex:0];
+ if ((body = [fetch objectForKey:@"body"]) == nil) {
+ [self logWithFormat:@"ERROR: did not find body in response: %@", result];
+ return nil;
+ }
+
+ if ((result = [body objectForKey:@"data"]) == nil) {
+ [self logWithFormat:@"ERROR: did not find data in body: %@", fetch];
+ return nil;
+ }
+ return result;
+}
+
/* debugging */
- (BOOL)isDebuggingEnabled {
would address the MIME part 1.2.3 of the mail 12345 in the folder INBOX.
*/
+@class NSString, NSArray, NSCalendarDate;
+@class NGImap4Envelope, NGImap4EnvelopeAddress;
+
@interface SOGoMailObject : SOGoMailBaseObject
{
+ id coreInfos;
}
/* message */
- (id)fetchParts:(NSArray *)_parts; /* Note: 'parts' are fetch keys here */
+/* core infos */
+
+- (id)fetchCoreInfos;
+
+- (NGImap4Envelope *)envelope;
+- (NSString *)subject;
+- (NSCalendarDate *)date;
+- (NGImap4EnvelopeAddress *)fromEnvelopeAddress;
+- (NSArray *)toEnvelopeAddresses;
+- (NSArray *)ccEnvelopeAddresses;
+
@end
#endif /* __Mailer_SOGoMailObject_H__ */
#include "SOGoMailObject.h"
#include "SOGoMailManager.h"
#include "SOGoMailBodyPart.h"
+#include <NGImap4/NGImap4Envelope.h>
+#include <NGImap4/NGImap4EnvelopeAddress.h>
#include "common.h"
@implementation SOGoMailObject
+static NSArray *coreInfoKeys = nil;
+
++ (void)initialize {
+ /* Note: see SOGoMailManager.m for allowed IMAP4 keys */
+ /* Note: "BODY" actually returns the structure! */
+ coreInfoKeys = [[NSArray alloc] initWithObjects:
+ @"FLAGS", @"ENVELOPE", @"BODY", nil];
+}
+
+- (void)dealloc {
+ [self->coreInfos release];
+ [super dealloc];
+}
+
/* IMAP4 */
- (NSString *)relativeImap4Name {
password:[self imap4Password]];
}
+/* core infos */
+
+- (id)fetchCoreInfos {
+ id msgs;
+
+ if (self->coreInfos != nil)
+ return [self->coreInfos isNotNull] ? self->coreInfos : nil;
+
+ msgs = [[self clientObject] fetchParts:coreInfoKeys]; // returns dict
+ // [self logWithFormat:@"M: %@", msgs];
+ msgs = [msgs valueForKey:@"fetch"];
+ if ([msgs count] == 0)
+ return nil;
+
+ self->coreInfos = [[msgs objectAtIndex:0] retain];
+ return self->coreInfos;
+}
+
+- (NGImap4Envelope *)envelope {
+ return [[self fetchCoreInfos] valueForKey:@"envelope"];
+}
+- (NSString *)subject {
+ return [[self envelope] subject];
+}
+- (NSCalendarDate *)date {
+ return [[self envelope] date];
+}
+- (NGImap4EnvelopeAddress *)fromEnvelopeAddress {
+ return [[self envelope] from];
+}
+- (NSArray *)toEnvelopeAddresses {
+ return [[self envelope] to];
+}
+- (NSArray *)ccEnvelopeAddresses {
+ return [[self envelope] cc];
+}
+
/* name lookup */
- (BOOL)isBodyPartKey:(NSString *)_key inContext:(id)_ctx {
# $Id$
-SUBMINOR_VERSION:=21
+SUBMINOR_VERSION:=22
+2004-10-04 Helge Hess <helge.hess@opengroupware.org>
+
+ * UIxMailView.m: use core infos stored in message SoObject for display
+ (v0.9.13)
+
2004-10-03 Helge Hess <helge.hess@opengroupware.org>
* v0.9.12
@interface UIxMailView : UIxComponent
{
- id message;
id currentAddress;
}
- (void)dealloc {
[self->currentAddress release];
- [self->message release];
[super dealloc];
}
- (void)sleep {
[self->currentAddress release]; self->currentAddress = nil;
- [self->message release]; self->message = nil;
[super sleep];
}
/* fetching */
-- (NSArray *)fetchKeys {
- /* Note: see SOGoMailManager.m for allowed IMAP4 keys */
- static NSArray *keys = nil;
- if (keys == nil) {
- /* Note: "BODY" actually returns the structure! */
- keys = [[NSArray alloc] initWithObjects:
- @"FLAGS", @"ENVELOPE", @"BODY", nil];
- }
- return keys;
-}
-
- (id)message {
- id msgs;
-
- if (self->message != nil)
- return [self->message isNotNull] ? self->message : nil;
-
- msgs = [[self clientObject] fetchParts:[self fetchKeys]]; // returns dict
- // [self logWithFormat:@"M: %@", msgs];
- msgs = [msgs valueForKey:@"fetch"];
- if ([msgs count] == 0)
- return nil;
-
- self->message = [[msgs objectAtIndex:0] retain];
- return self->message;
+ return [[self clientObject] fetchCoreInfos];
}
/* derived accessors */
- (BOOL)hasCC {
- return [[self valueForKeyPath:@"message.envelope.cc"] count] > 0 ? YES : NO;
+ return [[[self clientObject] ccEnvelopeAddresses] count] > 0 ? YES : NO;
}
/* actions */
<tr class="mailer_fieldrow">
<td class="mailer_fieldname" ><var:string label:value="Subject"/>:</td>
<td class="mailer_subjectfieldvalue">
- <var:string value="message.envelope.subject"
+ <var:string value="clientObject.subject"
formatter="context.mailSubjectFormatter"/>
</td>
</tr>
<td class="mailer_fieldvalue">
<!-- compose link? -->
<a href="#">
- <var:string value="message.envelope.from"
+ <var:string value="clientObject.fromEnvelopeAddress"
formatter="context.mailEnvelopeFullAddressFormatter" /></a>
</td>
</tr>
<tr class="mailer_fieldrow">
<td class="mailer_fieldname" ><var:string label:value="Date"/>:</td>
<td class="mailer_fieldvalue">
- <var:string value="message.envelope.date"
+ <var:string value="clientObject.date"
formatter="context.mailDateFormatter"/>
</td>
</tr>
<td class="mailer_fieldname" ><var:string label:value="To"/>:</td>
<td class="mailer_fieldvalue">
<!-- compose link? -->
- <var:foreach list="message.envelope.to" item="currentAddress">
+ <var:foreach list="clientObject.toEnvelopeAddresses"
+ item="currentAddress">
<a href="#">
<var:string value="currentAddress"
formatter="context.mailEnvelopeFullAddressFormatter" /></a>
<td class="mailer_fieldname" ><var:string label:value="CC"/>:</td>
<td class="mailer_fieldvalue">
<!-- compose link? -->
- <var:foreach list="message.envelope.cc" item="currentAddress">
+ <var:foreach list="clientObject.ccEnvelopeAddresses"
+ item="currentAddress">
<a href="#">
<var:string value="currentAddress"
formatter="context.mailEnvelopeFullAddressFormatter" /></a>
# $Id$
-SUBMINOR_VERSION:=12
+SUBMINOR_VERSION:=13