]> rtime.felk.cvut.cz Git - notmuch.git/blobdiff - devel/nmbug/nmbug-status
Add explicit license information
[notmuch.git] / devel / nmbug / nmbug-status
index 6a156af28250e5309a968d1791be38da29c2e00a..a7c79206621e8d21ac3305210be45eac54e902be 100755 (executable)
@@ -1,10 +1,23 @@
 #!/usr/bin/python
 #
 # Copyright (c) 2011-2012 David Bremner <david@tethera.net>
-# License: Same as notmuch
+#
 # dependencies
 #       - python 2.6 for json
 #       - argparse; either python 2.7, or install separately
+#
+# This program 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.
+#
+# This program 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 this program.  If not, see http://www.gnu.org/licenses/ .
 
 from __future__ import print_function
 from __future__ import unicode_literals
@@ -13,7 +26,6 @@ import codecs
 import collections
 import datetime
 import email.utils
-import locale
 try:  # Python 3
     from urllib.parse import quote
 except ImportError:  # Python 2
@@ -24,9 +36,10 @@ import os
 import re
 import sys
 import subprocess
+import xml.sax.saxutils
 
 
-_ENCODING = locale.getpreferredencoding() or sys.getdefaultencoding()
+_ENCODING = 'UTF-8'
 _PAGES = {}
 
 
@@ -41,7 +54,7 @@ if not hasattr(collections, 'OrderedDict'):  # Python 2.6 or earlier
             super(_OrderedDict, self).__setitem__(key, value)
             self._keys.append(key)
 
-        def __values__(self):
+        def values(self):
             for key in self._keys:
                 yield self[key]
 
@@ -89,7 +102,7 @@ class Page (object):
                 byte_stream = sys.stdout.buffer
             except AttributeError:  # Python 2
                 byte_stream = sys.stdout
-            stream = codecs.getwriter(encoding='UTF-8')(stream=byte_stream)
+            stream = codecs.getwriter(encoding=_ENCODING)(stream=byte_stream)
         self._write_header(views=views, stream=stream)
         for view in views:
             self._write_view(database=database, view=view, stream=stream)
@@ -204,19 +217,22 @@ class HtmlPage (Page):
             return
         stream.write('<table>\n')
         for thread in threads:
+            stream.write('  <tbody>\n')
             for message_display_data in thread:
                 stream.write((
-                    '<tr>\n'
-                    '  <td>{date}</td>\n'
-                    '  <td><code>{message-id-term}</code></td>\n'
-                    '</tr>\n'
-                    '<tr>\n'
-                    '  <td>{from}</td>\n'
-                    '  <td>{subject}</td>\n'
-                    '</tr>\n'
+                    '    <tr class="message-first">\n'
+                    '      <td>{date}</td>\n'
+                    '      <td><code>{message-id-term}</code></td>\n'
+                    '    </tr>\n'
+                    '    <tr class="message-last">\n'
+                    '      <td>{from}</td>\n'
+                    '      <td>{subject}</td>\n'
+                    '    </tr>\n'
                     ).format(**message_display_data))
+            stream.write('  </tbody>\n')
             if thread != threads[-1]:
-                stream.write('<tr><td colspan="2"><br /></td></tr>\n')
+                stream.write(
+                    '  <tbody><tr><td colspan="2"><br /></td></tr></tbody>\n')
         stream.write('</table>\n')
 
     def _message_display_data(self, *args, **kwargs):
@@ -226,51 +242,90 @@ class HtmlPage (Page):
         if 'subject' in display_data and 'message-id' in display_data:
             d = {
                 'message-id': quote(display_data['message-id']),
-                'subject': display_data['subject'],
+                'subject': xml.sax.saxutils.escape(display_data['subject']),
                 }
             display_data['subject'] = (
                 '<a href="http://mid.gmane.org/{message-id}">{subject}</a>'
                 ).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')
+parser.add_argument('--config', help='load config from given 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()
+
+config = read_config(path=args.config)
 
 _PAGES['text'] = Page()
 _PAGES['html'] = HtmlPage(
     header='''<!DOCTYPE html>
 <html lang="en">
 <head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Notmuch Patches</title>
+  <meta http-equiv="Content-Type" content="text/html; charset={encoding}" />
+  <title>{title}</title>
+  <style media="screen" type="text/css">
+    table {{
+      border-spacing: 0;
+    }}
+    tr.message-first td {{
+      padding-top: {inter_message_padding};
+    }}
+    tr.message-last td {{
+      padding-bottom: {inter_message_padding};
+    }}
+    td {{
+      padding-left: {border_radius};
+      padding-right: {border_radius};
+    }}
+    tr:first-child td:first-child {{
+      border-top-left-radius: {border_radius};
+    }}
+    tr:first-child td:last-child {{
+      border-top-right-radius: {border_radius};
+    }}
+    tr:last-child td:first-child {{
+      border-bottom-left-radius: {border_radius};
+    }}
+    tr:last-child td:last-child {{
+      border-bottom-right-radius: {border_radius};
+    }}
+    tbody:nth-child(4n+1) tr td {{
+      background-color: #ffd96e;
+    }}
+    tbody:nth-child(4n+3) tr td {{
+      background-color: #bce;
+    }}
+  </style>
 </head>
 <body>
-<h2>Notmuch Patches</h2>
+<h2>{title}</h2>
 <p>
 Generated: {date}<br />
-For more infomation see <a href="http://notmuchmail.org/nmbug">nmbug</a>
+{blurb}
 </p>
 <h3>Views</h3>
-'''.format(date=datetime.datetime.utcnow().date()),
+'''.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='</body>\n</html>\n',
     )
 
-
-parser = argparse.ArgumentParser()
-parser.add_argument('--text', help='output plain text format',
-                    action='store_true')
-parser.add_argument('--config', help='load config from given 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()
-
-config = read_config(path=args.config)
-
 if args.list_views:
     for view in config['views']:
         print(view['title'])