Commit 52db24bdd0a24c472877da4d26a809b54a3ae2bc

Remove older script of swtstore implementation
swtr.py
(0 / 425)
  
1# -*- coding: utf-8 -*-
2"""
3 swtr
4 ~~~~~~
5
6 http://swtr.us
7
8 :license: BSD, see LICENSE for more details.
9"""
10from __future__ import with_statement
11from pymongo import Connection
12from bson.objectid import ObjectId
13from bson.errors import InvalidId
14from flask import Flask, request, session, g, redirect, url_for, abort, \
15 render_template, flash, _app_ctx_stack, make_response, jsonify
16from urllib import unquote_plus
17import json
18import conf
19import requests
20
21# TODO:
22# restify
23# APIs as follows:
24# GET /sweets/q -> query sweets
25# args: who, where, what, how
26# GET /sweets/<id> -> get specific sweet
27# POST /sweets -> post sweets (one or a batch of)
28# OPTIONS /sweets - > CORS policy .. understand it better
29# classes!
30# sqlAlchemy
31# Postgres
32# Persona, Auth in API endpoints
33
34# TODO: move this in a config file
35# configuration
36
37DATABASE = 'sweets_production'
38COLLECTION_NAME = 'posts'
39DEBUG = True
40SECRET_KEY = conf.SECRET_KEY
41USERNAME = 'admin'
42PASSWORD = 'default'
43DB_PORT = 27017
44DB_HOST = 'localhost'
45URL = 'http://localhost:5001'
46MOZ_PERSONA_VERIFIER = 'https://verifier.login.persona.org/verify'
47MOZ_PERSONA_AUDIENCE = 'http://localhost:5000'
48
49appURL_map = {'img-anno': 'http://localhost:5000/?where=',
50 're-narration': 'http://y.a11y.in/web?foruri=',
51 'idh-mowl': 'http://app.swtr.us/?where=',
52 'testFromAPI': 'http://app.swtr.us/?where='}
53
54# create our little application :)
55# ^ ... It's going to be big now :P
56app = Flask(__name__)
57app.config.from_object(__name__)
58app.config.from_envvar('FLASKR_SETTINGS', silent=True)
59
60# Jinja filters
61app.jinja_env.filters['len'] = len
62
63
64def validateSweet(payload):
65 for i in payload:
66 try:
67 if len(i['who']) and len(i['what']) and len(i['where']) and\
68 len(i['how']) and len(i['created']):
69 pass
70 else:
71 return False
72 except KeyError:
73 return False
74 return True
75
76
77def getUsers():
78 db = g.connection[app.config['DATABASE']]
79 coll = db['sweet_users']
80 users = []
81 for i in coll.find():
82 users.append(i['user'])
83 return users
84
85def gatherStats(coll):
86 stats = {}
87 stats['total_sweets'] = coll.count()
88 return stats
89
90@app.before_request
91def init_db():
92 g.connection = Connection(app.config['DB_HOST'], app.config['DB_PORT'])
93 db = g.connection[app.config['DATABASE']]
94 g.collection = db[app.config["COLLECTION_NAME"]]
95 g.stats = gatherStats(g.collection)
96
97
98@app.teardown_request
99def close_db(exception):
100 g.connection.disconnect()
101
102
103@app.errorhandler(404)
104def page_not_found(e):
105 return render_template('404.html'), 404
106
107
108@app.errorhandler(500)
109def internal_error(e):
110 return render_template('500.html'), 500
111
112@app.route('/')
113def show_entries():
114 res = g.collection.find().sort('_id',direction=-1).limit(100)
115 entries = make_list(res)
116 return render_template('show_entries.html', entries=entries,
117 appURL_map=appURL_map, stats=g.stats)
118
119
120# TODO: understand if we really need the OPTIONS
121@app.route('/sweets', methods=['POST', 'OPTIONS'])
122@app.route('/add', methods=['POST', 'OPTIONS'])
123def addSweets():
124 print request.method
125
126 if request.method == 'OPTIONS':
127 response = make_response()
128 response.status_code = 200
129 response.headers['Access-Control-Allow-Origin'] =\
130 'http://localhost:5000'
131 response.headers['Access-Control-Max-Age'] = '20days'
132 response.headers['Access-Control-Allow-Headers'] = 'Origin,\
133 X-Requested-With, Content-Type, Accept'
134 return response
135
136 response = make_response()
137 response.headers['Access-Control-Allow-Origin'] = 'http://localhost:5000'
138 response.headers['Access-Control-Allow-Headers'] = 'Origin,\
139 X-Requested-With, Content-Type, Accept'
140 data = {}
141 data_list = []
142
143 if 'email' in session:
144 print 'identifed user'
145 print session['email']
146 else:
147 print 'unidentified user'
148
149 # TODO: find a better way of handling reqeust sweets
150 try:
151 payload = json.loads(request.form['data'])
152 except:
153 try:
154 payload = [{'who': request.form['who'], 'what': request.form['what'],
155 'where': request.form['where'], 'how': request.form['how']}]
156 except:
157 try:
158 payload = request.json
159 except:
160 payload = json.loads(request.data)
161
162
163 valid = validateSweet(payload)
164 if not valid:
165 response.status_code = 400
166 response.data = "Bad or Malformed Request. Please check the validity\
167 of your request"
168 return response
169 print 'swt payload rcvd..'
170 print payload
171 for i in payload:
172 data = i
173 id = g.collection.insert(i)
174 data['permalink'] = app.config['URL'] + '/posts/' + str(ObjectId(id))
175 data['id'] = str(ObjectId(id))
176 del(data['_id'])
177 print 'data', data
178 data_list.append(data)
179 response.data = json.dumps(data_list)
180 print 'swt stored..'
181 return response
182
183
184@app.route('/login', methods=['GET', 'POST'])
185def login():
186 error = None
187 if request.method == 'POST':
188 if request.form['username'] != app.config['USERNAME']:
189 error = 'Invalid username'
190 elif request.form['password'] != app.config['PASSWORD']:
191 error = 'Invalid password'
192 else:
193 session['logged_in'] = True
194 flash('You were logged in')
195 return redirect(url_for('show_entries'))
196 return render_template('login.html', error=error)
197
198
199@app.route('/sweets/q', methods=['GET'])
200def searchSweets():
201 response = make_response()
202 response.status_code = 200
203 response.headers['Access-Control-Allow-Origin'] = 'http://localhost:5000'
204 response.headers['Access-Control-Max-Age'] = '20days'
205 response.headers['Access-Control-Allow-Headers'] = 'Origin,\
206 X-Requested-With, Content-Type, Accept'
207
208 args = request.args
209
210 if args is None:
211 reponse.status_code = 400
212 return response
213
214 #if args['where'] is None:
215 # reponse.status_code = 400
216 # return response
217
218 params = {}
219
220 if args.get('where'):
221 params['where'] = args.get('where')
222 if args.get('who'):
223 params['who'] = args.get('who')
224 if args.get('what'):
225 params['what'] = args.get('what')
226 if args.get('how'):
227 params['how'] = args.get('how')
228
229
230 print params
231 res = g.collection.find(params)
232
233 if res.count() < 1:
234 response.status_code = 404
235 return response
236
237 swt_list = []
238 for swt in res:
239 _id = swt['_id']
240 del(swt['_id'])
241 swt['id'] = str(_id)
242 swt_list.append(swt)
243
244 response.data = json.dumps(swt_list)
245 return response
246
247
248@app.route('/sweets/<post_id>', methods=['GET'])
249@app.route('/query/<post_id>',methods=['GET'])
250def return_database_entry(post_id):
251 try:
252 res = g.collection.find_one({'_id':ObjectId(post_id)})
253 if(res):
254 res['blog'] = url_for('show_specific_entry', post_id = str(res['_id']))
255 del(res['_id'])
256 return jsonify(res)
257 # entries = make_list(res)
258 # return render_template('show_posts.html', entries=res, str=str)
259 else:
260 abort(404)
261 except InvalidId:
262 abort(404)
263
264
265
266@app.route('/posts/<post_id>',methods=['GET'])
267def show_specific_entry(post_id):
268 try:
269 res = g.collection.find({'_id':ObjectId(post_id)})
270 if(res.count() > 0):
271 #entries = make_list(res)
272 entries = []
273 for i in res:
274 _id = i['_id']
275 del(i['_id'])
276 i['id'] = _id
277 entries.append(i)
278 return render_template('show_posts.html', entries=entries, str=str)
279 else:
280 abort(404)
281 except InvalidId:
282 abort(404)
283
284
285@app.route('/posts/delete/', methods=['POST'])
286def delete_post():
287 try:
288 g.collection.remove({'_id':ObjectId(request.form['post_id'])})
289 return jsonify(status='ok')
290 except:
291 abort(500)
292
293@app.route('/logout')
294def logout():
295 session.pop('logged_in', None)
296 flash('You were logged out')
297 return redirect(url_for('show_entries'))
298
299@app.route('/serveUser')
300def serveUser():
301 if "logged_in" in session:
302 #print session["logged_in"]
303 session['key'] = conf.SECRET_KEY
304 return render_template('user.html')
305 else:
306 return render_template('login.html', error=None)
307
308@app.route('/user/', methods=['POST', 'GET'])
309@app.route('/user/<user_id>', methods=['GET'])
310def user(user_id='all'):
311 if request.method == 'POST':
312 response = make_response()
313 db = g.connection[app.config['DATABASE']]
314 collection = db['sweet_users']
315
316 # check if user already exists
317 if request.form['user'] in getUsers():
318 #print 'user already exists!'
319 flash('User already exists!')
320 return redirect(url_for('serveUser'))
321
322 # else insert new user
323 collection.insert({'user': request.form['user'],
324 'key': request.form['key']})
325 response.status_code = 200
326 response.data = 'User added.'
327 return response
328
329 elif request.method == 'GET':
330 db = g.connection[app.config['DATABASE']]
331 collection = db['sweet_users']
332 users = []
333 if user_id == 'all':
334 users = getUsers()
335 else:
336 user = collection.find_one({'user': user_id})
337 if user:
338 users.append(user['user'])
339 else:
340 abort(404)
341 return render_template("users.html", users=users)
342
343
344@app.route('/authenticate', methods=['POST','GET'])
345def authenticate():
346 if request.method == "POST":
347 response = make_response()
348 db = g.connection[app.config['DATABASE']]
349 collection = db['sweet_users']
350 for i in collection.find():
351 if i['user'] == request.form['user'] and i['key'] == request.form['hash']:
352 response.status_code = 200
353 response.headers['Access-Control-Allow-Origin'] = '*'
354 return response
355 else:
356 pass
357 response.status_code = 403
358 response.headers['Access-Control-Allow-Origin'] = '*'
359 return response
360 elif request.method == "GET":
361 return app.send_static_file("sweet-authenticate.js")
362
363@app.route('/auth/login', methods=['POST'])
364def authLogin():
365 response = make_response()
366 response.headers['Access-Control-Allow-Origin'] = 'http://localhost:5000'
367 response.headers['Access-Control-Allow-Credentials'] = 'true'
368 response.headers['Access-Control-Max-Age'] = '20days'
369 response.headers['Access-Control-Allow-Headers'] = 'Origin,\
370 X-Requested-With, Content-Type, Accept'
371
372 if 'assertion' not in request.form:
373 response.status_code = 400
374 return response
375
376 data = {'assertion': request.form['assertion'], 'audience':
377 MOZ_PERSONA_AUDIENCE}
378 resp = requests.post(MOZ_PERSONA_VERIFIER, data=data, verify=True)
379 print resp.status_code
380 print resp.json()
381
382 if resp.ok:
383 verified_data = json.loads(resp.content)
384 if verified_data['status'] == 'okay':
385 #session.update({'email': verified_data['email']})
386 session['email'] = verified_data['email']
387 response.status_code = 200
388 response.data = {'email': verified_data['email']}
389 return response
390
391 response.status_code = 500
392 return response
393
394@app.route('/auth/logout', methods=['POST'])
395def authLogout():
396 response = make_response()
397 response.headers['Access-Control-Allow-Origin'] = 'http://localhost:5000'
398 response.headers['Access-Control-Allow-Credentials'] = 'true'
399 response.headers['Access-Control-Max-Age'] = '20days'
400 response.headers['Access-Control-Allow-Headers'] = 'Origin,\
401 X-Requested-With, Content-Type, Accept'
402
403 if 'email' in session:
404 print 'logging out '
405 print session['email']
406 session.pop('email')
407
408 response.status_code = 200
409 return response
410
411def make_list(res):
412 entries = []
413 for row in res:
414 d = row
415 d['id'] = str(row['_id'])
416 try:
417 if d['who'] in getUsers() or d['author'] in getUsers():
418 d['registered'] = True
419 except KeyError:
420 pass
421 entries.append(d)
422 return entries
423
424if __name__ == '__main__':
425 app.run(debug=True, port=5001)
  
1# -*- coding: utf-8 -*-
2"""
3 swtr
4 ~~~~~~
5
6 http://swtr.us
7
8 :license: BSD, see LICENSE for more details.
9"""
10from __future__ import with_statement
11from pymongo import Connection
12from bson.objectid import ObjectId
13from bson.errors import InvalidId
14from flask import Flask, request, session, g, redirect, url_for, abort, \
15 render_template, flash, _app_ctx_stack, make_response, jsonify
16from urllib import unquote_plus
17import json
18import conf
19import requests
20
21# TODO:
22# restify
23# APIs as follows:
24# GET /sweets/q -> query sweets
25# args: who, where, what, how
26# GET /sweets/<id> -> get specific sweet
27# POST /sweets -> post sweets (one or a batch of)
28# OPTIONS /sweets - > CORS policy .. understand it better
29# classes!
30# sqlAlchemy
31# Postgres
32# Persona, Auth in API endpoints
33
34# TODO: move this in a config file
35# configuration
36
37DATABASE = 'sweets_production'
38COLLECTION_NAME = 'posts'
39DEBUG = True
40SECRET_KEY = conf.SECRET_KEY
41USERNAME = 'admin'
42PASSWORD = 'default'
43DB_PORT = 27017
44DB_HOST = 'localhost'
45URL = 'http://localhost:5001'
46MOZ_PERSONA_VERIFIER = 'https://verifier.login.persona.org/verify'
47MOZ_PERSONA_AUDIENCE = 'http://localhost:5000'
48
49appURL_map = {'img-anno': 'http://localhost:5000/?where=',
50 're-narration': 'http://y.a11y.in/web?foruri=',
51 'idh-mowl': 'http://app.swtr.us/?where=',
52 'testFromAPI': 'http://app.swtr.us/?where='}
53
54# create our little application :)
55# ^ ... It's going to be big now :P
56app = Flask(__name__)
57app.config.from_object(__name__)
58app.config.from_envvar('FLASKR_SETTINGS', silent=True)
59
60# Jinja filters
61app.jinja_env.filters['len'] = len
62
63
64def validateSweet(payload):
65 for i in payload:
66 try:
67 if len(i['who']) and len(i['what']) and len(i['where']) and\
68 len(i['how']) and len(i['created']):
69 pass
70 else:
71 return False
72 except KeyError:
73 return False
74 return True
75
76
77def getUsers():
78 db = g.connection[app.config['DATABASE']]
79 coll = db['sweet_users']
80 users = []
81 for i in coll.find():
82 users.append(i['user'])
83 return users
84
85def gatherStats(coll):
86 stats = {}
87 stats['total_sweets'] = coll.count()
88 return stats
89
90@app.before_request
91def init_db():
92 g.connection = Connection(app.config['DB_HOST'], app.config['DB_PORT'])
93 db = g.connection[app.config['DATABASE']]
94 g.collection = db[app.config["COLLECTION_NAME"]]
95 g.stats = gatherStats(g.collection)
96
97
98@app.teardown_request
99def close_db(exception):
100 g.connection.disconnect()
101
102
103@app.errorhandler(404)
104def page_not_found(e):
105 return render_template('404.html'), 404
106
107
108@app.errorhandler(500)
109def internal_error(e):
110 return render_template('500.html'), 500
111
112@app.route('/')
113def show_entries():
114 res = g.collection.find().sort('_id',direction=-1).limit(100)
115 entries = make_list(res)
116 return render_template('show_entries.html', entries=entries,
117 appURL_map=appURL_map, stats=g.stats)
118
119
120# TODO: understand if we really need the OPTIONS
121@app.route('/sweets', methods=['POST', 'OPTIONS'])
122@app.route('/add', methods=['POST', 'OPTIONS'])
123def addSweets():
124 print request.method
125
126 if request.method == 'OPTIONS':
127 response = make_response()
128 response.status_code = 200
129 response.headers['Access-Control-Allow-Origin'] =\
130 'http://localhost:5000'
131 response.headers['Access-Control-Max-Age'] = '20days'
132 response.headers['Access-Control-Allow-Headers'] = 'Origin,\
133 X-Requested-With, Content-Type, Accept'
134 return response
135
136 response = make_response()
137 response.headers['Access-Control-Allow-Origin'] = 'http://localhost:5000'
138 response.headers['Access-Control-Allow-Headers'] = 'Origin,\
139 X-Requested-With, Content-Type, Accept'
140 data = {}
141 data_list = []
142
143 if 'email' in session:
144 print 'identifed user'
145 print session['email']
146 else:
147 print 'unidentified user'
148
149 # TODO: find a better way of handling reqeust sweets
150 try:
151 payload = json.loads(request.form['data'])
152 except:
153 try:
154 payload = [{'who': request.form['who'], 'what': request.form['what'],
155 'where': request.form['where'], 'how': request.form['how']}]
156 except:
157 try:
158 payload = request.json
159 except:
160 payload = json.loads(request.data)
161
162
163 valid = validateSweet(payload)
164 if not valid:
165 response.status_code = 400
166 response.data = "Bad or Malformed Request. Please check the validity\
167 of your request"
168 return response
169 print 'swt payload rcvd..'
170 print payload
171 for i in payload:
172 data = i
173 id = g.collection.insert(i)
174 data['permalink'] = app.config['URL'] + '/posts/' + str(ObjectId(id))
175 data['id'] = str(ObjectId(id))
176 del(data['_id'])
177 print 'data', data
178 data_list.append(data)
179 response.data = json.dumps(data_list)
180 print 'swt stored..'
181 return response
182
183
184@app.route('/login', methods=['GET', 'POST'])
185def login():
186 error = None
187 if request.method == 'POST':
188 if request.form['username'] != app.config['USERNAME']:
189 error = 'Invalid username'
190 elif request.form['password'] != app.config['PASSWORD']:
191 error = 'Invalid password'
192 else:
193 session['logged_in'] = True
194 flash('You were logged in')
195 return redirect(url_for('show_entries'))
196 return render_template('login.html', error=error)
197
198
199@app.route('/sweets/q', methods=['GET'])
200def searchSweets():
201 response = make_response()
202 response.status_code = 200
203 response.headers['Access-Control-Allow-Origin'] = 'http://localhost:5000'
204 response.headers['Access-Control-Max-Age'] = '20days'
205 response.headers['Access-Control-Allow-Headers'] = 'Origin,\
206 X-Requested-With, Content-Type, Accept'
207
208 args = request.args
209
210 if args is None:
211 reponse.status_code = 400
212 return response
213
214 #if args['where'] is None:
215 # reponse.status_code = 400
216 # return response
217
218 params = {}
219
220 if args.get('where'):
221 params['where'] = args.get('where')
222 if args.get('who'):
223 params['who'] = args.get('who')
224 if args.get('what'):
225 params['what'] = args.get('what')
226 if args.get('how'):
227 params['how'] = args.get('how')
228
229
230 print params
231 res = g.collection.find(params)
232
233 if res.count() < 1:
234 response.status_code = 404
235 return response
236
237 swt_list = []
238 for swt in res:
239 _id = swt['_id']
240 del(swt['_id'])
241 swt['id'] = str(_id)
242 swt_list.append(swt)
243
244 response.data = json.dumps(swt_list)
245 return response
246
247
248@app.route('/sweets/<post_id>', methods=['GET'])
249@app.route('/query/<post_id>',methods=['GET'])
250def return_database_entry(post_id):
251 try:
252 res = g.collection.find_one({'_id':ObjectId(post_id)})
253 if(res):
254 res['blog'] = url_for('show_specific_entry', post_id = str(res['_id']))
255 del(res['_id'])
256 return jsonify(res)
257 # entries = make_list(res)
258 # return render_template('show_posts.html', entries=res, str=str)
259 else:
260 abort(404)
261 except InvalidId:
262 abort(404)
263
264
265
266@app.route('/posts/<post_id>',methods=['GET'])
267def show_specific_entry(post_id):
268 try:
269 res = g.collection.find({'_id':ObjectId(post_id)})
270 if(res.count() > 0):
271 #entries = make_list(res)
272 entries = []
273 for i in res:
274 _id = i['_id']
275 del(i['_id'])
276 i['id'] = _id
277 entries.append(i)
278 return render_template('show_posts.html', entries=entries, str=str)
279 else:
280 abort(404)
281 except InvalidId:
282 abort(404)
283
284
285@app.route('/posts/delete/', methods=['POST'])
286def delete_post():
287 try:
288 g.collection.remove({'_id':ObjectId(request.form['post_id'])})
289 return jsonify(status='ok')
290 except:
291 abort(500)
292
293@app.route('/logout')
294def logout():
295 session.pop('logged_in', None)
296 flash('You were logged out')
297 return redirect(url_for('show_entries'))
298
299@app.route('/serveUser')
300def serveUser():
301 if "logged_in" in session:
302 #print session["logged_in"]
303 session['key'] = conf.SECRET_KEY
304 return render_template('user.html')
305 else:
306 return render_template('login.html', error=None)
307
308@app.route('/user/', methods=['POST', 'GET'])
309@app.route('/user/<user_id>', methods=['GET'])
310def user(user_id='all'):
311 if request.method == 'POST':
312 response = make_response()
313 db = g.connection[app.config['DATABASE']]
314 collection = db['sweet_users']
315
316 # check if user already exists
317 if request.form['user'] in getUsers():
318 #print 'user already exists!'
319 flash('User already exists!')
320 return redirect(url_for('serveUser'))
321
322 # else insert new user
323 collection.insert({'user': request.form['user'],
324 'key': request.form['key']})
325 response.status_code = 200
326 response.data = 'User added.'
327 return response
328
329 elif request.method == 'GET':
330 db = g.connection[app.config['DATABASE']]
331 collection = db['sweet_users']
332 users = []
333 if user_id == 'all':
334 users = getUsers()
335 else:
336 user = collection.find_one({'user': user_id})
337 if user:
338 users.append(user['user'])
339 else:
340 abort(404)
341 return render_template("users.html", users=users)
342
343
344@app.route('/authenticate', methods=['POST','GET'])
345def authenticate():
346 if request.method == "POST":
347 response = make_response()
348 db = g.connection[app.config['DATABASE']]
349 collection = db['sweet_users']
350 for i in collection.find():
351 if i['user'] == request.form['user'] and i['key'] == request.form['hash']:
352 response.status_code = 200
353 response.headers['Access-Control-Allow-Origin'] = '*'
354 return response
355 else:
356 pass
357 response.status_code = 403
358 response.headers['Access-Control-Allow-Origin'] = '*'
359 return response
360 elif request.method == "GET":
361 return app.send_static_file("sweet-authenticate.js")
362
363@app.route('/auth/login', methods=['POST'])
364def authLogin():
365 response = make_response()
366 response.headers['Access-Control-Allow-Origin'] = 'http://localhost:5000'
367 response.headers['Access-Control-Allow-Credentials'] = 'true'
368 response.headers['Access-Control-Max-Age'] = '20days'
369 response.headers['Access-Control-Allow-Headers'] = 'Origin,\
370 X-Requested-With, Content-Type, Accept'
371
372 if 'assertion' not in request.form:
373 response.status_code = 400
374 return response
375
376 data = {'assertion': request.form['assertion'], 'audience':
377 MOZ_PERSONA_AUDIENCE}
378 resp = requests.post(MOZ_PERSONA_VERIFIER, data=data, verify=True)
379 print resp.status_code
380 print resp.json()
381
382 if resp.ok:
383 verified_data = json.loads(resp.content)
384 if verified_data['status'] == 'okay':
385 #session.update({'email': verified_data['email']})
386 session['email'] = verified_data['email']
387 response.status_code = 200
388 response.data = {'email': verified_data['email']}
389 return response
390
391 response.status_code = 500
392 return response
393
394@app.route('/auth/logout', methods=['POST'])
395def authLogout():
396 response = make_response()
397 response.headers['Access-Control-Allow-Origin'] = 'http://localhost:5000'
398 response.headers['Access-Control-Allow-Credentials'] = 'true'
399 response.headers['Access-Control-Max-Age'] = '20days'
400 response.headers['Access-Control-Allow-Headers'] = 'Origin,\
401 X-Requested-With, Content-Type, Accept'
402
403 if 'email' in session:
404 print 'logging out '
405 print session['email']
406 session.pop('email')
407
408 response.status_code = 200
409 return response
410
411def make_list(res):
412 entries = []
413 for row in res:
414 d = row
415 d['id'] = str(row['_id'])
416 try:
417 if d['who'] in getUsers() or d['author'] in getUsers():
418 d['registered'] = True
419 except KeyError:
420 pass
421 entries.append(d)
422 return entries
423
424if __name__ == '__main__':
425 app.run(debug=True, port=5001)