X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=cnotmuch%2Fmessage.py;h=ba93d8fea773fdb1807f9dddc1417973b48caf69;hp=6ae5564795af2f2bbdf5dd5d453b0dc02a575af7;hb=bac66abdd2a02c0af677c3e503ea3bae705287c6;hpb=48ec49f05daad3b0e53e8735bbd8d7a1171676c5 diff --git a/cnotmuch/message.py b/cnotmuch/message.py index 6ae55647..ba93d8fe 100644 --- a/cnotmuch/message.py +++ b/cnotmuch/message.py @@ -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 . +# +# (C) Copyright 2010 Sebastian Spaeth +# Jesse Rosenthal + 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 @@ -197,14 +221,11 @@ class Messages(object): raise NotmuchError next_indent = indent + 1 - + # get replies and print them also out (if there are any) 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 +630,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""" @@ -628,17 +649,20 @@ class Message(object): email_msg = email.message_from_file(fp) fp.close() - # A subfunction to recursively unpack the message parts into a - # list. - def msg_unpacker_gen(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): + """Returns the nth message body part""" + 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 +676,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 +688,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 +697,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 +722,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 +740,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 +749,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 +764,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: