-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy.py
125 lines (107 loc) · 3.83 KB
/
proxy.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import sys
import logging
import os
import zulip
import json
import gevent
from gevent import monkey, Timeout
from functools import wraps
from flask import Flask, request, make_response, Response
MAGIC_KEY = 'fhqwhgads'
monkey.patch_socket()
logging.basicConfig(filename='error.log',level=logging.DEBUG)
app = Flask(__name__)
app.config.from_pyfile('config.py')
client = zulip.Client(email="quebecois-bot@rotq.net", api_key="BfsqBUyxSfMzmKyguETDS3xbG7eNbRGv")
def add_response_headers(headers={}):
"""This decorator adds the headers passed in to the response"""
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
resp = make_response(f(*args, **kwargs))
h = resp.headers
for header, value in headers.items():
h[header] = value
return resp
return decorated_function
return decorator
def require_key():
"""This decorator requires the magic key to access the route"""
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if request.args.get('key') != MAGIC_KEY:
return '{"result": "error", "msg": "bad quebecois key"}'
else:
return f(*args, **kwargs)
return decorated_function
return decorator
@app.route('/subscribe', methods=["OPTIONS"])
@add_response_headers({'Access-Control-Allow-Origin': '*'})
@add_response_headers({'Access-Control-Allow-Headers': 'X-Requested-With'})
def subscribe_options():
return ''
@app.route('/subscribe', methods=["GET"])
@require_key()
@add_response_headers({'Access-Control-Allow-Origin': '*'})
@add_response_headers({'Access-Control-Allow-Headers': 'X-Requested-With'})
def subscribe():
return json.dumps(client.add_subscriptions([{"name": request.args.get('stream_name')}]))
@app.route('/register', methods=["OPTIONS"])
@add_response_headers({'Access-Control-Allow-Origin': '*'})
@add_response_headers({'Access-Control-Allow-Headers': 'X-Requested-With'})
def register_options():
return ''
@app.route('/register', methods=["GET"])
@require_key()
@add_response_headers({'Access-Control-Allow-Origin': '*'})
@add_response_headers({'Access-Control-Allow-Headers': 'X-Requested-With'})
def register():
return json.dumps(client.register(event_types=["message"]))
@app.route('/events', methods=["OPTIONS"])
@add_response_headers({'Access-Control-Allow-Origin': '*'})
@add_response_headers({'Access-Control-Allow-Headers': 'X-Requested-With'})
def events_options():
return ''
@app.route('/events', methods=["GET"])
@require_key()
@add_response_headers({'Access-Control-Allow-Origin': '*'})
@add_response_headers({'Access-Control-Allow-Headers': 'X-Requested-With'})
def events():
queue_id = request.args.get('queue_id')
last_event_id = request.args.get('last_event_id')
def generate():
result = None
while result is None:
try:
timeout = Timeout(25)
timeout.start()
result = json.dumps(client.get_events(
queue_id=queue_id,
last_event_id=last_event_id))
logging.debug('got a response')
except Timeout:
pass
finally:
timeout.cancel()
yield result or ' '
return Response(generate())
@app.route('/messages', methods=["OPTIONS"])
@add_response_headers({'Access-Control-Allow-Origin': '*'})
@add_response_headers({'Access-Control-Allow-Headers': 'X-Requested-With'})
def messages_options():
return ''
@app.route('/messages', methods=["POST"])
@require_key()
@add_response_headers({'Access-Control-Allow-Origin': '*'})
@add_response_headers({'Access-Control-Allow-Headers': 'X-Requested-With'})
def messages():
typ = request.args.get('type')
to = request.args.get('to')
subject = request.args.get('subject')
content = request.form.get('content')
return json.dumps(client.send_message({"type": typ, "to": to, "subject": subject, "content": content}))
@app.route('/public/<filename>')
def public(filename):
logging.debug(filename)
return app.send_static_file(filename)