From bed291c039a47ffc200260241fbca4aa67764290 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Wed, 7 Apr 2010 13:58:59 +0000 Subject: [PATCH 1/3] Monotone-Parent: 17604ed59a73836f0c28f1e20146d8645215cbb1 Monotone-Revision: 3d66d23639769946e3c2badd40d0861b60c6cff8 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-04-07T13:58:59 Monotone-Branch: ca.inverse.sogo --- SOPE/sope-patchset-r1664.diff | 58 ++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/SOPE/sope-patchset-r1664.diff b/SOPE/sope-patchset-r1664.diff index 96997e611..b44efeb73 100644 --- a/SOPE/sope-patchset-r1664.diff +++ b/SOPE/sope-patchset-r1664.diff @@ -1036,20 +1036,21 @@ Index: sope-mime/NGImap4/NGImap4Client.m pool = [[NSAutoreleasePool alloc] init]; -@@ -547,7 +567,11 @@ +@@ -547,7 +567,12 @@ if (!(_pattern = [self _folder2ImapFolder:_pattern])) return nil; - s = [NSString stringWithFormat:@"list \"%@\" \"%@\"", _folder, _pattern]; + if ([_folder length] > 0) -+ prefix = [NSString stringWithFormat: @"%@%@", SaneFolderName(_folder), self->delimiter]; ++ prefix = [NSString stringWithFormat: @"%@%@", ++ SaneFolderName(_folder), self->delimiter]; + else + prefix = @""; -+ s = [NSString stringWithFormat:@"list \"%@\" \"%@\"", prefix, _pattern]; ++ s = [NSString stringWithFormat:@"LIST \"\" \"%@%@\"", prefix, _pattern]; map = [self processCommand:s]; if (self->delimiter == nil) { -@@ -563,18 +587,49 @@ +@@ -563,18 +588,49 @@ } - (NSDictionary *)capability { @@ -1102,7 +1103,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m if (_folder == nil) _folder = @""; -@@ -591,7 +646,11 @@ +@@ -591,7 +647,11 @@ return nil; } @@ -1111,11 +1112,11 @@ Index: sope-mime/NGImap4/NGImap4Client.m + prefix = [NSString stringWithFormat: @"%@%@", SaneFolderName(_folder), self->delimiter]; + else + prefix = @""; -+ s = [NSString stringWithFormat:@"lsub \"%@\" \"%@\"", prefix, _pattern]; ++ s = [NSString stringWithFormat:@"LSUB \"\" \"%@%@\"", prefix, _pattern]; map = [self processCommand:s]; if (self->delimiter == nil) { -@@ -617,24 +676,25 @@ +@@ -617,24 +677,25 @@ 'flags' - array of strings (eg (answered,flagged,draft,seen); 'RawResponse' - the raw IMAP4 response */ @@ -1150,7 +1151,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m - (NSDictionary *)status:(NSString *)_folder flags:(NSArray *)_flags { NSString *cmd; -@@ -646,7 +706,7 @@ +@@ -646,7 +707,7 @@ return nil; cmd = [NSString stringWithFormat:@"status \"%@\" (%@)", @@ -1159,7 +1160,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m return [self->normer normalizeStatusResponse:[self processCommand:cmd]]; } -@@ -663,24 +723,28 @@ +@@ -663,24 +724,28 @@ if ((_newName = [self _folder2ImapFolder:_newName]) == nil) return nil; @@ -1193,7 +1194,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m return [self _performCommand:@"delete" onFolder:_name]; } - (NSDictionary *)create:(NSString *)_name { -@@ -820,23 +884,23 @@ +@@ -820,23 +885,23 @@ return [self->normer normalizeResponse:[self processCommand:cmd]]; } @@ -1223,7 +1224,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m seqstr, _flag ? '+' : '-', flagstr]; return [self->normer normalizeResponse:[self processCommand:cmd]]; -@@ -896,35 +960,23 @@ +@@ -896,35 +961,23 @@ NSArray *flags; NGHashMap *result; NSString *message, *icmd; @@ -1270,7 +1271,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m if (old[cntOld] == '\n') { new[cntNew] = '\r'; cntNew++; new[cntNew] = '\n'; cntNew++; -@@ -932,16 +984,24 @@ +@@ -932,16 +985,24 @@ else if (old[cntOld] != '\r') { new[cntNew] = old[cntOld]; cntNew++; } @@ -1301,7 +1302,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m result = [self processCommand:icmd withTag:YES withNotification:NO]; -@@ -967,11 +1027,12 @@ +@@ -967,11 +1028,12 @@ descr = @"Could not process qualifier for imap search "; descr = [descr stringByAppendingString:reason]; @@ -1317,7 +1318,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m } - (NSString *)_searchExprForQual:(EOQualifier *)_qualifier { -@@ -1093,7 +1154,18 @@ +@@ -1093,7 +1155,18 @@ Eg: UID SORT ( DATE REVERSE SUBJECT ) UTF-8 TODO */ NSString *tmp; @@ -1336,7 +1337,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m if ([_sortSpec isKindOfClass:[NSArray class]]) tmp = [self _generateIMAP4SortOrderings:_sortSpec]; else if ([_sortSpec isKindOfClass:[EOSortOrdering class]]) -@@ -1107,9 +1179,10 @@ +@@ -1107,9 +1180,10 @@ tmp = @"DATE"; } @@ -1349,7 +1350,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m } - (NSDictionary *)sort:(NSArray *)_sortOrderings qualifier:(EOQualifier *)_qual -@@ -1130,7 +1203,7 @@ +@@ -1130,7 +1204,7 @@ return nil; } @@ -1358,7 +1359,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m return [self->normer normalizeSearchResponse:[self processCommand:s]]; } -@@ -1142,7 +1215,7 @@ +@@ -1142,7 +1216,7 @@ if ((_folder = [self _folder2ImapFolder:_folder]) == nil) return nil; @@ -1367,7 +1368,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m return [self->normer normalizeGetACLResponse:[self processCommand:cmd]]; } -@@ -1155,7 +1228,7 @@ +@@ -1155,7 +1229,7 @@ return nil; cmd = [NSString stringWithFormat:@"setacl \"%@\" \"%@\" \"%@\"", @@ -1376,7 +1377,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m return [self->normer normalizeResponse:[self processCommand:cmd]]; } -@@ -1166,7 +1239,7 @@ +@@ -1166,7 +1240,7 @@ return nil; cmd = [NSString stringWithFormat:@"deleteacl \"%@\" \"%@\"", @@ -1385,7 +1386,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m return [self->normer normalizeResponse:[self processCommand:cmd]]; } -@@ -1177,7 +1250,7 @@ +@@ -1177,7 +1251,7 @@ return nil; cmd = [NSString stringWithFormat:@"listrights \"%@\" \"%@\"", @@ -1394,7 +1395,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m return [self->normer normalizeListRightsResponse:[self processCommand:cmd]]; } -@@ -1187,12 +1260,94 @@ +@@ -1187,12 +1261,94 @@ if ((_folder = [self _folder2ImapFolder:_folder]) == nil) return nil; @@ -1490,7 +1491,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m - (NSException *)_processCommandParserException:(NSException *)_exception { [self logWithFormat:@"ERROR(%s): catched IMAP4 parser exception %@: %@", __PRETTY_FUNCTION__, [_exception name], [_exception reason]]; -@@ -1280,7 +1435,9 @@ +@@ -1280,7 +1436,9 @@ if (tryReconnect) { [self reconnect]; } @@ -1501,7 +1502,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m if (reconnectCnt == 0) { reconnectCnt++; tryReconnect = YES; -@@ -1412,21 +1569,24 @@ +@@ -1412,21 +1570,24 @@ return nil; } @@ -1534,7 +1535,7 @@ Index: sope-mime/NGImap4/NGImap4Client.m } - (NSString *)_imapFolder2Folder:(NSString *)_folder { -@@ -1442,10 +1602,16 @@ +@@ -1442,10 +1603,16 @@ return nil; } @@ -3064,7 +3065,14 @@ Index: sope-mime/NGImap4/ChangeLog =================================================================== --- sope-mime/NGImap4/ChangeLog (revision 1664) +++ sope-mime/NGImap4/ChangeLog (working copy) -@@ -1,3 +1,158 @@ +@@ -1,3 +1,165 @@ ++2010-04-07 Wolfgang Sourdeau ++ ++ * NGImap4Client.m (-list:pattern:, -lsub:pattern:): use an empty ++ prefix and put the used prefix in the "pattern" component of the ++ LIST or LSUB command, as this work around bugs in bad server ++ implementations. ++ +2010-04-02 Wolfgang Sourdeau + + * NGSieveClient.m (-putScript:script:): From cd43a73710ae1f0aa9a82640cf10c8ab9a7fa9a6 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Wed, 7 Apr 2010 14:04:48 +0000 Subject: [PATCH 2/3] Monotone-Parent: 3d66d23639769946e3c2badd40d0861b60c6cff8 Monotone-Revision: 7346726a0f54ccee6cdcb46da66c4b48bfa8ab67 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-04-07T14:04:48 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 16 +++++ SoObjects/Mailer/SOGoMailAccount.m | 2 +- SoObjects/Mailer/SOGoMailFolder.m | 98 ++++++++++++++---------------- 3 files changed, 64 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7748202dd..4c7a355d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2010-04-07 Wolfgang Sourdeau + + * SoObjects/Mailer/SOGoMailFolder.m (-toManyRelationshipKeys): we + now check if the mailbox exists before returning the message + identifiers. + (-lookupName:inContext:acquire:): we no longer check whether the + folder exists as it causes problems when it is a "noselect" parent + folder. Existence of folders is thus checked only when messages + are accessed. + + * SoObjects/Mailer/SOGoMailAccount.m + (_appendNamespace:toFolders:): it may happen that the namespace + "folders" have already been added via the list command, therefore + we now ensure that the folder names do not already exist before + adding them to the array. + 2010-04-06 Wolfgang Sourdeau * UI/WebServerResources/UIxPreferences.js (prototypeIfyFilters): diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m index ea025a45e..74cd6ea67 100644 --- a/SoObjects/Mailer/SOGoMailAccount.m +++ b/SoObjects/Mailer/SOGoMailAccount.m @@ -112,7 +112,7 @@ static NSString *sieveScriptName = @"sogo"; newFolder = [[currentPart objectForKey: @"prefix"] substringFromIndex: 1]; if ([newFolder length]) - [folders addObject: newFolder]; + [folders addObjectUniquely: newFolder]; } } diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m index 24468d62f..5979d3472 100644 --- a/SoObjects/Mailer/SOGoMailFolder.m +++ b/SoObjects/Mailer/SOGoMailFolder.m @@ -243,17 +243,20 @@ static NSString *defaultUserID = @"anyone"; if (!filenames) { filenames = [NSMutableArray new]; - uids = [self fetchUIDsMatchingQualifier: nil sortOrdering: @"DATE"]; - if (![uids isKindOfClass: [NSException class]]) - { - max = [uids count]; - for (count = 0; count < max; count++) - { - filename = [NSString stringWithFormat: @"%@.eml", - [uids objectAtIndex: count]]; - [filenames addObject: filename]; - } - } + if ([[self imap4Connection] doesMailboxExistAtURL: [self imap4URL]]) + { + uids = [self fetchUIDsMatchingQualifier: nil sortOrdering: @"DATE"]; + if (![uids isKindOfClass: [NSException class]]) + { + max = [uids count]; + for (count = 0; count < max; count++) + { + filename = [NSString stringWithFormat: @"%@.eml", + [uids objectAtIndex: count]]; + [filenames addObject: filename]; + } + } + } } return filenames; @@ -494,11 +497,11 @@ static NSString *defaultUserID = @"anyone"; { // We check for the existence of the IMAP folder (likely to be the // Sent mailbox) prior to appending messages to it. - if ([[self imap4Connection] doesMailboxExistAtURL: [self imap4URL]] || - ![[self imap4Connection] createMailbox: [[self imap4Connection] imap4FolderNameForURL: [self imap4URL]] - atURL: [[self mailAccountFolder] imap4URL]]) + if ([[self imap4Connection] doesMailboxExistAtURL: [self imap4URL]] + || ![[self imap4Connection] createMailbox: [[self imap4Connection] imap4FolderNameForURL: [self imap4URL]] + atURL: [[self mailAccountFolder] imap4URL]]) return [[self imap4Connection] postData: _data flags: _flags - toFolderURL: [self imap4URL]]; + toFolderURL: [self imap4URL]]; return [NSException exceptionWithHTTPStatus: 502 /* Bad Gateway */ reason: [NSString stringWithFormat: @"%@ is not an IMAP4 folder", [self relativeImap4Name]]]; @@ -576,47 +579,40 @@ static NSString *defaultUserID = @"anyone"; SOGoMailAccount *mailAccount; id obj; - // We automatically create mailboxes that don't exist but that we're - // trying to open. This shouldn't happen unless a mailbox has been - // deleted "behind our back" or if we're trying to open a special - // mailbox that doesn't yet exist. - if ([[self imap4Connection] doesMailboxExistAtURL: [self imap4URL]] - || ![[self imap4Connection] createMailbox: [self relativeImap4Name] - atURL: [[self mailAccountFolder] imap4URL]]) + obj = [super lookupName: _key inContext: _ctx acquire: NO]; + if (!obj) { - obj = [super lookupName: _key inContext: _ctx acquire: NO]; - if (!obj) + if ([_key hasPrefix: @"folder"]) { - if ([_key hasPrefix: @"folder"]) - { - mailAccount = [self mailAccountFolder]; - folderName = [[_key substringFromIndex: 6] fromCSSIdentifier]; - fullFolderName = [NSString stringWithFormat: @"%@/%@", - [self traversalFromMailAccount], folderName]; - if ([fullFolderName - isEqualToString: [mailAccount sentFolderNameInContext: _ctx]]) - className = @"SOGoSentFolder"; - else if ([fullFolderName isEqualToString: - [mailAccount draftsFolderNameInContext: _ctx]]) - className = @"SOGoDraftsFolder"; - else if ([fullFolderName isEqualToString: - [mailAccount trashFolderNameInContext: _ctx]]) - className = @"SOGoTrashFolder"; - /* else if ([folderName isEqualToString: - [mailAccount sieveFolderNameInContext: _ctx]]) - obj = [self lookupFiltersFolder: _key inContext: _ctx]; */ - else - className = @"SOGoMailFolder"; + mailAccount = [self mailAccountFolder]; + folderName = [[_key substringFromIndex: 6] fromCSSIdentifier]; + fullFolderName = [NSString stringWithFormat: @"%@/%@", + [self traversalFromMailAccount], folderName]; + if ([fullFolderName + isEqualToString: + [mailAccount sentFolderNameInContext: _ctx]]) + className = @"SOGoSentFolder"; + else if ([fullFolderName + isEqualToString: + [mailAccount draftsFolderNameInContext: _ctx]]) + className = @"SOGoDraftsFolder"; + else if ([fullFolderName + isEqualToString: + [mailAccount trashFolderNameInContext: _ctx]]) + className = @"SOGoTrashFolder"; + /* else if ([folderName isEqualToString: + [mailAccount sieveFolderNameInContext: _ctx]]) + obj = [self lookupFiltersFolder: _key inContext: _ctx]; */ + else + className = @"SOGoMailFolder"; - obj = [NSClassFromString (className) objectWithName: _key - inContainer: self]; - } - else if (isdigit ([_key characterAtIndex: 0])) - obj = [SOGoMailObject objectWithName: _key inContainer: self]; + obj = [NSClassFromString (className) objectWithName: _key + inContainer: self]; } + else if (isdigit ([_key characterAtIndex: 0]) + && [[self imap4Connection] doesMailboxExistAtURL: [self imap4URL]]) + obj = [SOGoMailObject objectWithName: _key inContainer: self]; } - else - obj = nil; if (!obj && _acquire) obj = [NSException exceptionWithHTTPStatus: 404 /* Not Found */]; From 88857d6e4e0945059941524c6c497acb860a368b Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Wed, 7 Apr 2010 15:06:07 +0000 Subject: [PATCH 3/3] Monotone-Parent: 7346726a0f54ccee6cdcb46da66c4b48bfa8ab67 Monotone-Revision: fa3da496f8fda4380291c10cbb009ed34be0c475 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-04-07T15:06:07 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 5 ++++ UI/MailPartViewers/UIxMailPartICalActions.m | 27 ++++++++++++--------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4c7a355d9..68ada5331 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2010-04-07 Wolfgang Sourdeau + * UI/MailPartViewers/UIxMailPartICalActions.m + (_eventObjectWithUID:forUser:): we check that the target event + exists only in the specified user's calendar, as it may already + exists in subcribed calendars belonging to other attendees. + * SoObjects/Mailer/SOGoMailFolder.m (-toManyRelationshipKeys): we now check if the mailbox exists before returning the message identifiers. diff --git a/UI/MailPartViewers/UIxMailPartICalActions.m b/UI/MailPartViewers/UIxMailPartICalActions.m index fb9b9fa67..27020e8bf 100644 --- a/UI/MailPartViewers/UIxMailPartICalActions.m +++ b/UI/MailPartViewers/UIxMailPartICalActions.m @@ -79,24 +79,29 @@ SOGoAppointmentObject *eventObject; NSArray *folders; NSEnumerator *e; - NSString *cname; + NSString *cname, *userLogin; eventObject = nil; + userLogin = [user login]; + folders = [[user calendarsFolderInContext: context] subFolders]; e = [folders objectEnumerator]; - while ( eventObject == nil && (folder = [e nextObject]) ) + while (eventObject == nil && (folder = [e nextObject])) { - cname = [folder resourceNameForEventUID: uid]; - if (cname) - { - eventObject = [folder lookupName: cname - inContext: context acquire: NO]; - if (![eventObject isKindOfClass: [SOGoAppointmentObject class]]) - eventObject = nil; - } + if ([[folder ownerInContext: nil] isEqualToString: userLogin]) + { + cname = [folder resourceNameForEventUID: uid]; + if (cname) + { + eventObject = [folder lookupName: cname inContext: context + acquire: NO]; + if (![eventObject isKindOfClass: [NSException class]]) + eventObject = nil; + } + } } - + if (!eventObject) { folder = [user personalCalendarFolderInContext: context];