]> rtime.felk.cvut.cz Git - notmuch.git/blobdiff - cnotmuch/message.py
[REV2] adding part, simplifying Message.get_parts(), and fixing json to work with...
[notmuch.git] / cnotmuch / message.py
index 6ae5564795af2f2bbdf5dd5d453b0dc02a575af7..0dc8812f4e9f59e6da27b59c1062f75c7ba30c40 100644 (file)
@@ -1,3 +1,21 @@
+#    This file is part of cnotmuch.
+#
+#    cnotmuch is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    cnotmuch is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with cnotmuch.  If not, see <http://www.gnu.org/licenses/>.
+#
+#    (C) Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
+#                       Jesse Rosenthal <jrosenthal@jhu.edu>
+        
 from ctypes import c_char_p, c_void_p, c_long, c_bool
 from datetime import date
 from cnotmuch.globals import nmlib, STATUS, NotmuchError, Enum
@@ -154,14 +172,19 @@ class Messages(object):
         self._msgs = None
         return i
 
-
-
     def __del__(self):
         """Close and free the notmuch Messages"""
         if self._msgs is not None:
             nmlib.notmuch_messages_destroy (self._msgs)
 
-    def show_messages(self, format, indent=0, entire_thread=True):
+    def print_messages(self, format, indent=0, entire_thread=False):
+        """Outputs messages as needed for 'notmuch show' to sys.stdout
+
+        :param format: A string of either 'text' or 'json'.
+        :param indent: A number indicating the reply depth of these messages.
+        :param entire_thread: A bool, indicating whether we want to output 
+                       whole threads or only the matching messages.
+        """
         if format.lower() == "text":
             set_start = ""
             set_end = ""
@@ -177,6 +200,7 @@ class Messages(object):
 
         sys.stdout.write(set_start)
 
+        # iterate through all toplevel messages in this thread
         for msg in self:
             # if not msg:
             #     break 
@@ -196,15 +220,14 @@ 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
             if not replies is None:
                 sys.stdout.write(set_sep)
-                replies.show_messages(format, next_indent, entire_thread)
-
+                replies.print_messages(format, next_indent, entire_thread)
 
             sys.stdout.write(set_end)
         sys.stdout.write(set_end)
@@ -609,7 +632,7 @@ class Message(object):
 
     def is_match(self):
         """(Not implemented)"""
-        return self.get_flag(self.FLAG.MATCH)
+        return self.get_flag(Message.FLAG.MATCH)
 
     def __str__(self):
         """A message() is represented by a 1-line summary"""
@@ -630,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,
@@ -652,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
 
@@ -664,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. 
@@ -673,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
@@ -698,17 +734,15 @@ class Message(object):
         easy to change to a new format when the format changes."""
 
         format = self.format_message_internal()
-        output = "\n\fmessage{ id:%s depth:%d filename:%s" % (format["id"],
-                                                              indent,
-                                                              format["filename"])
+        output = "\fmessage{ id:%s depth:%d match:%d filename:%s" \
+                 % (format['id'], indent, format['match'], format['filename'])
         output += "\n\fheader{"
 
-        #Todo: this date is supposed to be cleaned up, as in the index.
+        #Todo: this date is supposed to be prettified, as in the index.
         output += "\n%s (%s) (" % (format["headers"]["from"],
                                    format["headers"]["date"])
         output += ", ".join(format["tags"])
-        output += ")\n"
-
+        output += ")"
 
         output += "\nSubject: %s" % format["headers"]["subject"]
         output += "\nFrom: %s" % format["headers"]["from"]
@@ -718,7 +752,7 @@ class Message(object):
         if format["headers"]["bcc"]:
             output += "\nBcc: %s" % format["headers"]["bcc"]
         output += "\nDate: %s" % format["headers"]["date"]
-        output += "\nheader}\f"
+        output += "\n\fheader}"
 
         output += "\n\fbody{"
 
@@ -727,7 +761,7 @@ class Message(object):
         for p in parts:
             if not p.has_key("filename"):
                 output += "\n\fpart{ "
-                output += "ID: %d, Content-type:%s\n" % (p["id"], 
+                output += "ID: %d, Content-type: %s\n" % (p["id"], 
                                                          p["content_type"])
                 if p.has_key("content"):
                     output += "\n%s\n" % p["content"]
@@ -742,11 +776,10 @@ class Message(object):
                 output += "\n\fattachment}\n"
 
         output += "\n\fbody}\n"
-        output += "\n\fmessage}\n"
+        output += "\n\fmessage}"
 
         return output
 
-
     def __del__(self):
         """Close and free the notmuch Message"""
         if self._msg is not None: