X-Git-Url: https://git.notmuchmail.org/git?a=blobdiff_plain;f=devel%2Fnmbug%2Fnmbug-status;h=19dc48abf557d3c1b5732c075fb82e5793015ebe;hb=bed8b6743d1cfffe8193c6b3571ef460b92e4ade;hp=a7c79206621e8d21ac3305210be45eac54e902be;hpb=d1d84cab1df3e280676553b057d7c59199b382ea;p=notmuch diff --git a/devel/nmbug/nmbug-status b/devel/nmbug/nmbug-status index a7c79206..19dc48ab 100755 --- a/devel/nmbug/nmbug-status +++ b/devel/nmbug/nmbug-status @@ -19,6 +19,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/ . +"""Generate HTML for one or more notmuch searches. + +Messages matching each search are grouped by thread. Each message +that contains both a subject and message-id will have the displayed +subject link to the Gmane view of the message. +""" + from __future__ import print_function from __future__ import unicode_literals @@ -62,28 +69,60 @@ if not hasattr(collections, 'OrderedDict'): # Python 2.6 or earlier collections.OrderedDict = _OrderedDict +class ConfigError (Exception): + """Errors with config file usage + """ + pass + + def read_config(path=None, encoding=None): "Read config from json file" if not encoding: encoding = _ENCODING if path: - fp = open(path) + try: + with open(path, 'rb') as f: + config_bytes = f.read() + except IOError as e: + raise ConfigError('Could not read config from {}'.format(path)) else: nmbhome = os.getenv('NMBGIT', os.path.expanduser('~/.nmbug')) + branch = 'config' + filename = 'status-config.json' # read only the first line from the pipe sha1_bytes = subprocess.Popen( - ['git', '--git-dir', nmbhome, 'show-ref', '-s', 'config'], + ['git', '--git-dir', nmbhome, 'show-ref', '-s', branch], stdout=subprocess.PIPE).stdout.readline() sha1 = sha1_bytes.decode(encoding).rstrip() + if not sha1: + raise ConfigError( + ("No local branch '{branch}' in {nmbgit}. " + 'Checkout a local {branch} branch or explicitly set --config.' + ).format(branch=branch, nmbgit=nmbhome)) - fp_byte_stream = subprocess.Popen( + p = subprocess.Popen( ['git', '--git-dir', nmbhome, 'cat-file', 'blob', - sha1+':status-config.json'], - stdout=subprocess.PIPE).stdout - fp = codecs.getreader(encoding=encoding)(stream=fp_byte_stream) - - return json.load(fp) + '{}:{}'.format(sha1, filename)], + stdout=subprocess.PIPE) + config_bytes, err = p.communicate() + status = p.wait() + if status != 0: + raise ConfigError( + ("Missing status-config.json in branch '{branch}' of" + '{nmbgit}. Add the file or explicitly set --config.' + ).format(branch=branch, nmbgit=nmbhome)) + + config_json = config_bytes.decode(encoding) + try: + return json.loads(config_json) + except ValueError as e: + if not path: + path = "{} in branch '{}' of {}".format( + filename, branch, nmbhome) + raise ConfigError( + 'Could not parse JSON from the config file {}:\n{}'.format( + path, e)) class Thread (list): @@ -255,7 +294,7 @@ class HtmlPage (Page): def _slug(self, string): return self._slug_regexp.sub('-', string) -parser = argparse.ArgumentParser() +parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--text', help='output plain text format', action='store_true') parser.add_argument('--config', help='load config from given file', @@ -267,11 +306,13 @@ parser.add_argument('--get-query', help='get query for view', args = parser.parse_args() -config = read_config(path=args.config) +try: + config = read_config(path=args.config) +except ConfigError as e: + print(e) + sys.exit(1) -_PAGES['text'] = Page() -_PAGES['html'] = HtmlPage( - header=''' +header_template = config['meta'].get('header', ''' @@ -308,22 +349,43 @@ _PAGES['html'] = HtmlPage( tbody:nth-child(4n+3) tr td {{ background-color: #bce; }} + hr {{ + border: 0; + height: 1px; + color: #ccc; + background-color: #ccc; + }}

{title}

-

-Generated: {date}
{blurb}

Views

-'''.format(date=datetime.datetime.utcnow().date(), - title=config['meta']['title'], - blurb=config['meta']['blurb'], - encoding=_ENCODING, - inter_message_padding='0.25em', - border_radius='0.5em'), - footer='\n\n', +''') + +footer_template = config['meta'].get('footer', ''' +
+

Generated: {datetime} + + +''') + +now = datetime.datetime.utcnow() +context = { + 'date': now, + 'datetime': now.strftime('%Y-%m-%d %H:%M:%SZ'), + 'title': config['meta']['title'], + 'blurb': config['meta']['blurb'], + 'encoding': _ENCODING, + 'inter_message_padding': '0.25em', + 'border_radius': '0.5em', + } + +_PAGES['text'] = Page() +_PAGES['html'] = HtmlPage( + header=header_template.format(**context), + footer=footer_template.format(**context), ) if args.list_views: