3 """Serve a JSON API for getting/setting notmuch tags with nmbug commits."""
17 app = flask.Flask(__name__)
18 app.config['CORS_HEADERS'] = 'Content-Type'
21 TAG_PREFIX = os.getenv('NMBPREFIX', 'notmuch::')
25 @app.route('/tags', methods=['GET'])
28 database = notmuch.Database(path=NOTMUCH_PATH)
30 for t in database.get_all_tags():
31 if t.startswith(TAG_PREFIX):
32 tags.add(t[len(TAG_PREFIX):])
35 return flask.Response(
36 response=json.dumps(sorted(tags)),
37 mimetype='application/json')
40 def _message_tags(message):
42 tag[len(TAG_PREFIX):] for tag in message.get_tags()
43 if tag.startswith(TAG_PREFIX))
46 @app.route('/mid/<message_id>', methods=['GET', 'POST'])
47 def message_id_tags(message_id):
48 if flask.request.method == 'POST':
49 changes = flask.request.get_json()
50 database = notmuch.Database(
52 mode=notmuch.Database.MODE.READ_WRITE)
54 message = database.find_message(message_id)
56 return flask.Response(status=404)
57 database.begin_atomic()
59 for change in changes:
60 if change.startswith('+'):
61 message.add_tag(TAG_PREFIX + change[1:])
62 elif change.startswith('-'):
63 message.remove_tag(TAG_PREFIX + change[1:])
65 return flask.Response(status=400)
68 tags = _message_tags(message=message)
71 nmbug.commit(message='nmhive: {} {}'.format(
72 message_id, ' '.join(changes)))
73 elif flask.request.method == 'GET':
74 database = notmuch.Database(path=NOTMUCH_PATH)
76 message = database.find_message(message_id)
78 return flask.Response(status=404)
79 tags = _message_tags(message=message)
82 return flask.Response(
83 response=json.dumps(tags),
84 mimetype='application/json')
87 @app.route('/gmane/<group>/<int:article>', methods=['GET'])
88 def gmane_message_id(group, article):
89 url = 'http://download.gmane.org/{}/{}/{}'.format(
90 group, article, article + 1)
91 response = urllib.request.urlopen(url=url, timeout=3)
92 mbox_bytes = response.read()
93 with tempfile.NamedTemporaryFile(prefix='nmbug-', suffix='.mbox') as f:
95 mbox = mailbox.mbox(path=f.name)
96 _, message = mbox.popitem()
97 message_id = message['message-id']
98 return flask.Response(
99 response=message_id.lstrip('<').rstrip('>'),
100 mimetype='text/plain')
103 if __name__ == '__main__':
106 parser = argparse.ArgumentParser(description=__doc__)
108 '-H', '--host', default='127.0.0.1',
109 help='The hostname to listen on.')
111 '-p', '--port', type=int, default=5000,
112 help='The port to listen on.')
114 args = parser.parse_args()
116 app.run(host=args.host, port=args.port)