Skip to content

Commit 664dc9e

Browse files
committed
feat: add support for group actions
1 parent 1d5b933 commit 664dc9e

File tree

5 files changed

+144
-83
lines changed

5 files changed

+144
-83
lines changed

routers/groups_router.py

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pydantic import BaseModel
66
from util.get_class import get_activities_related_to_user
77

8-
from utils import compulsory_temporary_token, get_current_user
8+
from utils import compulsory_temporary_token, get_current_user, validate_object_id
99

1010
router = APIRouter()
1111

@@ -33,32 +33,56 @@ async def create_group(payload: Group, user=Depends(get_current_user)):
3333

3434

3535
@router.get("")
36-
async def get_groups(page: int = -1, perpage: int = 10, user=Depends(get_current_user)):
36+
async def get_groups(
37+
page: int = 1,
38+
perpage: int = 10,
39+
type="all",
40+
search="",
41+
user=Depends(get_current_user),
42+
):
3743
"""
3844
Get all groups
3945
"""
4046

4147
if len(user["per"]) == 0:
4248
raise HTTPException(status_code=403, detail="Permission denied")
4349

44-
count = await db.zvms.groups.count_documents({})
50+
if type == "all":
51+
target = ["permission", "class"]
52+
elif type == "permission":
53+
target = ["permission"]
54+
elif type == "class":
55+
target = ["class"]
56+
else:
57+
raise HTTPException(status_code=400, detail="Invalid type")
58+
59+
count = await db.zvms.groups.count_documents(
60+
{"name": {"$regex": search, "$options": "i"}}
61+
)
4562

4663
pipeline = [
64+
{
65+
"$match": {
66+
"type": {"$in": target},
67+
"name": {"$regex": search, "$options": "i"},
68+
},
69+
},
70+
{"$project": {"description": 0}},
4771
{"$sort": {"name": 1}},
48-
{"$skip": (page - 1) * perpage},
49-
{"$limit": perpage},
72+
{"$skip": 0 if page < 1 else (page - 1) * perpage},
73+
{"$limit": count if page < 1 else perpage},
5074
]
5175

5276
result = await db.zvms.groups.aggregate(pipeline).to_list(None)
5377

54-
5578
for group in result:
5679
group["_id"] = str(group["_id"])
5780

5881
return {
5982
"status": "ok",
6083
"code": 200,
6184
"data": result,
85+
"metadata": {"size": count},
6286
}
6387

6488

@@ -98,7 +122,7 @@ async def update_group_name(
98122
raise HTTPException(status_code=403, detail="Permission denied")
99123

100124
await db.zvms.groups.update_one(
101-
{"_id": ObjectId(group_id)}, {"$set": {"name": payload.name}}
125+
{"_id": validate_object_id(group_id)}, {"$set": {"name": payload.name}}
102126
)
103127

104128
return {
@@ -110,10 +134,11 @@ async def update_group_name(
110134
@router.get("/{group_id}/activity")
111135
async def get_class_activities(
112136
group_id: str,
113-
page: int = -1,
137+
page: int = 1,
114138
perpage: int = 10,
115139
query: str = "",
116-
user=Depends(get_current_user)):
140+
user=Depends(get_current_user),
141+
):
117142
"""
118143
Get activities related to a group
119144
"""
@@ -128,39 +153,48 @@ async def get_class_activities(
128153
}
129154

130155

131-
@router.get('/{group_id}/user')
132-
async def get_users_in_class(group_id: str, page: int = -1, perpage: int = 10, query: str = '', user=Depends(get_current_user)):
133-
'''
156+
@router.get("/{group_id}/user")
157+
async def get_users_in_class(
158+
group_id: str,
159+
page: int = 1,
160+
perpage: int = 10,
161+
search: str = "",
162+
user=Depends(get_current_user),
163+
):
164+
"""
134165
Get users in a class
135-
'''
166+
"""
136167
same_class = False
137-
if 'secretary' in user['per']:
138-
user = await db.zvms.users.find_one({'_id': ObjectId(user['_id'])})
168+
if "secretary" in user["per"]:
169+
user = await db.zvms.users.find_one({"_id": ObjectId(user["_id"])})
139170
if user is None:
140-
raise HTTPException(status_code=404, detail='User not found')
141-
classid = user['group']
171+
raise HTTPException(status_code=404, detail="User not found")
172+
classid = user["group"]
142173
if classid == group_id:
143174
same_class = True
144175
if user is None:
145-
raise HTTPException(status_code=404, detail='User not found')
146-
if not 'admin' in user['per'] and not 'auditor' in user['per'] and not 'department' in user['per'] and (not 'secretary' in user['per'] or not same_class):
147-
raise HTTPException(status_code=403, detail='Permission denied')
148-
count = await db.zvms.users.count_documents({'group': group_id})
176+
raise HTTPException(status_code=404, detail="User not found")
177+
if (
178+
not "admin" in user["per"]
179+
and not "auditor" in user["per"]
180+
and not "department" in user["per"]
181+
and (not "secretary" in user["per"] or not same_class)
182+
):
183+
raise HTTPException(status_code=403, detail="Permission denied")
184+
count = await db.zvms.users.count_documents(
185+
{"group": group_id, "name": {"$regex": search, "$options": "i"}}
186+
)
149187
pipeline = [
150-
{"$match": {"group": group_id}},
151-
{"$sort": {"name": 1}},
188+
{"$match": {"group": group_id, "name": {"$regex": search, "$options": "i"}}},
189+
{"$sort": {"id": 1}},
152190
{"$skip": (page - 1) * perpage},
153191
{"$limit": perpage},
154192
]
155193
result = await db.zvms.users.aggregate(pipeline).to_list(None)
156194
for user in result:
157-
user['_id'] = str(user['_id'])
158-
return {
159-
'status': 'ok',
160-
'code': 200,
161-
'data': result,
162-
'metadata': {'size': count}
163-
}
195+
user["_id"] = str(user["_id"])
196+
return {"status": "ok", "code": 200, "data": result, "metadata": {"size": count}}
197+
164198

165199
class PutGroupDescription(BaseModel):
166200
description: str

routers/images_router.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ async def upload_image(file: UploadFile, user=Depends(get_current_user)):
4343
@router.get("/{image_id}/data")
4444
async def get_image(image_id: str):
4545
data = await db.zvms.images.find_one({"_id": validate_object_id(image_id)})
46+
if data is None:
47+
raise HTTPException(status_code=404, detail="Image not found")
4648
image = image_storage.getBBImage(data['id'])
4749
if image.status_code != 200:
4850
raise HTTPException(status_code=image.status_code, detail=image.text)
@@ -57,10 +59,9 @@ def generate():
5759

5860
@router.delete("/{image_id}")
5961
async def delete_image(image_id: str, user=Depends(compulsory_temporary_token)):
60-
image = db.zvms.images.find_one({"id": image_id})
61-
if not image:
62-
raise HTTPException(status_code=404, detail="Image not found")
6362
image = await db.zvms.images.find_one({"_id": validate_object_id(image_id)})
63+
if image is None:
64+
raise HTTPException(status_code=404, detail="Image not found")
6465
image_storage.remove(image['id'])
6566
await db.zvms.images.delete_one({"_id": validate_object_id(image["_id"])})
6667
return {"status": "ok", "code": 200}

routers/notifications_router.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import datetime
12
from fastapi import APIRouter, HTTPException, Depends, Request
23
from typings.notification import Notification
34
from utils import compulsory_temporary_token, get_current_user, validate_object_id
@@ -99,12 +100,20 @@ async def update_notification_content(
99100
item = await db.zvms.notifications.find_one(
100101
{"_id": validate_object_id(notification_oid)}
101102
)
102-
if user["id"] != item["publisher"] and "admin" not in user["per"]:
103+
if item is None:
104+
raise HTTPException(status_code=404, detail="Notification not found")
105+
if user["id"] != item["publisher"] or "admin" not in user["per"]:
106+
raise HTTPException(status_code=403, detail="Permission denied")
107+
actioner = await db.zvms.users.find_one({"_id": item["publisher"]})
108+
if actioner is None:
109+
raise HTTPException(status_code=404, detail="User not found")
110+
msg = f"{actioner['name']} modified notification at {datetime.now()}"
111+
if user["id"] != item["publisher"] or "admin" not in user["per"]:
103112
raise HTTPException(status_code=403, detail="Permission denied")
104113
# Update notification content
105114
await db.zvms.notifications.update_one(
106115
{"_id": validate_object_id(notification_oid)},
107-
{"$set": {"content": request.content}},
116+
{"$set": {"content": request.content + "\n" + msg}},
108117
)
109118

110119

@@ -118,7 +127,9 @@ async def update_notification_title(
118127
item = await db.zvms.notifications.find_one(
119128
{"_id": validate_object_id(notification_oid)}
120129
)
121-
if user["id"] != item["publisher"] and "admin" not in user["per"]:
130+
if item is None:
131+
raise HTTPException(status_code=404, detail="Notification not found")
132+
if user["id"] != item["publisher"] or "admin" not in user["per"]:
122133
raise HTTPException(status_code=403, detail="Permission denied")
123134
# Update notification title
124135
await db.zvms.notifications.update_one(
@@ -137,6 +148,8 @@ async def delete_notification(
137148
item = await db.zvms.notifications.find_one(
138149
{"_id": validate_object_id(notification_oid)}
139150
)
151+
if item is None:
152+
raise HTTPException(status_code=404, detail="Notification not found")
140153
if user["id"] != item["publisher"] and "admin" not in user["per"]:
141154
raise HTTPException(status_code=403, detail="Permission denied")
142155
# Remove notification

routers/trophies_router.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ async def get_trophy(trophy_oid: str, user=Depends(get_current_user)):
6969
"""
7070
# Get trophy
7171
result = await db.zvms.trophies.find_one({"_id": validate_object_id(trophy_oid)})
72+
if result is None:
73+
raise HTTPException(status_code=404, detail="Not Found")
7274
result["_id"] = str(result["_id"])
7375
return {
7476
"status": "ok",
@@ -125,6 +127,8 @@ async def delete_trophy(trophy_oid: str, user=Depends(compulsory_temporary_token
125127
Delete Trophy
126128
"""
127129
trophy = await db.zvms.trophies.find_one({"_id": validate_object_id(trophy_oid)})
130+
if trophy is None:
131+
raise HTTPException(status_code=404, detail="Not Found")
128132
if "admin" not in user["per"] and user["id"] != trophy["creator"]:
129133
raise HTTPException(status_code=403, detail="Permission denied")
130134
# Delete trophy
@@ -177,6 +181,8 @@ async def update_trophy_member_status(
177181
Update Trophy Member Status
178182
"""
179183
trophy = await db.zvms.trophies.find_one({"_id": validate_object_id(trophy_oid)})
184+
if trophy is None:
185+
raise HTTPException(status_code=404, detail="Not Found")
180186
if "admin" in user["per"]:
181187
pass
182188
elif "department" in user["per"] and user["id"] == trophy["create"]:
@@ -223,6 +229,8 @@ async def delete_trophy_member(
223229
Delete Trophy Member
224230
"""
225231
trophy = await db.zvms.trophies.find_one({"_id": validate_object_id(trophy_oid)})
232+
if trophy is None:
233+
raise HTTPException(status_code=404, detail="Not Found")
226234
if (
227235
"admin" not in user["per"]
228236
and not ("department" in user["per"] and user["id"] == trophy["creator"])
@@ -248,6 +256,8 @@ async def add_trophy_award(
248256
Add Trophy Award
249257
"""
250258
trophy = await db.zvms.trophies.find_one({"_id": validate_object_id(trophy_oid)})
259+
if trophy is None:
260+
raise HTTPException(status_code=404, detail="Not Found")
251261
if "admin" not in user["per"] and user["id"] != trophy["creator"]:
252262
raise HTTPException(status_code=403, detail="Permission denied")
253263
# Add trophy award
@@ -266,6 +276,8 @@ async def delete_trophy_award(
266276
Delete Trophy Award
267277
"""
268278
trophy = await db.zvms.trophies.find_one({"_id": validate_object_id(trophy_oid)})
279+
if trophy is None:
280+
raise HTTPException(status_code=404, detail="Not Found")
269281
if "admin" not in user["per"] and user["id"] != trophy["creator"]:
270282
raise HTTPException(status_code=403, detail="Permission denied")
271283
# Delete trophy award
@@ -293,6 +305,8 @@ async def update_trophy_award_duration(
293305
Update Trophy Award Duration
294306
"""
295307
trophy = await db.zvms.trophies.find_one({"_id": validate_object_id(trophy_oid)})
308+
if trophy is None:
309+
raise HTTPException(status_code=404, detail="Not Found")
296310
if "admin" not in user["per"] and user["id"] != trophy["creator"]:
297311
raise HTTPException(status_code=403, detail="Permission denied")
298312
# Update trophy award duration

0 commit comments

Comments
 (0)