nmbug.js: Fill in the tag-fetching portion of nmbug.show
[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 flask_cors.CORS(app)
14
15
16 _TAGS = {}
17
18
19 @app.route('/mid/<message_id>', methods=['GET', 'POST'])
20 def message_id_tags(message_id):
21     if flask.request.method == 'POST':
22         tags = _TAGS.get(message_id, set())
23         new_tags = tags.copy()
24         for change in flask.request.get_json():
25             if change.startswith('+'):
26                 new_tags.add(change[1:])
27             elif change.startswith('-'):
28                 try:
29                     new_tags.remove(change[1:])
30                 except KeyError:
31                     return flask.Response(status=400)
32             else:
33                 return flask.Response(status=400)
34         _TAGS[message_id] = new_tags
35         return flask.Response(
36             response=json.dumps(sorted(new_tags)),
37             mimetype='application/json')
38     elif flask.request.method == 'GET':
39         try:
40             tags = _TAGS[message_id]
41         except KeyError:
42             return flask.Response(status=404)
43         return flask.Response(
44             response=json.dumps(sorted(tags)),
45             mimetype='application/json')
46
47
48 @app.route('/gmane/<group>/<int:article>', methods=['GET'])
49 def gmane_message_id(group, article):
50     url = 'http://download.gmane.org/{}/{}/{}'.format(
51         group, article, article + 1)
52     response = urllib.request.urlopen(url=url, timeout=3)
53     mbox_bytes = response.read()
54     with tempfile.NamedTemporaryFile(prefix='nmbug-', suffix='.mbox') as f:
55         f.write(mbox_bytes)
56         mbox = mailbox.mbox(path=f.name)
57         _, message = mbox.popitem()
58         message_id = message['message-id']
59     return flask.Response(
60         response=message_id.lstrip('<').rstrip('>'),
61         mimetype='text/plain')
62
63
64 if __name__ == '__main__':
65     app.debug = True
66     app.run(host='0.0.0.0')