From: Jann Horn Date: Sun, 1 Sep 2024 23:37:17 +0000 (+0200) Subject: turn it into a webserver thing X-Git-Url: http://git.thejh.net/?a=commitdiff_plain;h=ceba8d3a1d33da535d1af927d88570e509932149;p=mehlbrei.git turn it into a webserver thing --- diff --git a/app.yaml b/app.yaml new file mode 100644 index 0000000..98e5a42 --- /dev/null +++ b/app.yaml @@ -0,0 +1,7 @@ +runtime: python312 +instance_class: F1 +automatic_scaling: + max_instances: 1 +handlers: +- url: /.* + script: auto diff --git a/threadview.py b/main.py similarity index 71% rename from threadview.py rename to main.py index 0de3861..38c0bfd 100755 --- a/threadview.py +++ b/main.py @@ -5,6 +5,7 @@ import email import email.policy import html import mailbox +from urllib.parse import parse_qs # for diff preparation: # normalize whitespace sequences to single space, for when people reply from @@ -98,12 +99,12 @@ class TextBlockRange: if last_line.lstrip().startswith('On ') and last_line.rstrip().endswith(':'): # Check if next block is quote check_pos = self.start_pos_orig + self.length_orig - print('######## LOOKS LIKE QUOTE: <<'+last_line+'>>') + #print('######## LOOKS LIKE QUOTE: <<'+last_line+'>>') while check_pos < len(self.message.lines.lines): if self.message.lines.lines[check_pos].real_quote: # is real quote, strip last line self.length_orig -= 1 - print(' IS QUOTE!') + #print(' IS QUOTE!') break if not self.message.lines.lines[check_pos].empty: break @@ -122,17 +123,17 @@ class TextBlockRangeset: self.ranges.append(r) def import_rangeset(self, other_ranges): - print('import_rangeset()') - print(' own ranges:') - for r in self.ranges: - print(' '+str(r.start_pos_child)+'-'+str(r.end_pos_child())+' '+('quote' if r.is_quote else 'new')) - print(' import ranges:') - for r in other_ranges: - print(' '+str(r.pos_parent)) + #print('import_rangeset()') + #print(' own ranges:') + #for r in self.ranges: + # print(' '+str(r.start_pos_child)+'-'+str(r.end_pos_child())+' '+('quote' if r.is_quote else 'new')) + #print(' import ranges:') + #for r in other_ranges: + # print(' '+str(r.pos_parent)) own_i = 0 for other_range in other_ranges: - print('importing element with pos_parent='+str(other_range.pos_parent)) + #print('importing element with pos_parent='+str(other_range.pos_parent)) while own_i != len(self.ranges) and other_range.pos_parent >= self.ranges[own_i].end_pos_child(): own_i += 1 if other_range.pos_parent == -1: @@ -153,9 +154,9 @@ class TextBlockRangeset: other_range.move_up_after(self.ranges[own_i-1]) self.ranges.insert(own_i, other_range) - print(' own ranges after:') - for r in self.ranges: - print(' '+str(r.start_pos_child)+'-'+str(r.end_pos_child())+' '+('quote' if r.is_quote else 'new')+' '+r.meta_origin_str()) + #print(' own ranges after:') + #for r in self.ranges: + # print(' '+str(r.start_pos_child)+'-'+str(r.end_pos_child())+' '+('quote' if r.is_quote else 'new')+' '+r.meta_origin_str()) def drop_quotes(self): self.ranges = list(filter(lambda r: not r.is_quote, self.ranges)) @@ -260,7 +261,7 @@ class ThreadMessage: child.dump_tree(level+1, topic_only) def init_diff_recursively(self): - print('init_diff_recursively') + #print('init_diff_recursively') if self.is_diff_root(): self.blocks = TextBlockRangeset() self.blocks.append(TextBlockRange(self, 0, len(self.lines.lines), -1, False)) @@ -279,7 +280,7 @@ class ThreadMessage: for block in child.blocks.ranges: all_child_blocks.append(block) all_child_blocks.sort(key=lambda block:block.pos_parent) - print('importing for '+self.id+' from '+self.from_hdr) + #print('importing for '+self.id+' from '+self.from_hdr) self.blocks.import_rangeset(all_child_blocks) self.blocks.drop_quotes() @@ -287,43 +288,46 @@ class ThreadMessage: # only do this for diff roots, at the end self.blocks.trim_blocks() -mbox = mailbox.mbox('t.mbox', factory=lambda x: email.message_from_binary_file(x, policy=email.policy.default)) -root_message = None -messages_by_id = {} -all_messages = [] -all_topic_roots = [] -message_index = 0 -for msg in mbox: - tmsg = ThreadMessage(msg, message_index) - message_index += 1 - messages_by_id[tmsg.id] = tmsg - #print('have message "'+tmsg.id+'"') - all_messages.append(tmsg) - if tmsg.parent_id == None: - if root_message != None: - raise Exception('more than one root message') - root_message = tmsg - if tmsg.parent_id == None or tmsg.is_patch: - all_topic_roots.append(tmsg) - -if root_message == None: - raise Exception('no root message') - -for tmsg in all_messages: - #print('looking up message "'+tmsg.parent_id+'"') - if not tmsg.parent_id: - continue - if not tmsg.parent_id in messages_by_id: - raise Exception('missing intermediate message') - parent_tmsg = messages_by_id[tmsg.parent_id] - tmsg.parent = parent_tmsg - parent_tmsg.children.append(tmsg) +def parse_mbox(): + mbox = mailbox.mbox('t.mbox', factory=lambda x: email.message_from_binary_file(x, policy=email.policy.default)) + root_message = None + messages_by_id = {} + all_messages = [] + all_topic_roots = [] + message_index = 0 + for msg in mbox: + tmsg = ThreadMessage(msg, message_index) + message_index += 1 + messages_by_id[tmsg.id] = tmsg + #print('have message "'+tmsg.id+'"') + all_messages.append(tmsg) + if tmsg.parent_id == None: + if root_message != None: + raise Exception('more than one root message') + root_message = tmsg + if tmsg.parent_id == None or tmsg.is_patch: + all_topic_roots.append(tmsg) + + if root_message == None: + raise Exception('no root message') + + for tmsg in all_messages: + #print('looking up message "'+tmsg.parent_id+'"') + if not tmsg.parent_id: + continue + if not tmsg.parent_id in messages_by_id: + raise Exception('missing intermediate message') + parent_tmsg = messages_by_id[tmsg.parent_id] + tmsg.parent = parent_tmsg + parent_tmsg.children.append(tmsg) + + root_message.init_diff_recursively() + return all_topic_roots # note: theoretically we can have loops in the "tree" at this point, but they'd # have to be unreachable from the root, so, meh, whatever #root_message.dump_tree(0, False) -root_message.init_diff_recursively() #messages_by_id['<20240827143852.163123189@linuxfoundation.org>'].init_diff_recursively() #for topic in all_topic_roots: # print('TOPIC: '+topic.msg.get('subject', '')) @@ -331,56 +335,69 @@ root_message.init_diff_recursively() # print('') -print('<<<<<<') +#print('<<<<<<') #print(messages_by_id['<20240827143852.163123189@linuxfoundation.org>'].blocks.get_formatted()) -print(root_message.blocks.get_formatted()) -print('>>>>>>') +#print(root_message.blocks.get_formatted()) +#print('>>>>>>') #messages_by_id['<20240827143852.163123189@linuxfoundation.org>'].blocks.dump_meta() -root_message.blocks.dump_meta() - - -with open('/tmp/lkml-out.html', 'wt') as outfile: - outfile.write('\n') - outfile.write('\n') - outfile.write(' \n') - outfile.write(' Mehlbrei\n') - outfile.write(' \n') - outfile.write(' \n') - outfile.write(' \n') - outfile.write('
\n') - outfile.write('

Topics

\n') +#root_message.blocks.dump_meta() + +def app(environ, start_response): + out = [] + query = parse_qs(environ.get('QUERY_STRING', '')) + msgid = query.get('msgid', None) + + all_topic_roots = parse_mbox() + + out.append('') + out.append('') + out.append(' ') + out.append(' Mehlbrei') + out.append(' ') + out.append(' ') + out.append(' ') + out.append('
') + out.append('

Topics

') for topic_root in all_topic_roots: - outfile.write(' '+html.escape(topic_root.msg.get('subject', ''), quote=False)+' ('+str(topic_root.non_diff_root_descendants)+' replies)\n') - outfile.write('
\n') - outfile.write('
\n') + out.append(' '+html.escape(topic_root.msg.get('subject', ''), quote=False)+' ('+str(topic_root.non_diff_root_descendants)+' replies)') + out.append('
') + out.append('
') for topic_root in all_topic_roots: - outfile.write('
\n') + out.append('
') printed_top_header = False printed_threads_header = False for block in topic_root.blocks.ranges: if block.start_pos_child < 0 and not printed_top_header: - outfile.write('

Top-posted messages (sorry this section looks like a mess)

\n') + out.append('

Top-posted messages (sorry this section looks like a mess)

') printed_top_header = True if block.start_pos_child >= 0 and not printed_threads_header: - outfile.write('

Actual thread

\n') + out.append('

Actual thread

') printed_threads_header = True - outfile.write('
\n') - outfile.write('
'+html.escape(block.message.from_hdr, quote=False)+'
\n') - outfile.write('
'+html.escape(block.get_text(), quote=False)+'
\n') - outfile.write('
\n') - outfile.write('
\n') - outfile.write('
\n') - outfile.write(' \n') - outfile.write('\n') + out.append('
') + out.append('
'+html.escape(block.message.from_hdr, quote=False)+'
') + out.append('
'+html.escape(block.get_text(), quote=False)+'
') + out.append('
') + out.append('
') + out.append('
') + out.append(' ') + out.append('') + + out = bytes('\n'.join(out), 'utf-8') + start_response("200 OK", [ + ("Content-Type", "text/html; charset=utf-8"), + ("Content-Length", str(len(out))) + ]) + + return iter([out])