]> err.no Git - sope/commitdiff
improvements in NGImap4Client
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Thu, 30 Sep 2004 23:12:09 +0000 (23:12 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Thu, 30 Sep 2004 23:12:09 +0000 (23:12 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@206 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-mime/ChangeLog
sope-mime/NGImap4/ChangeLog
sope-mime/NGImap4/NGImap4Client.h
sope-mime/NGImap4/NGImap4Client.m
sope-mime/NGImap4/NGImap4Folder.m
sope-mime/Version

index b0b2b16abf8b70d2a5a75d2a87b8501259c3a869..39566f104cd448bc827f27968b1ff820b71cef38 100644 (file)
@@ -1,3 +1,7 @@
+2004-10-01  Helge Hess  <helge.hess@opengroupware.org>
+
+       * NGImap4: NGImap4Client improvements (v4.3.183)
+
 2004-09-30  Helge Hess  <helge.hess@skyrix.com>
 
        * NGMime: fixed OGo buf #936 (v4.3.182)
index b65e3a662e2e6d1ccc400d9522c9c5ab165fe069..5e87e1799a3ec2ef688f83d333c1e623dd3e042d 100644 (file)
@@ -1,3 +1,12 @@
+2004-09-30  Helge Hess  <helge.hess@opengroupware.org>
+
+       * v4.3.183
+
+       * NGImap4Folder.m: use new sort API
+
+       * NGImap4Client.m: deprecated -sort:qualifier: in favor of
+         -sort:qualifier:encoding:, code cleanups
+
 2004-09-29  Helge Hess  <helge.hess@skyrix.com>
 
        * NGImap4Client.m: improved -description (v4.3.181)
index 0d7f0120e402f221acfb67c1a662f6cae8823e29..baee139054f1be918ab64f501d0c7e12c6d0a799 100644 (file)
@@ -127,9 +127,10 @@ typedef enum {
 - (NSDictionary *)expunge;
   
 - (NSDictionary *)sort:(NSArray *)_sortOrderings
-  qualifier:(EOQualifier *)_qual;
+  qualifier:(EOQualifier *)_qual
+  encoding:(NSString *)_encoding;
 - (NSDictionary *)fetchUids:(NSArray *)_uids parts:(NSArray *)_parts;
-- (NSDictionary *)fetchUid:(unsigned)_uid parts:(NSArray *)_parts;
+- (NSDictionary *)fetchUid:(unsigned)_uid    parts:(NSArray *)_parts;
 - (NSDictionary *)fetchFrom:(unsigned)_from to:(unsigned)_to
   parts:(NSArray *)_parts;
 - (NSDictionary *)storeUid:(unsigned)_uid add:(NSNumber *)_add
@@ -147,9 +148,17 @@ typedef enum {
 
 - (NSDictionary *)searchWithQualifier:(EOQualifier *)_qualifier;
 
+/* context accessors (DEPRECATED) */
+
 - (void)setContext:(NGImap4Context *)_ctx;
 - (NGImap4Context *)context;
 
+/* raw methods */
+
+- (NSDictionary *)primarySort:(NSString *)_sortString
+  qualifierString:(NSString *)_qualString
+  encoding:(NSString *)_encoding;
+
 @end
 
 #endif /* __SOPE_NGImap4_NGImap4Client_H__ */
index 247103263950d339fe2cf7916d099c55b3f72f9c..0511a259c9ce82b1ccba776bf1fad6e5805542af 100644 (file)
@@ -593,6 +593,19 @@ static BOOL         ImapDebugEnabled   = NO;
 }
 
 - (NSDictionary *)select:(NSString *)_folder {
+  /*
+    Select a folder (required for a lot of methods).
+    eg: 'SELECT "INBOX"'
+    
+    The result dict contains the following keys:
+      'result'      - a boolean
+      'access'      - string           (eg "READ-WRITE")
+      'exists'      - number?          (eg 1)
+      'recent'      - number?          (eg 0)
+      'expunge'     - array            (of what?)
+      'flags'       - array of strings (eg (answered,flagged,draft,seen);
+      'RawResponse' - the raw IMAP4 response
+   */
   NSString *s;
   id tmp;
 
@@ -911,6 +924,12 @@ static BOOL         ImapDebugEnabled   = NO;
 }
 
 - (NSString *)_searchExprForQual:(EOQualifier *)_qualifier {
+  /*
+    samples:
+      ' ALL'
+      ' SINCE 1-Feb-1994'
+      ' TEXT "why SOPE rocks"'
+  */
   id result;
   
   if (_qualifier == nil)
@@ -925,91 +944,182 @@ static BOOL         ImapDebugEnabled   = NO;
   return result;
 }
 
-/* siehe draft-ietf-imapext-thread-12.txt
-   returns an array of uids in sort order */
-
 - (NSDictionary *)threadBySubject:(BOOL)_bySubject
   charset:(NSString *)_charSet
 {
-  NSString *threadStr;
-  NSString *threadAlg;
+  /*
+    http://www.ietf.org/proceedings/03mar/I-D/draft-ietf-imapext-thread-12.txt
 
-  if (_bySubject)
-    threadAlg = @"REFERENCES";
-  else
-    threadAlg = @"ORDEREDSUBJECT";
+    Returns an array of uids in sort order.
+
+    Parameters:
+      _bySubject - if yes, use "REFERENCES" else "ORDEREDSUBJECT" (TODO: ?!)
+      _charSet   - default: "UTF-8"
     
+    Generates:
+      UID THREAD REFERENCES|ORDEREDSUBJECT UTF-8 ALL
+  */
+  NSString *threadStr;
+  NSString *threadAlg;
+  
+  threadAlg = (_bySubject)
+    ? @"REFERENCES"
+    : @"ORDEREDSUBJECT";
   
-  if (![_charSet length])
+  if ([_charSet length] == 0)
     _charSet = @"UTF-8";
-
+  
   threadStr = [NSString stringWithFormat:@"UID THREAD %@ %@ ALL",
                       threadAlg, _charSet];
-
+  
   return [self->normer normalizeThreadResponse:
                [self processCommand:threadStr]];
 }
 
-- (NSDictionary *)sort:(NSArray *)_sortOrderings
-  qualifier:(EOQualifier *)_qual
-{
-  /* siehe draft-ietf-imapext-sort */
-  /* returns an array of uids in sort order */
+- (NSString *)_generateIMAP4SortOrdering:(EOSortOrdering *)_sortOrdering {
+  SEL      sel;
+  NSString *key;
+    
+  key = [_sortOrdering key];
+  if ([key length] == 0)
+    return nil;
+    
+  if (![AllowedSortKeys containsObject:[key uppercaseString]]) {
+    [self logWithFormat:@"ERROR[%s] key %@ is not allowed here!",
+           __PRETTY_FUNCTION__, key];
+    return nil;
+  }
+
+  sel = [_sortOrdering selector];
+  if (sel_eq(sel, EOCompareDescending) ||
+      sel_eq(sel, EOCompareCaseInsensitiveDescending)) {
+    return [@"REVERSE " stringByAppendingString:key];
+  }
+  // TODO: check other selectors whether they make sense instead of silent acc.
+  
+  return key;
+}
+
+- (NSString *)_generateIMAP4SortOrderings:(NSArray *)_sortOrderings {
+  /*
+    turn EOSortOrdering into an IMAP4 value for "SORT()"
+    
+    eg: "DATE REVERSE SUBJECT"
+    
+    It also checks a set of allowed sort-keys (don't know why)
+  */
   NSMutableString *sortStr;
-  NSEnumerator    *enumerator;
+  NSEnumerator    *soe;
   EOSortOrdering  *so;
   BOOL            isFirst = YES;
-
-  sortStr = [NSMutableString stringWithCapacity:128];
   
   if ([_sortOrderings count] == 0)
-    return [NSDictionary dictionaryWithObjectsAndKeys:@"result", NoNumber,nil];
-  
-  enumerator = [_sortOrderings objectEnumerator];
-
-  [sortStr appendString:@"UID SORT ("];
+    return nil;
   
-  while ((so = [enumerator nextObject])) {
-    SEL      sel;
-    NSString *key;
-    
-    key = [[so key] uppercaseString];
-    
-    if ([key length] == 0)
-      continue;
+  sortStr = [NSMutableString stringWithCapacity:128];
+  soe     = [_sortOrderings objectEnumerator];
+  while ((so = [soe nextObject])) {
+    NSString *s;
 
-    if (![AllowedSortKeys containsObject:key]) {
-      [self logWithFormat:@"ERROR[%s] key %@ is not allowed here!",
-            __PRETTY_FUNCTION__, key];
+    s = [self _generateIMAP4SortOrdering:so];
+    if (s == nil)
       continue;
-    }
+    
     if (isFirst)
       isFirst = NO;
     else
       [sortStr appendString:@" "];
-    sel = [so selector];
-
-    if (sel_eq(sel, EOCompareDescending) ||
-        sel_eq(sel, EOCompareCaseInsensitiveDescending)) {
-      [sortStr appendString:@"REVERSE "];
-    }
-    [sortStr appendString:[so key]];
-  }
-  if (isFirst) { /* found no valid key use date sorting */
-    [sortStr appendString:@"DATE"];
-#if 0    
-    return [NSDictionary dictionaryWithObjectsAndKeys:
-                          NoNumber, @"result", nil];
-#endif    
+    
+    [sortStr appendString:s];
   }
+  return isFirst ? nil : sortStr;
+}
+
+- (NSDictionary *)primarySort:(NSString *)_sort
+  qualifierString:(NSString *)_qualString
+  encoding:(NSString *)_encoding
+{
+  /* 
+     http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-17.txt
+     
+     The result dict contains the following keys:
+      'result'      - a boolean
+      'expunge'     - array            (of what?)
+      'sort'        - array of uids in sort order
+      'RawResponse' - the raw IMAP4 response
+     
+     Eg: UID SORT ( DATE REVERSE SUBJECT ) UTF-8 TODO
+  */
+  NSMutableString *sortStr;
+
+  if (![_encoding   isNotNull]) _encoding   = @"UTF-8";
+  if (![_qualString isNotNull]) _qualString = @" ALL";
+  
+  sortStr = [NSMutableString stringWithCapacity:128];
+  
+  [sortStr appendString:@"UID SORT ("];
+  if (_sort != nil) [sortStr appendString:_sort];
   [sortStr appendString:@") "];
-  // TODO: make that the other way around! should be an ivar in the client
-  [sortStr appendString:[[self context] sortEncoding]];
-  [sortStr appendString:[self _searchExprForQual:_qual]];
+  
+  [sortStr appendString:_encoding];   /* eg 'UTF-8' */
+  
+  /* Note: this is _space sensitive_! to many spaces lead to error! */
+  [sortStr appendString:_qualString]; /* eg ' ALL' or ' TEXT "abc"' */
   
   return [self->normer normalizeSortResponse:[self processCommand:sortStr]];
 }
 
+- (NSDictionary *)sort:(id)_sortSpec
+  qualifier:(EOQualifier *)_qual
+  encoding:(NSString *)_encoding
+{
+  /* 
+     http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-17.txt
+
+     The _sortSpec can be:
+     - a simple 'raw' IMAP4 sort string
+     - an EOSortOrdering
+     - an array of EOSortOrderings
+     
+     The result dict contains the following keys:
+      'result'      - a boolean
+      'expunge'     - array            (of what?)
+      'sort'        - array of uids in sort order
+      'RawResponse' - the raw IMAP4 response
+    
+     If no sortable key was found, the sort will run against 'DATE'.
+     => TODO: this is inconsistent. If none are passed in, false will be
+              returned
+     
+     Eg: UID SORT ( DATE REVERSE SUBJECT ) UTF-8 TODO
+  */
+  NSString *tmp;
+  
+  if ([_sortSpec isKindOfClass:[NSArray class]])
+    tmp = [self _generateIMAP4SortOrderings:_sortSpec];
+  else if ([_sortSpec isKindOfClass:[EOSortOrdering class]])
+    tmp = [self _generateIMAP4SortOrdering:_sortSpec];
+  else
+    tmp = [_sortSpec stringValue];
+  
+  if ([tmp length] == 0) { /* found no valid key use date sorting */
+    [self logWithFormat:@"Note: no key found for sorting, using 'DATE': %@",
+           _sortSpec];
+    tmp = @"DATE";
+  }
+  
+  return [self primarySort:tmp 
+              qualifierString:[self _searchExprForQual:_qual]
+              encoding:_encoding];
+}
+- (NSDictionary *)sort:(NSArray *)_sortOrderings
+  qualifier:(EOQualifier *)_qual
+{
+  // DEPRECATED, should not use context!
+  return [self sort:_sortOrderings qualifier:_qual
+              encoding:[[self context] sortEncoding]];
+}
+
 - (NSDictionary *)searchWithQualifier:(EOQualifier *)_qualifier {
   NSString *s;
   
index b96b1ad32ac3df92a8be9492ff2f8018a9977424..75fd174173a0d75f466eaad024166e6d2e12c6c6 100644 (file)
@@ -18,7 +18,7 @@
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
+// $Id: NGImap4Folder.m 1 2004-08-20 10:08:27Z znek $
 
 #include "NGImap4Folder.h"
 #include "NGImap4Context.h"
@@ -716,10 +716,11 @@ static int FetchNewUnseenMessagesInSubFoldersOnDemand = -1;
         
         qual2 = UnseenQual;
       }
-
-      if (qual1) {
-        dict = [[self->context client] sort:DateSo qualifier:qual1];
-
+      
+      if (qual1 != nil) {
+        dict = [[self->context client] sort:DateSo qualifier:qual1
+                                      encoding:[self->context sortEncoding]];
+       
         if (![[dict objectForKey:@"result"] boolValue]) {
           [self logWithFormat:@"ERROR[%s](1): sort failed (sortOrderings %@, "
                 @"qual1 %@)", __PRETTY_FUNCTION__, DateSo, qual1];
@@ -727,9 +728,10 @@ static int FetchNewUnseenMessagesInSubFoldersOnDemand = -1;
         }
         [muids addObjectsFromArray:[dict objectForKey:@"sort"]];
       }
-      if (qual2) {
-        dict = [[self->context client] sort:DateSo qualifier:qual2];
-
+      if (qual2 != nil) {
+        dict = [[self->context client] sort:DateSo qualifier:qual2
+                                      encoding:[self->context sortEncoding]];
+       
         if (![[dict objectForKey:@"result"] boolValue]) {
           [self logWithFormat:@"ERROR[%s](2): sort failed (sortOrderings %@, "
                 @"qual2 %@ ", __PRETTY_FUNCTION__, DateSo, qual2];
@@ -764,8 +766,9 @@ static int FetchNewUnseenMessagesInSubFoldersOnDemand = -1;
 
     [self resetLastException];
     
-    dict = [[self->context client] sort:_so qualifier:qual];
-
+    dict = [[self->context client] sort:_so qualifier:qual
+                                  encoding:[self->context sortEncoding]];
+    
     if (![self _checkResult:dict cmd:__PRETTY_FUNCTION__])
       return nil;
 
index 627cb44f4cf342302d7ccbf5fc9644b019fd91e4..5f3604ff0936634e26fdfb8b1364e83ad89bd6b5 100644 (file)
@@ -2,6 +2,6 @@
 
 MAJOR_VERSION:=4
 MINOR_VERSION:=3
-SUBMINOR_VERSION:=182
+SUBMINOR_VERSION:=183
 
 # v4.2.149 requires libNGStreams v4.2.34