1 |
from flask import Module, jsonify, request, make_response, abort, g, json |
2 |
#import json |
3 |
from sqlalchemy.exc import IntegrityError |
4 |
|
5 |
from swtstore.classes.models import Context |
6 |
from swtstore.classes.models import Sweet |
7 |
from swtstore.classes.exceptions import AlreadyExistsError |
8 |
from swtstore.classes.utils import urlnorm # normalize URLs |
9 |
from swtstore.classes.utils.httputils import make_cross_origin_headers |
10 |
from swtstore.classes import oauth |
11 |
|
12 |
|
13 |
api = Module(__name__) |
14 |
|
15 |
|
16 |
# Get a specific sweet |
17 |
@api.route('/sweets/<int:id>', methods=['GET']) |
18 |
def getSweetById(id): |
19 |
try: |
20 |
sweet = Sweet.query.get(id) |
21 |
except: |
22 |
abort(404) |
23 |
|
24 |
if sweet is None: |
25 |
abort(404) |
26 |
|
27 |
print sweet |
28 |
return jsonify(sweet.to_dict()) |
29 |
|
30 |
|
31 |
# Post a sweet to the sweet store |
32 |
@api.route('/sweets', methods=['OPTIONS', 'POST']) |
33 |
@oauth.require_oauth('email', 'sweet') |
34 |
def createSweet(oauth_request): |
35 |
|
36 |
response = make_response() |
37 |
|
38 |
client = oauth_request.client |
39 |
|
40 |
#TODO: check if response is coming from a registered client |
41 |
response = make_cross_origin_headers(response, client.host_url) |
42 |
|
43 |
if request.method == 'OPTIONS': |
44 |
response.status_code = 200 |
45 |
return response |
46 |
|
47 |
if request.json: |
48 |
payload = request.json |
49 |
if request.data: |
50 |
payload = json.loads(request.data) |
51 |
else: |
52 |
print 'data not found in payload!' |
53 |
g.error= 'data not found in payload!' |
54 |
abort(400) |
55 |
|
56 |
print 'new sweet payload recvd..' |
57 |
print payload |
58 |
|
59 |
# the payload has to be a list; a list of swts |
60 |
for each in payload: |
61 |
if 'what' not in each and 'where' not in\ |
62 |
each and 'how' not in each: |
63 |
|
64 |
print 'Invalid Request..' |
65 |
abort(400) |
66 |
|
67 |
# all ok. create swts from the list now |
68 |
|
69 |
swts = [] |
70 |
for each in payload: |
71 |
|
72 |
what = Context.query.filter_by(name=each['what']).first() |
73 |
|
74 |
if what is None: |
75 |
print 'Context doesn\'t exist' |
76 |
g.error = 'Context doesn\'t exist' |
77 |
abort(400) # this context doesn't exist! |
78 |
|
79 |
# Get the authenticated user from the oauth request object. |
80 |
# Older swtr clients sending `who` in string will be ignored. |
81 |
who = oauth_request.user |
82 |
|
83 |
print 'SWEET DATA' |
84 |
print '------------' |
85 |
print who |
86 |
print what |
87 |
print each['where'] |
88 |
print each['how'] |
89 |
print '-------------' |
90 |
|
91 |
new_sweet = Sweet(who, what, each['where'], each['how']) |
92 |
|
93 |
new_sweet.persist() |
94 |
print new_sweet |
95 |
swts.append(new_sweet.id) |
96 |
|
97 |
response.status_code = 200 |
98 |
response.data = json.dumps(swts) |
99 |
return response |
100 |
|
101 |
|
102 |
# The Sweet query API: /sweets/q?who=<>&what=<>&where=<> |
103 |
# args: who, what, where |
104 |
@api.route('/sweets/q', methods=['GET', 'OPTIONS']) |
105 |
@oauth.require_oauth('sweet') |
106 |
def querySweets(oauth_request): |
107 |
|
108 |
response = make_response() |
109 |
response = make_cross_origin_headers(response, |
110 |
oauth_request.client.host_url) |
111 |
|
112 |
if request.method == 'OPTIONS': |
113 |
reponse.status_code = 200 |
114 |
return response |
115 |
|
116 |
args = request.args |
117 |
|
118 |
# if no arguments are passed, its an invalid request |
119 |
if args is None: |
120 |
abort(400) |
121 |
|
122 |
params = {} |
123 |
if args.get('who'): |
124 |
params['who'] = args.get('who') |
125 |
if args.get('what'): |
126 |
what = Context.query.filter_by(name=args.get('what')).first() |
127 |
params['what'] = what |
128 |
if args.get('where'): |
129 |
params['where'] = urlnorm(args.get('where')) |
130 |
|
131 |
# if none of the above parameters are present, its an invalid request |
132 |
if len(params) == 0: |
133 |
abort(400) |
134 |
|
135 |
print 'recvd params' |
136 |
print params |
137 |
|
138 |
|
139 |
sweets = Sweet.query.filter_by(**params).all() |
140 |
|
141 |
if len(sweets) == 0: |
142 |
print 'No sweets found to satisfy query..' |
143 |
abort(404) |
144 |
|
145 |
swts = [i.to_dict() for i in sweets] |
146 |
|
147 |
response.data = json.dumps(swts) |
148 |
response.headers['Content-type'] = 'application/json' |
149 |
return response |
150 |
|
151 |
|
152 |
# Get a specific context with its definition; based on name |
153 |
@api.route('/contexts/<name>', methods=['GET']) |
154 |
def getContextByName(name): |
155 |
|
156 |
context = Context.query.filter_by(name=name).first() |
157 |
if context is None: |
158 |
abort(404) |
159 |
|
160 |
print context |
161 |
return jsonify(context.to_dict()) |
162 |
|
163 |
# Get a specific context with its definition; based on id |
164 |
@api.route('/contexts/<int:id>', methods=['GET']) |
165 |
def getContextById(id): |
166 |
|
167 |
context = Context.query.get(id) |
168 |
if context is None: |
169 |
abort(404) |
170 |
|
171 |
print context |
172 |
print context.created |
173 |
print context.to_dict() |
174 |
print jsonify(context.to_dict()).data |
175 |
return jsonify(context.to_dict()) |
176 |
|
177 |
|
178 |
# Create a new Sweet Context |
179 |
@oauth.require_oauth('email', 'context') |
180 |
@api.route('/contexts', methods=['POST']) |
181 |
def createContext(): |
182 |
|
183 |
response = make_response() |
184 |
|
185 |
# try our best to get the data from request object |
186 |
if request.json: |
187 |
payload = request.json |
188 |
elif request.data: |
189 |
payload = json.loads(request.data) |
190 |
else: |
191 |
# if not found send back a 400 |
192 |
abort(400) |
193 |
|
194 |
#TODO: change it to logger component |
195 |
print 'new context payload recvd..' |
196 |
print payload |
197 |
|
198 |
# if data is invalid send back 400 |
199 |
if 'name' not in payload and 'definition' not in payload: |
200 |
abort(400) |
201 |
|
202 |
try: |
203 |
new_context = Context(payload['name'], payload['definition']) |
204 |
|
205 |
except AlreadyExistsError: |
206 |
# context with same name exists; send back 400? |
207 |
print 'Already Exists Error' |
208 |
abort(400) |
209 |
|
210 |
print 'new context' |
211 |
print new_context |
212 |
# all ok. save the new context |
213 |
res = new_context.persist() |
214 |
|
215 |
response.status_code = 200 |
216 |
return response |
217 |
|
218 |
|
219 |
# Send back logged in user data |
220 |
@api.route('/users/me', methods=['GET', 'OPTIONS']) |
221 |
@oauth.require_oauth('email') |
222 |
def getCurrentUser(oauth_request): |
223 |
response = make_response() |
224 |
response = make_cross_origin_headers(response, |
225 |
oauth_request.client.host_url) |
226 |
response.status_code = 200 |
227 |
|
228 |
if request.method == 'OPTIONS': |
229 |
return response |
230 |
|
231 |
response.data = json.dumps(oauth_request.user.to_dict()) |
232 |
return response |