22import sys
33from email .message import EmailMessage
44
5- from util import *
6- from quotes import *
5+ from . util import *
6+ from . quotes import *
77
88def get_message_by_id (msgs , msg_id ):
9+ if msg_id is None or msg_id == "" :
10+ return None
911 # TODO: handle weird brackets stuff
1012 for msg in msgs :
1113 if msg ["message-id" ] == msg_id :
@@ -119,15 +121,27 @@ def __repr__(self):
119121
120122 return "\n " .join (repr_lines )
121123
122- def parse (msg , refs = []):
123- # For some reason Python strips "Re:" prefixes
124- subject = flatten_header_field (msg ["subject" ])
124+ def build_message_tree (messages ):
125+ heads = []
126+ replies = []
127+
128+ for msg in messages :
129+ in_reply_to = get_message_by_id (messages , msg ['in-reply-to' ])
130+ if in_reply_to is None :
131+ heads .append (msg )
132+ else :
133+ replies .append ((msg , in_reply_to ))
134+
135+ if len (heads ) != 1 :
136+ raise Exception ("expected exactly one head message, got " + str (len (heads )))
137+ head = heads [0 ]
125138
126- in_reply_to = get_message_by_id (refs , msg ['in-reply-to' ])
127- if in_reply_to is None or flatten_header_field (in_reply_to ["subject" ]) != subject :
128- text = get_text (msg )
129- text_lines = text .splitlines ()
130- return Thread (text_lines , msg , (0 , len (text_lines )))
139+ replies = sorted (replies , key = lambda reply : reply [0 ]['date' ])
140+
141+ return (head , replies )
142+
143+ def parse_reply (msg , in_reply_to , thread ):
144+ subject = flatten_header_field (msg ["subject" ])
131145
132146 blocks = parse_blocks (msg )
133147 blocks = trim_quotes_footer (blocks )
@@ -136,8 +150,6 @@ def parse(msg, refs=[]):
136150 # print("\n".join([str(block) for block in blocks]))
137151 blocks = merge_blocks (blocks )
138152
139- thread = parse (in_reply_to , refs )
140-
141153 last_quote = None
142154 for block in blocks :
143155 if isinstance (block , Text ):
@@ -162,3 +174,15 @@ def parse(msg, refs=[]):
162174 last_quote = block
163175
164176 return thread
177+
178+ def parse (messages ):
179+ (head , replies ) = build_message_tree (messages )
180+
181+ text = get_text (head )
182+ text_lines = text .splitlines ()
183+ thread = Thread (text_lines , head , (0 , len (text_lines )))
184+
185+ for (msg , in_reply_to ) in replies :
186+ parse_reply (msg , in_reply_to , thread )
187+
188+ return thread
0 commit comments