#!/usr/bin/python # # Generate an HTML page with the result of one or more notmuch # searches, (with links to gmane views of each email if available). # # Copyright (c) 2011-2012 David Bremner # Copyright (c) 2014 Carl Worth 72}\n' ).format(**message_display_data)) if thread != threads[-1]: stream.write('\n') def _message_display_data(self, running_data, message): headers = ('thread-id', 'message-id', 'date', 'from', 'subject') data = {} for header in headers: if header == 'thread-id': value = message.get_thread_id() elif header == 'message-id': value = message.get_message_id() data['message-id-term'] = 'id:"{0}"'.format(value) elif header == 'date': value = str(datetime.datetime.utcfromtimestamp( message.get_date()).date()) else: value = message.get_header(header) if header == 'from': (value, addr) = email.utils.parseaddr(value) if not value: value = addr.split('@')[0] data[header] = value next_running_data = data.copy() for header, value in data.items(): if header in ['message-id', 'subject']: continue if value == running_data.get(header, None): data[header] = '' return (next_running_data, data) class HtmlPage (Page): _slug_regexp = re.compile('\W+') def _write_header(self, views, stream): super(HtmlPage, self)._write_header(views=views, stream=stream) stream.write('\n') def _write_view_header(self, view, stream): stream.write('

{title}

\n'.format(**view)) stream.write('

\n') if 'comment' in view: stream.write(view['comment']) stream.write('\n') for line in [ '

This view is generated from the following query:', '

', '

', ' ', 'notmuch search ' + view['query-string'], ' ', '

', ]: stream.write(line) stream.write('\n') def _write_threads(self, threads, stream): if not threads: return stream.write('\n') for thread in threads: stream.write(' \n') for message_display_data in thread: stream.write(( ' \n' ' \n' ' \n' ' \n' ' \n' ).format(**message_display_data)) stream.write(' \n') if thread != threads[-1]: stream.write( ' \n') stream.write('
{from}{date}{subject}

\n') def _message_display_data(self, *args, **kwargs): running_data, display_data = super( HtmlPage, self)._message_display_data( *args, **kwargs) if 'subject' in display_data and 'message-id' in display_data: d = { 'message-id': quote(display_data['message-id']), 'subject': xml.sax.saxutils.escape(display_data['subject']), } display_data['subject'] = ( '{subject}' ).format(**d) for key in ['message-id', 'from']: if key in display_data: display_data[key] = xml.sax.saxutils.escape(display_data[key]) return (running_data, display_data) def _slug(self, string): return self._slug_regexp.sub('-', string) parser = argparse.ArgumentParser() parser.add_argument('--text', help='output plain text format', action='store_true') group = parser.add_mutually_exclusive_group() group.add_argument('--config', help='path to configuration file', metavar='PATH') group.add_argument('--query', help='path to configuration file', metavar='PATH') parser.add_argument('--list-views', help='list views', action='store_true') parser.add_argument('--get-query', help='get query for view', metavar='VIEW') args = parser.parse_args() if (args.config): config = read_config(path=args.config) elif (args.query): config = json.loads(DEFAULT_CONFIG.format(query=args.query)) else: print ('''To use notmuch-to-html, you need to provide a notmuch query. Try: notmuch-to-html --query=tag:inbox Or 'notmuch-to-html --help' for additional options.''') exit (0) _PAGES['text'] = Page() _PAGES['html'] = HtmlPage( header=''' {title}

{title}

{blurb}

Views

'''.format(title=config['meta']['title'], blurb=config['meta']['blurb'], encoding=_ENCODING, inter_message_padding='0.25em', border_radius='0.5em'), footer='''

Generated: {date} courtesy of notmuch and notmuch-to-html. '''.format(date=datetime.datetime.utcnow().date()) ) if args.list_views: for view in config['views']: print(view['title']) sys.exit(0) elif args.get_query != None: for view in config['views']: if args.get_query == view['title']: print(' and '.join(view['query'])) sys.exit(0) else: # only import notmuch if needed import notmuch if args.text: page = _PAGES['text'] else: page = _PAGES['html'] db = notmuch.Database(mode=notmuch.Database.MODE.READ_ONLY) page.write(database=db, views=config['views']) if (args.query): print ('''To customize the output use 'notmuch-to-html --config=CONFIG_FILE' after placing the following content into CONFIG_FILE (note that you can add additional views with their own queries): ''', file=sys.stderr) print (json.dumps(config, indent=4, separators=(',',':')), file=sys.stderr)