nmhive.py: Accept Content-Type headers via CORS
[nmhive.git] / nmhive.py
1 #!/usr/bin/env python
2
3 import json
4 import mailbox
5 import tempfile
6 import urllib.request
7
8 import flask
9 import flask_cors
10
11
12 app = flask.Flask(__name__)
13 app.config['CORS_HEADERS'] = 'Content-Type'
14 flask_cors.CORS(app)
15
16
17 _AVAILABLE_TAGS = {
18     'bug',
19     'needs-review',
20     'obsolete',
21     'patch',
22     }
23 _TAGS = {}
24
25
26 @app.route('/tags', methods=['GET'])
27 def tags():
28     return flask.Response(
29         response=json.dumps(sorted(_AVAILABLE_TAGS)),
30         mimetype='application/json')
31
32
33 @app.route('/mid/<message_id>', methods=['GET', 'POST'])
34 def message_id_tags(message_id):
35     if flask.request.method == 'POST':
36         tags = _TAGS.get(message_id, set())
37         new_tags = tags.copy()
38         for change in flask.request.get_json():
39             if change.startswith('+'):
40                 new_tags.add(change[1:])
41             elif change.startswith('-'):
42                 try:
43                     new_tags.remove(change[1:])
44                 except KeyError:
45                     return flask.Response(status=400)
46             else:
47                 return flask.Response(status=400)
48         _TAGS[message_id] = new_tags
49         return flask.Response(
50             response=json.dumps(sorted(new_tags)),
51             mimetype='application/json')
52     elif flask.request.method == 'GET':
53         try:
54             tags = _TAGS[message_id]
55         except KeyError:
56             return flask.Response(status=404)
57         return flask.Response(
58             response=json.dumps(sorted(tags)),
59             mimetype='application/json')
60
61
62 @app.route('/gmane/<group>/<int:article>', methods=['GET'])
63 def gmane_message_id(group, article):
64     url = 'http://download.gmane.org/{}/{}/{}'.format(
65         group, article, article + 1)
66     response = urllib.request.urlopen(url=url, timeout=3)
67     mbox_bytes = response.read()
68     with tempfile.NamedTemporaryFile(prefix='nmbug-', suffix='.mbox') as f:
69         f.write(mbox_bytes)
70         mbox = mailbox.mbox(path=f.name)
71         _, message = mbox.popitem()
72         message_id = message['message-id']
73     return flask.Response(
74         response=message_id.lstrip('<').rstrip('>'),
75         mimetype='text/plain')
76
77
78 if __name__ == '__main__':
79     app.debug = True
80     app.run(host='0.0.0.0')