[REV2] adding part, simplifying Message.get_parts(), and fixing json to work with...
authorJesse Rosenthal <jrosenthal@jhu.edu>
Tue, 30 Mar 2010 06:59:40 +0000 (08:59 +0200)
committerJesse Rosenthal <jrosenthal@jhu.edu>
Tue, 30 Mar 2010 06:59:40 +0000 (08:59 +0200)
Sebastian:

This replaces the patch it responds to. With this patch, we can now use
the cnotmuch with David's json ui. There are still issues, but this
allows interaction with emacs.

---

cnotmuch/message.py
notmuch

index 6a68c92d3ca1b1e8686131e9b580a9ea080b8df5..0dc8812f4e9f59e6da27b59c1062f75c7ba30c40 100644 (file)
@@ -220,8 +220,8 @@ class Messages(object):
                 else:
                     raise NotmuchError
                 next_indent = indent + 1
-
-
+                
+            #sys.stdout.write(set_end)
             replies = msg.get_replies()
             # if isinstance(replies, types.NoneType):
             #     break
@@ -653,15 +653,28 @@ class Message(object):
 
         # A subfunction to recursively unpack the message parts into a
         # list.
-        def msg_unpacker_gen(msg):
+        # def msg_unpacker_gen(msg):
+        #     if not msg.is_multipart():
+        #         yield msg
+        #     else:
+        #         for part in msg.get_payload():
+        #             for subpart in msg_unpacker_gen(part):
+        #                 yield subpart
+        #
+        # return list(msg_unpacker_gen(email_msg))
+        out = []
+        for msg in email_msg.walk():
             if not msg.is_multipart():
-                yield msg
-            else:
-                for part in msg.get_payload():
-                    for subpart in msg_unpacker_gen(part):
-                        yield subpart
+                out.append(msg)
+        return out
 
-        return list(msg_unpacker_gen(email_msg))
+    def get_part(self, num):
+        parts = self.get_message_parts()
+        if (num <= 0 or num > len(parts)):
+            return ""
+        else:
+            out_part = parts[(num - 1)]
+            return out_part.get_payload(decode=True)
 
     def format_message_internal(self):
         """Create an internal representation of the message parts,
@@ -675,7 +688,7 @@ class Message(object):
         output["tags"] = list(self.get_tags())
 
         headers = {}
-        for h in ["subject", "from", "to", "cc", "bcc", "date"]:
+        for h in ["Subject", "From", "To", "Cc", "Bcc", "Date"]:
             headers[h] = self.get_header(h)
         output["headers"] = headers
 
@@ -687,7 +700,7 @@ class Message(object):
             part_dict["id"] = i + 1
             # We'll be using this is a lot, so let's just get it once.
             cont_type = msg.get_content_type()
-            part_dict["content_type"] = cont_type
+            part_dict["content-type"] = cont_type
             # NOTE:
             # Now we emulate the current behaviour, where it ignores
             # the html if there's a text representation. 
@@ -696,16 +709,16 @@ class Message(object):
             # here in the future than to end up with another
             # incompatible solution.
             disposition = msg["Content-Disposition"]
-            if disposition:
-                if disposition.lower().startswith("attachment"):
-                    part_dict["filename"] = msg.get_filename()
+            if disposition and disposition.lower().startswith("attachment"):
+                part_dict["filename"] = msg.get_filename()
             else:
                 if cont_type.lower() == "text/plain":
                     part_dict["content"] = msg.get_payload()
                 elif (cont_type.lower() == "text/html" and 
                       i == 0):
                     part_dict["content"] = msg.get_payload()
-            body.append(part_dict)
+        body.append(part_dict)
+
         output["body"] = body
 
         return output
diff --git a/notmuch b/notmuch
index 2bb496f3132c08d29f5c8dac1b7a909b24f0325e..9f63e2107f84affcb1c9fc47f6a7cd9f3106cb15 100755 (executable)
--- a/notmuch
+++ b/notmuch
@@ -288,6 +288,43 @@ if __name__ == '__main__':
        if len(sys.argv) == 2: print HELPTEXT
        else: print "Not implemented"
    #-------------------------------------
+   elif sys.argv[1] == 'part':
+      db = Database()
+      query_string = ''
+      part_num=0
+      first_search_term = None
+      for (i, arg) in enumerate(sys.argv[1:]):
+         if arg.startswith('--part='):
+            part_num_str=arg.split("=")[1]
+            try:
+               part_num = int(part_num_str)
+            except ValueError:
+               # just emulating behavior
+               sys.exit()
+         elif not arg.startswith('--'):
+              #save the position of the first sys.argv that is a search term
+              first_search_term = i+1
+
+      if first_search_term:
+          #mangle arguments wrapping terms with spaces in quotes
+          querystr = quote_query_line(sys.argv[first_search_term:])
+
+      
+      logging.debug("part "+querystr)
+      qry = Query(db,querystr)
+      msgs = qry.search_messages()
+      msg_list = []
+      for m in msgs:
+        msg_list.append(m)
+        
+      if len(msg_list) == 0:
+        sys.exit()
+      elif len(msg_list) > 1:
+        raise Exception("search term did not match precisely one message")
+      else:
+        msg = msg_list[0]
+        print(msg.get_part(part_num))
+   #-------------------------------------
    elif sys.argv[1] == 'search':
       db = Database()
       query_string = ''