Skip to content

Commit c7f8723

Browse files
authored
Merge pull request #63 from RGBOARD/saved-images
User Saved Images View
2 parents fd68c5f + ce5ebd8 commit c7f8723

12 files changed

Lines changed: 558 additions & 103 deletions

File tree

app.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def get_all_users():
3535
handler = User(email=get_jwt_identity())
3636
return handler.get_all_users()
3737

38+
3839
@app.route("/user/pagination", methods=['GET'])
3940
@jwt_required()
4041
def get_users_paginated():
@@ -50,6 +51,7 @@ def get_users_paginated():
5051
except Exception as e:
5152
return jsonify({'error': str(e)}), 500
5253

54+
5355
@app.route("/user", methods=['POST'])
5456
def create_user():
5557
handler = User(json_data=request.json)
@@ -119,7 +121,7 @@ def handleUserById(user_id):
119121
def upload_design():
120122
handler = Design(email=get_jwt_identity())
121123
return handler.add_new_design(
122-
title=request.form.get('title'),
124+
title=request.form.get('title'),
123125
pixel_data=request.form.get('pixel_data')
124126
)
125127

@@ -129,7 +131,7 @@ def upload_design():
129131
def update_design_image(design_id):
130132
handler = Design(email=get_jwt_identity())
131133
return handler.update_design_image(
132-
design_id=design_id,
134+
design_id=design_id,
133135
pixel_data=request.form.get('pixel_data')
134136
)
135137

@@ -141,6 +143,16 @@ def get_design():
141143
return handler.get_design(design_id=request.form.get('design_id'))
142144

143145

146+
@app.route("/designs", methods=['GET'])
147+
@jwt_required()
148+
def get_designs():
149+
page = int(request.args.get('page', 1)) # default 1
150+
page_size = int(request.args.get('page_size', 10)) # default 10
151+
152+
handler = Design(email=get_jwt_identity())
153+
return handler.get_user_designs(page=page, page_size=page_size)
154+
155+
144156
@app.route("/design/<int:design_id>/title", methods=['PUT'])
145157
@jwt_required()
146158
def update_design_title():
@@ -172,7 +184,15 @@ def get_approved_designs():
172184
return jsonify(approved), 200
173185

174186

175-
#AdminAction-----------------------------------------------------------------------------------------------------------
187+
@app.route("/design", methods=['DELETE'])
188+
@jwt_required()
189+
def delete_design():
190+
data = request.get_json()
191+
handler = Design(email=get_jwt_identity())
192+
return handler.delete_design(design_id=data.get('design_id'))
193+
194+
195+
# AdminAction-----------------------------------------------------------------------------------------------------------
176196
@app.route("/admin_action", methods=['GET', 'POST'])
177197
def handleAdminAction():
178198
if request.method == 'GET':
@@ -263,14 +283,16 @@ def get_queue_paginated():
263283
except Exception as e:
264284
return jsonify({'error': str(e)}), 500
265285

286+
266287
@app.route("/queue_item/<int:queue_id>/order", methods=['PUT'])
267288
@jwt_required()
268289
def update_item_order(queue_id):
269290
data = request.get_json()
270291
new_order = data.get('new_order')
271292
handler = QueueItem(email=get_jwt_identity())
272293
return handler.update_item_order(queue_id=queue_id, new_order=new_order)
273-
294+
295+
274296
@app.route("/queue_item", methods=['GET', 'POST'])
275297
def handleQueueItem():
276298
if request.method == 'GET':
@@ -324,7 +346,6 @@ def handleQueueItemById(queue_id):
324346
return jsonify("Can not delete record because it is referenced by other records"), 400
325347

326348

327-
328349
@app.route("/queue_item/scheduled", methods=['GET'])
329350
@jwt_required()
330351
def get_scheduled_designs():
@@ -399,5 +420,6 @@ def authorize():
399420
def callback():
400421
return authorize_callback()
401422

423+
402424
if __name__ == '__main__':
403425
app.run()

controller/design.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import json
2-
from flask import jsonify, request
2+
3+
from flask import jsonify
4+
35
from controller.user import User
46
from model.design import DesignDAO
7+
from model.queue_item import QueueItemDAO
58

69

710
def serialize_design(t):
@@ -25,6 +28,11 @@ def make_json_one(t):
2528
return serialize_design(t)
2629

2730

31+
def is_scheduled(design_id):
32+
queue_item_dao = QueueItemDAO()
33+
return queue_item_dao.is_design_scheduled(design_id)
34+
35+
2836
class Design:
2937

3038
def __init__(self, email=None):
@@ -41,14 +49,14 @@ def add_new_design(self, title=None, pixel_data=None):
4149
json.loads(pixel_data)
4250
except json.JSONDecodeError:
4351
return jsonify(error="Invalid pixel data format"), 400
44-
52+
4553
if not title:
4654
title = "Untitled Design"
4755

4856
user_id = self.user.get_user_id()
4957
if user_id is None:
5058
return jsonify(error='User not found'), 404
51-
59+
5260
dao = DesignDAO()
5361
new_id = dao.add_new_design(user_id, title, pixel_data)
5462

@@ -84,6 +92,27 @@ def get_design(self, design_id=None):
8492

8593
return design, 200
8694

95+
def get_user_designs(self, user_id: int = None, page=1, page_size=10):
96+
requesting_user_id = self.user.get_user_id()
97+
98+
if requesting_user_id is None:
99+
return jsonify(error="Couldn't verify user."), 500
100+
101+
if user_id is None:
102+
user_id = requesting_user_id
103+
104+
# admin can see everything, user has restrictions
105+
if requesting_user_id != user_id and not self.user.is_admin():
106+
return jsonify(error="Unauthorized."), 403
107+
108+
design_dao = DesignDAO()
109+
designs = design_dao.get_designs_by_id(user_id, page, page_size)
110+
111+
if designs is None or len(designs) == 0:
112+
return jsonify(error="No designs found."), 404
113+
114+
return jsonify(designs), 200
115+
87116
def update_design_title(self, design_id, title):
88117
if design_id is None:
89118
return jsonify(error="No id provided."), 400
@@ -107,10 +136,13 @@ def update_design_title(self, design_id, title):
107136
def update_design_image(self, design_id, pixel_data=None):
108137
if design_id is None:
109138
return jsonify(error="No id provided."), 400
110-
139+
140+
if is_scheduled(design_id):
141+
return jsonify(error="Design image can't be updated when already in queue."), 400
142+
111143
if not pixel_data:
112144
return jsonify(error="No pixel data provided"), 400
113-
145+
114146
# Validate pixel_data is valid JSON
115147
try:
116148
# Parse the JSON to validate it, but store as string
@@ -179,6 +211,9 @@ def delete_design(self, design_id):
179211
if user_id is None:
180212
return jsonify(error="Couldn't verify user"), 500
181213

214+
if design_id is None:
215+
return jsonify(error="No design id provided"), 400
216+
182217
design_dao = DesignDAO()
183218
design_user_id = design_dao.get_user_id(design_id)
184219

@@ -196,4 +231,3 @@ def getApprovedDesigns(self):
196231
approved_records = dao.getApprovedDesigns()
197232
answer = [serialize_design(record) for record in approved_records]
198233
return answer
199-

model/design.py

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,30 @@ def get_design_by_id(self, design_id: int):
2121
finally:
2222
cursor.close()
2323

24+
def get_designs_by_id(self, user_id: int, page: int, page_size: int):
25+
cursor = self.conn.cursor()
26+
query = (
27+
"SELECT d.*, "
28+
"CASE WHEN q.scheduled THEN 1 ELSE 0 END AS is_scheduled, "
29+
"CASE WHEN q.queue_id IS NOT NULL THEN 1 ELSE 0 END AS is_in_queue "
30+
"FROM design d "
31+
"LEFT JOIN queue_item q ON d.design_id = q.design_id "
32+
"WHERE d.user_id = ? "
33+
"ORDER BY d.updated_at DESC "
34+
"LIMIT ? OFFSET ?;"
35+
)
36+
37+
try:
38+
cursor.execute(query, (user_id, page_size, (page - 1) * page_size))
39+
columns = [col[0] for col in cursor.description]
40+
rows = cursor.fetchall()
41+
result = [dict(zip(columns, row)) for row in rows]
42+
return result
43+
except sqlite3.Error:
44+
return None
45+
finally:
46+
cursor.close()
47+
2448
def get_user_id(self, design_id: int):
2549
"""
2650
This so we can verify the user corresponding to the image in a small transaction.
@@ -114,24 +138,19 @@ def update_design_status(self, design_id: int, design_status: int):
114138
return status
115139

116140
def delete_design(self, design_id):
117-
status = 1
118141
cursor = self.conn.cursor()
119142
query = "DELETE FROM design WHERE design_id = ?"
120143

121144
try:
122145
cursor.execute(query, (design_id,))
123146
self.conn.commit()
124-
status = 0
147+
if cursor.rowcount == 0:
148+
return 1 # No row deleted
149+
return 0
125150
except sqlite3.Error:
126-
status = 1
127-
151+
return 1
128152
finally:
129153
cursor.close()
130-
return status
131-
132-
return result
133-
134-
import logging
135154

136155
def getApprovedDesigns(self):
137156
cursor = self.conn.cursor()
@@ -146,4 +165,3 @@ def getApprovedDesigns(self):
146165
return [] # Return an empty list on error
147166
finally:
148167
cursor.close()
149-

0 commit comments

Comments
 (0)