offlineimap rev 559

"Automatic Subversion Change Mailer" <[email protected]> Tue, 12 Aug 2003 15:26:20 -0500 (CDT)
Newsgroups gmane.mail.imap.offlineimap.subversion
Message-ID <[email protected]>
You are receiving this message because
all commits get sent to this address.

Author: jgoerzen
Date: 2003-08-12 15:26:00 -0500 (Tue, 12 Aug 2003)
New Revision: 559

Modified:
  offlineimap/branches/twisted/twistedfixes/imap4.diff
  offlineimap/branches/twisted/twistedfixes/imap4.py

Log:
Updated to 1.139 from Twisted CVS... will no longer require custom diffs.


Diff:
Deleted: offlineimap/branches/twisted/twistedfixes/imap4.diff
===================================================================
--- offlineimap/branches/twisted/twistedfixes/imap4.diff	2003-08-12 20:22:42 UTC (rev 558)
+++ offlineimap/branches/twisted/twistedfixes/imap4.diff	2003-08-12 20:26:00 UTC (rev 559)
@@ -1,22 +0,0 @@
---- /home/jgoerzen/tree/Twisted/twisted/protocols/imap4.py	2003-07-25 16:04:29.000000000 -0500
-+++ imap4.py	2003-08-05 15:42:49.000000000 -0500
-@@ -2189,6 +2189,10 @@
-                     raise IllegalServerResponse('(%s %s): %s' % (k, status[k], str(e)))
-         return status
- 
-+    def sendLine(self, line):
-+        print 'C:', repr(line)
-+        return basic.LineReceiver.sendLine(self, line)
-+
-     def append(self, mailbox, message, flags = (), date = None):
-         """Add the given message to the currently selected mailbox
- 
-@@ -2858,7 +2862,7 @@
-         store = uid and 'UID STORE' or 'STORE'
-         args = ' '.join((messages, cmd, '(%s)' % ' '.join(flags)))
-         d = self.sendCommand(Command(store, args, wantResponse=('FETCH',)))
--        d.addCallback(self.__cbFetch, lookFor='FLAGS')
-+        d.addCallback(self.__cbFetch)
-         return d
-     
-     def copy(self, messages, mailbox, uid):

Modified: offlineimap/branches/twisted/twistedfixes/imap4.py
===================================================================
--- offlineimap/branches/twisted/twistedfixes/imap4.py	2003-08-12 20:22:42 UTC (rev 558)
+++ offlineimap/branches/twisted/twistedfixes/imap4.py	2003-08-12 20:26:00 UTC (rev 559)
@@ -58,6 +58,8 @@
 import types
 import sys
 
+import email.Utils
+
 try:
     import cStringIO as StringIO
 except:
@@ -1308,8 +1310,8 @@
             elif part.type == 'internaldate':
                 response.extend(('INTERNALDATE', msg.getInternalDate()))
             elif part.type == 'rfc822header':
-                hdrs = msg.getHeaders((), True)
-                hdrs = [': '.join((k, v)) for (k. v) in hdrs.iteritems()]
+                hdrs = msg.getHeaders(True)
+                hdrs = [': '.join((k, v)) for (k, v) in hdrs.iteritems()]
                 hdrs = '\r\n'.join(hdrs)
                 response.extend(('RFC822.HEADER', hdrs + '\r\n\r\n'))
             elif part.type == 'rfc822text':
@@ -1317,8 +1319,8 @@
             elif part.type == 'rfc822size':
                 response.extend(('RFC822.SIZE', str(msg.getSize())))
             elif part.type == 'rfc822':
-                hdrs = msg.getHeaders((), True)
-                hdrs = [': '.join((k, v)) for (k. v) in hdrs.iteritems()]
+                hdrs = msg.getHeaders(True)
+                hdrs = [': '.join((k, v)) for (k, v) in hdrs.iteritems()]
                 hdrs.append('')
                 hdrs = '\r\n'.join(hdrs)
                 response.extend(('RFC822', hdrs + '\r\n' + msg.getBodyFile().read()))
@@ -1329,19 +1331,19 @@
                 else:
                     response.extend(('UID', str(msg.getUID())))
             elif part.type == 'bodystructure':
-                response.extend(('BODYSTRUCTURE', getBodyStructure(msg)))
+                response.extend(('BODYSTRUCTURE', getBodyStructure(msg, True)))
             elif part.type == 'body':
                 subMsg = msg
                 for p in part.part or ():
                     subMsg = subMsg.getSubPart(p)
                 if part.header:
                     if not part.header.fields:
-                        hdrs = msg.getHeaders((), True)
-                        hdrs = [': '.join((k, v)) for (k. v) in hdrs.iteritems()]
+                        hdrs = msg.getHeaders(True)
+                        hdrs = [': '.join((k, v)) for (k, v) in hdrs.iteritems()]
                         hdrs = '\r\n'.join(hdrs)
                         response.extend((str(part), hdrs + '\r\n\r\n'))
                     else:
-                        hdrs = subMsg.getHeaders(part.header.fields, part.header.negate)
+                        hdrs = subMsg.getHeaders(part.header.negate, *part.header.fields)
                         hdrs = ['%s: %s' % x for x in hdrs.iteritems()]
                         hdrs.append('')
                         hdrs = '\r\n'.join(hdrs) + '\r\n'
@@ -1349,17 +1351,21 @@
                 elif part.text:
                     response.extend((str(part), subMsg.getBodyFile()))
                 elif part.mime:
-                    hdrs = msg.getHeaders((), True)
-                    hdrs = [': '.join((k, v)) for (k. v) in hdrs.iteritems()]
+                    hdrs = msg.getHeaders(True)
+                    hdrs = [': '.join((k, v)) for (k, v) in hdrs.iteritems()]
                     hdrs = '\r\n'.join(hdrs)
                     response.extend((str(part), hdrs + '\r\n\r\n'))
-                else:
-                    # Simplified body request
-                    hdrs = msg.getHeaders((), True)
-                    hdrs = [': '.join((k, v)) for (k. v) in hdrs.iteritems()]
+                elif part.empty:
+                    # BODY[] request
+                    hdrs = msg.getHeaders(True)
+                    hdrs = [': '.join((k, v)) for (k, v) in hdrs.iteritems()]
                     hdrs.append('')
                     hdrs = '\r\n'.join(hdrs)
                     response.extend((str(part), hdrs + '\r\n' + subMsg.getBodyFile().read()))
+                else:
+                    # Simplified bodystructure request
+                    response.extend(('BODY', getBodyStructure(msg, False)))
+
         if uid and not seenUID:
             response[:0] = ['UID', str(msgId)]
         self.sendUntaggedResponse("%d FETCH %s" % (msgId, collapseNestedLists([response])))
@@ -2189,10 +2195,6 @@
                     raise IllegalServerResponse('(%s %s): %s' % (k, status[k], str(e)))
         return status
 
-    def sendLine(self, line):
-        print 'C:', repr(line)
-        return basic.LineReceiver.sendLine(self, line)
-
     def append(self, mailbox, message, flags = (), date = None):
         """Add the given message to the currently selected mailbox
 
@@ -2217,12 +2219,14 @@
         message.seek(0, 2)
         L = message.tell()
         message.seek(0, 0)
-        fmt = '%s (%s)%s%s {%d}'
+        fmt = '%s (%s)%s {%d}'
         if date:
-            date = '"%s"' % date
+            date = ' "%s"' % date
+        else:
+            date = ''
         cmd = fmt % (
             mailbox.encode('imap4-utf-7'), ' '.join(flags),
-            date and ' ' or '', date, L
+            date, L
         )
         continuation = defer.Deferred()
         continuation.addCallback(self.__cbContinueAppend, message)
@@ -2347,7 +2351,7 @@
 
         This command is allowed in the Selected state.
 
-        @type messages: C{str}
+        @type messages: C{MessageSet} or C{str}
         @param messages: A message sequence set
 
         @rtype: C{Deferred}
@@ -2364,7 +2368,7 @@
 
         This command is allowed in the Selected state.
 
-        @type messages: C{MessageSet}
+        @type messages: C{MessageSet} or C{str}
         @param messages: The messages for which to retrieve flags.
 
         @type uid: C{bool}
@@ -2385,7 +2389,7 @@
 
         This command is allowed in the Selected state.
 
-        @type messages: C{MessageSet}
+        @type messages: C{MessageSet} or C{str}
         @param messages: The messages for which to retrieve the internal date.
 
         @type uid: C{bool}
@@ -2407,7 +2411,7 @@
 
         This command is allowed in the Selected state.
 
-        @type messages: C{MessageSet}
+        @type messages: C{MessageSet} or C{str}
         @param messages: The messages for which to retrieve envelope data.
 
         @type uid: C{bool}
@@ -2434,7 +2438,7 @@
 
         This command is allowed in the Selected state.
 
-        @type messages: C{MessageSet}
+        @type messages: C{MessageSet} or C{str}
         @param messages: The messages for which to retrieve body structure
         data.
 
@@ -2464,7 +2468,7 @@
 
         This command is allowed in the Selected state.
 
-        @type messages: C{str}
+        @type messages: C{MessageSet} or C{str}
         @param messages: A message sequence set
 
         @type uid: C{bool}
@@ -2487,7 +2491,7 @@
 
         This command is allowed in the Selected state.
 
-        @type messages: C{str}
+        @type messages: C{MessageSet} or C{str}
         @param messages: A message sequence set
 
         @type uid: C{bool}
@@ -2508,7 +2512,7 @@
 
         This command is allowed in the Selected state.
 
-        @type messages: C{str}
+        @type messages: C{MessageSet} or C{str}
         @param messages: A message sequence set
 
         @type uid: C{bool}
@@ -2529,7 +2533,7 @@
 
         This command is allowed in the Selected state.
 
-        @type messages: C{str}
+        @type messages: C{MessageSet} or C{str}
         @param messages: A message sequence set
 
         @type uid: C{bool}
@@ -2550,7 +2554,7 @@
 
         This command is allowed in the Selected state.
 
-        @type messages: C{str}
+        @type messages: C{MessageSet} or C{str}
         @param messages: A message sequence set
 
         @type uid: C{bool}
@@ -2574,7 +2578,7 @@
         C{fetchSize}, C{fetchEnvelope}, and C{fetchSimplifiedBody}
         functions.
 
-        @type messages: C{str}
+        @type messages: C{MessageSet} or C{str}
         @param messages: A message sequence set
 
         @type uid: C{bool}
@@ -2601,7 +2605,7 @@
         to issuing all of the C{fetchFlags}, C{fetchInternalDate},
         C{fetchSize}, and C{fetchEnvelope} functions.
 
-        @type messages: C{str}
+        @type messages: C{MessageSet} or C{str}
         @param messages: A message sequence set
 
         @type uid: C{bool}
@@ -2628,7 +2632,7 @@
         to issuing all of the C{fetchFlags}, C{fetchInternalDate}, and
         C{fetchSize} functions.
 
-        @type messages: C{str}
+        @type messages: C{MessageSet} or C{str}
         @param messages: A message sequence set
 
         @type uid: C{bool}
@@ -2677,7 +2681,7 @@
                       offset=None, length=None):
         """Retrieve a specific section of one or more messages
 
-        @type messages: C{str}
+        @type messages: C{MessageSet} or C{str}
         @param messages: A message sequence set
 
         @type uid: C{bool}
@@ -3617,19 +3621,29 @@
         r[n] = getattr(mbox, _statusRequestDict[n])()
     return r
 
+def parseAddr(addr):
+    if addr is None:
+        return [(None, None, None),]
+    addrs = email.Utils.getaddresses([addr])
+    return [[fn or None, None] + addr.split('@') for fn, addr in addrs]
+
 def getEnvelope(msg):
-    date = msg.getHeaders(False, 'date',).get('date')
-    subject = msg.getHeaders(False, 'subject').get('subject')
-    from_ = msg.getHeaders(False, 'from').get('from')
-    sender = msg.getHeaders(False, 'sender').get('sender', from_)
-    reply_to = msg.getHeaders(False, 'reply-to').get('reply-to', from_)
-    to = msg.getHeaders(False, 'to').get('to')
-    cc = msg.getHeaders(False, 'cc').get('cc')
-    bcc = msg.getHeaders(False, 'bcc').get('bcc')
-    in_reply_to = msg.getHeaders(False, 'in-reply-to').get('in-reply-to')
-    return date, subject, from_, sender, reply_to, to, cc, bcc, in_reply_to
+    headers = msg.getHeaders(True)
+    date = headers.get('date')
+    subject = headers.get('subject')
+    from_ = headers.get('from')
+    sender = headers.get('sender', from_)
+    reply_to = headers.get('reply-to', from_)
+    to = headers.get('to')
+    cc = headers.get('cc')
+    bcc = headers.get('bcc')
+    in_reply_to = headers.get('in-reply-to')
+    mid = headers.get('message-id')
+    return (date, subject, parseAddr(from_), parseAddr(sender),
+        reply_to and parseAddr(reply_to), to and parseAddr(to),
+        cc and parseAddr(cc), bcc and parseAddr(bcc), in_reply_to, mid)
 
-def bodyStructure(msg):
+def getBodyStructure(msg, extended=False):
     # XXX - This does not properly handle multipart messages
     # BODYSTRUCTURE is obscenely complex and criminally under-documented.
     
@@ -3883,7 +3897,7 @@
     def fetch(self, messages, uid):
         """Retrieve one or more messages.
 
-        @type messages: A MessageSet object with the list of messages requested
+        @type messages: C{MessageSet}
         @param messages: The identifiers of messages to retrieve information
         about
 
@@ -3975,18 +3989,24 @@
         mime = None
         text = None
         part = None
+        empty = False
         partialBegin = None
         partialLength = None
         def __str__(self):
             base = 'BODY'
+            part = ''
+            if self.part:
+                part = '.'.join([str(x + 1) for x in self.part]) + '.'
             if self.peek:
                 base += '.PEEK'
             if self.header:
-                base += '[%s]' % (self.header,)
+                base += '[%s%s]' % (part, self.header,)
             elif self.text:
-                base += '[TEXT]'
+                base += '[%sTEXT]' % (part,)
             elif self.mime:
-                base += '[MIME]'
+                base += '[%sMIME]' % (part,)
+            elif self.empty:
+                base += '[]'
             if self.partialBegin is not None:
                 base += '<%d.%d>' % (self.partialBegin, self.partialLength)
             return base
@@ -3999,15 +4019,16 @@
     class Header:
         negate = False
         fields = None
+        part = None
         def __str__(self):
             base = 'HEADER'
             if self.fields:
                 base += '.FIELDS'
                 if self.negate:
                     base += '.NOT'
-                base += ' (%s)' % (' '.join(self.fields),)
+                base += ' (%s)' % (' '.join(map(str.title, self.fields)),)
             if self.part:
-                base = '.'.join(map(str, self.part)) + '.'
+                base = '.'.join([str(x + 1) for x in self.part]) + '.' + base
             return base
 
     class Text:
@@ -4153,19 +4174,24 @@
     def state_section(self, s):
         # Grab [HEADER] or [HEADER.FIELDS (Header list)] or 
         # [HEADER.FIELDS.NOT (Header list)], [TEXT], or [MIME]
+        # or simply []
+        
         l = s.lower()
         used = 0
-        if l.startswith('header]'):
-            o = self.pending_body.header = self.Header()
+        if l.startswith(']'):
+            self.pending_body.empty = True
+            used += 1
+        elif l.startswith('header]'):
+            self.pending_body.header = self.Header()
             used += 7
         elif l.startswith('text]'):
-            o = self.pending_body.text = self.Text()
+            self.pending_body.text = self.Text()
             used += 5
         elif l.startswith('mime]'):
-            o = self.pending_body.mime = self.MIME()
+            self.pending_body.mime = self.MIME()
             used += 5
         else:
-            o = h = self.Header()
+            h = self.Header()
             if l.startswith('header.fields.not'):
                 h.negate = True
                 used += 17