Skip to content

Commit 709504d

Browse files
Починить комменты, фотки, excludes в гетах и выпилить details, limit=0 fix (#42)
1 parent 31494a5 commit 709504d

12 files changed

Lines changed: 237 additions & 75 deletions

File tree

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
from .db import Credentials, Group, Lecturer, Event, Room, Direction, CommentEvent, CommentLecturer
1+
from .db import Credentials, Group, Lecturer, Event, Room, Direction, CommentEvent, CommentLecturer, EventsLecturers, EventsRooms
22

3-
__all__ = ["Credentials", "Group", "Lecturer", "Event", "Room", "Direction", "CommentEvent", "CommentLecturer"]
3+
__all__ = ["Credentials", "Group", "Lecturer", "Event",
4+
"Room", "Direction", "CommentEvent", "CommentLecturer", "EventsLecturers", "EventsRooms"]

calendar_backend/routes/event.py

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@
33
import logging
44
from typing import Literal
55

6-
from fastapi import APIRouter, Depends, Query
6+
from fastapi import APIRouter, Depends, Query, HTTPException
77
from fastapi_sqlalchemy import db
88

9-
from calendar_backend.exceptions import NotEnoughCriteria
9+
from calendar_backend.exceptions import NotEnoughCriteria, ObjectNotFound
1010
from calendar_backend.methods import auth, list_calendar
11-
from calendar_backend.models import Group, Room, Lecturer, Event, CommentEvent
11+
from calendar_backend.models import Group, Room, Lecturer, Event, EventsLecturers, EventsRooms
12+
from calendar_backend.models import CommentEvent as DbCommentEvent
1213
from calendar_backend.routes.models.event import (
1314
CommentEventGet,
1415
EventGet,
1516
EventPatch,
1617
EventPost,
17-
GetListEvent,
18+
GetListEvent, EventCommentPost, EventCommentPatch, EventComments,
1819
)
1920
from calendar_backend.settings import get_settings
2021

@@ -39,11 +40,16 @@ async def _get_timetable(start: date, end: date, group_id, lecturer_id, room_id,
3940
if group_id:
4041
events = events.filter(Event.group_id == group_id)
4142
elif lecturer_id:
42-
events = events.filter(Event.lecturer == Lecturer.get(lecturer_id, session=db.session))
43+
ids_ = EventsLecturers.get_all(session=db.session).filter(EventsLecturers.lecturer_id == lecturer_id).all()
44+
events = events.filter(Event.id.in_(row.event_id for row in ids_))
4345
elif room_id:
44-
events = events.filter(Event.lecturer == Room.get(room_id, session=db.session))
46+
ids_ = EventsRooms.get_all(session=db.session).filter(EventsRooms.room_id == room_id).all()
47+
events = events.filter(Event.id.in_(row.event_id for row in ids_))
4548
cnt = events.count()
46-
events = events.order_by(Event.start_ts).limit(limit).offset(offset).all()
49+
if limit:
50+
events = events.order_by(Event.start_ts).limit(limit).offset(offset).all()
51+
else:
52+
events = events.order_by(Event.start_ts).offset(offset).all()
4753

4854
fmt = {}
4955
if detail and "comment" not in detail:
@@ -96,19 +102,55 @@ async def http_create_event(event: EventPost, _: auth.User = Depends(auth.get_cu
96102

97103
@event_router.patch("/{id}", response_model=EventGet)
98104
async def http_patch_event(id: int, event_inp: EventPatch, _: auth.User = Depends(auth.get_current_user)) -> EventGet:
99-
return Event.update(id, session=db.session, **event_inp.dict(exclude_unset=True))
105+
return EventGet.from_orm(Event.update(id, session=db.session, **event_inp.dict(exclude_unset=True)))
100106

101107

102108
@event_router.delete("/{id}", response_model=None)
103109
async def http_delete_event(id: int, _: auth.User = Depends(auth.get_current_user)) -> None:
104110
Event.delete(id, session=db.session)
105111

106112

107-
# @event_router.post("/{event_id}/comment", response_model=CommentEventGet, deprecated=True)
108-
# async def http_comment_event(event_id: int, author_name: str, text: str) -> CommentEventGet:
109-
# return CommentEventGet.from_orm(CommentEvent(event_id=event_id, db.session, text, author_name))
113+
@event_router.post("/{id}/comment", response_model=CommentEventGet)
114+
async def http_comment_event(id: int, comment: EventCommentPost) -> CommentEventGet:
115+
return CommentEventGet.from_orm(DbCommentEvent.create(event_id = id, session=db.session, **comment.dict()))
116+
117+
118+
@event_router.patch("/{event_id}/comment/{id}", response_model=CommentEventGet)
119+
async def http_udpate_comment(id: int, event_id: int, comment_inp: EventCommentPatch) -> CommentEventGet:
120+
comment = DbCommentEvent.get(id, session=db.session)
121+
if comment.event_id != event_id:
122+
raise ObjectNotFound(DbCommentEvent, id)
123+
return CommentEventGet.from_orm(DbCommentEvent.update(id, session=db.session, **comment_inp.dict(exclude_unset=True)))
124+
125+
126+
@event_router.get("/{event_id}/comment/{id}", response_model=CommentEventGet)
127+
async def http_get_comment(id: int, event_id: int) -> CommentEventGet:
128+
comment = DbCommentEvent.get(id, session=db.session)
129+
if not comment.event_id == event_id:
130+
raise ObjectNotFound(DbCommentEvent, id)
131+
return CommentEventGet.from_orm(comment)
132+
133+
134+
@event_router.delete("/{id}/comment", response_model=None)
135+
async def http_delete_comment(id: int, event_id: int, _: auth.User = Depends(auth.get_current_user)) -> None:
136+
comment = DbCommentEvent.get(id, session=db.session)
137+
if comment.event_id != event_id:
138+
raise ObjectNotFound(DbCommentEvent, id)
139+
return DbCommentEvent.delete(id=id, session=db.session)
140+
141+
142+
@event_router.get("/{event_id}/comment", response_model=EventComments)
143+
async def http_get_event_comments(event_id: int, limit: int = 10, offset: int = 0) -> EventComments:
144+
res = DbCommentEvent.get_all(session=db.session).filter(DbCommentEvent.event_id == event_id)
145+
if limit:
146+
cnt, res = res.count(), res.offset(offset).limit(limit).all()
147+
else:
148+
cnt, res = res.count(), res.offset(offset).all()
149+
return EventComments(**{
150+
"items": res,
151+
"limit": limit,
152+
"offset": offset,
153+
"total": cnt
154+
})
110155

111156

112-
# @event_router.patch("/{id}/comment", response_model=CommentEventGet, deprecated=True)
113-
# async def http_udpate_comment(comment_id: int, new_text: str) -> CommentEventGet:
114-
# return CommentEventGet.from_orm(await utils.update_comment_event(comment_id, db.session, new_text))

calendar_backend/routes/group.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,18 @@ async def http_get_group_by_id(
2727

2828

2929
@group_router.get("/", response_model=GetListGroup)
30-
async def http_get_groups(query: str = "", limit: int = 10, offset: int = 0) -> dict[str, Any]:
31-
result = Group.get_all(session=db.session).filter(Group.number.contains(query))
32-
return {
33-
"items": [GroupGet.from_orm(row) for row in result.offset(offset).limit(limit).all()],
30+
async def http_get_groups(query: str = "", limit: int = 10, offset: int = 0) -> GetListGroup:
31+
res = Group.get_all(session=db.session).filter(Group.number.contains(query))
32+
if limit:
33+
cnt, res = res.count(), res.offset(offset).limit(limit).all()
34+
else:
35+
cnt, res = res.count(), res.offset(offset).all()
36+
return GetListGroup(**{
37+
"items": res,
3438
"limit": limit,
3539
"offset": offset,
36-
"total": result.count(),
37-
}
40+
"total": cnt,
41+
})
3842

3943

4044
@group_router.post("/", response_model=GroupGet)
@@ -50,7 +54,7 @@ async def http_patch_group(
5054
group_inp: GroupPatch,
5155
_: auth.User = Depends(auth.get_current_user),
5256
) -> GroupGet:
53-
return Group.update(id, **group_inp.dict(exclude_unset=True), session=db.session)
57+
return GroupGet.from_orm(Group.update(id, **group_inp.dict(exclude_unset=True), session=db.session))
5458

5559

5660
@group_router.delete("/{id}", response_model=None)

calendar_backend/routes/lecturer.py

Lines changed: 85 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
import logging
33
from typing import Any, Literal
44

5-
from fastapi import APIRouter, Depends, UploadFile, File, Query
5+
from fastapi import APIRouter, Depends, UploadFile, File, Query, HTTPException
66
from fastapi_sqlalchemy import db
77
from calendar_backend.models.db import Lecturer
8+
from calendar_backend.models.db import CommentLecturer as DbCommentLecturer
9+
from calendar_backend.models.db import Photo as DbPhoto
810

911
from calendar_backend.settings import get_settings
1012
from calendar_backend.methods import utils, auth
@@ -16,8 +18,9 @@
1618
LecturerPatch,
1719
Photo,
1820
LecturerPhotos,
19-
CommentLecturer,
21+
CommentLecturer, LecturerCommentPost, LecturerCommentPatch, LecturerComments
2022
)
23+
from calendar_backend.exceptions import ObjectNotFound
2124

2225
lecturer_router = APIRouter(prefix="/timetable/lecturer", tags=["Lecturer"])
2326
settings = get_settings()
@@ -41,25 +44,17 @@ async def http_get_lecturers(
4144
query: str = "",
4245
limit: int = 10,
4346
offset: int = 0,
44-
details: list[Literal["photo", "description", "comments", ""]] | None = Query([]),
4547
) -> dict[str, Any]:
4648
res = Lecturer.get_all(session=db.session).filter(Lecturer.search(query))
47-
cnt, res = res.count(), res.offset(offset).limit(limit).all()
49+
if limit:
50+
cnt, res = res.count(), res.offset(offset).limit(limit).all()
51+
else:
52+
cnt, res = res.count(), res.offset(offset).all()
4853
for row in res:
4954
row.avatar_link = row.avatar.link if row.avatar else None
5055
result = [LecturerGet.from_orm(row) for row in res]
51-
exclude = []
52-
details = details or [""]
53-
if "" in details:
54-
exclude.append(["photo", "description", "comments"])
55-
if "photo" not in details:
56-
exclude.append("photo")
57-
if "description" not in details:
58-
exclude.append("description")
59-
if "comments" not in details:
60-
exclude.append("comments")
6156
return {
62-
"items": [row.dict(exclude={*exclude}) for row in result],
57+
"items": result,
6358
"limit": limit,
6459
"offset": offset,
6560
"total": cnt,
@@ -68,7 +63,7 @@ async def http_get_lecturers(
6863

6964
@lecturer_router.post("/", response_model=LecturerGet)
7065
async def http_create_lecturer(lecturer: LecturerPost, _: auth.User = Depends(auth.get_current_user)) -> LecturerGet:
71-
return Lecturer.create(session=db.session, **lecturer.dict())
66+
return LecturerGet.from_orm(Lecturer.create(session=db.session, **lecturer.dict()))
7267

7368

7469
@lecturer_router.patch("/{id}", response_model=LecturerGet)
@@ -84,28 +79,88 @@ async def http_delete_lecturer(id: int, _: auth.User = Depends(auth.get_current_
8479
Lecturer.delete(id, session=db.session)
8580

8681

87-
@lecturer_router.post("/{id}/photo", response_model=Photo)
88-
async def http_upload_photo(id: int, photo: UploadFile = File(...)) -> Photo:
89-
return Photo.from_orm(await utils.upload_lecturer_photo(id, db.session, file=photo))
82+
@lecturer_router.post("/{lecturer_id}/photo", response_model=Photo)
83+
async def http_upload_photo(lecturer_id: int, photo: UploadFile = File(...)) -> Photo:
84+
return Photo.from_orm(await utils.upload_lecturer_photo(lecturer_id, db.session, file=photo))
9085

9186

92-
@lecturer_router.get("/{id}/photo", response_model=LecturerPhotos)
93-
async def http_get_lecturer_photos(id: int) -> LecturerPhotos:
94-
lecturer = Lecturer.get(id, session=db.session)
95-
lecturer.links = [row.link for row in lecturer.photos]
96-
return LecturerPhotos.from_orm(lecturer)
87+
@lecturer_router.get("/{lecturer_id}/photo", response_model=LecturerPhotos)
88+
async def http_get_lecturer_photos(lecturer_id: int, limit: int = 10,
89+
offset: int = 0) -> LecturerPhotos:
90+
res = DbPhoto.get_all(session=db.session).filter(DbPhoto.lecturer_id == lecturer_id)
91+
if limit:
92+
cnt, res = res.count(), res.offset(offset).limit(limit).all()
93+
else:
94+
cnt, res = res.count(), res.offset(offset).all()
95+
return LecturerPhotos(**{
96+
"items": [row.link for row in res],
97+
"limit": limit,
98+
"offset": offset,
99+
"total": cnt
100+
})
97101

98102

99-
@lecturer_router.post("/{id}/comment", response_model=CommentLecturer)
100-
async def http_comment_lecturer(id: int, comment_text: str, author_name: str) -> CommentLecturer:
101-
return CommentLecturer.from_orm(await utils.create_comment_lecturer(id, db.session, comment_text, author_name))
103+
@lecturer_router.post("/{lecturer_id}/comment/", response_model=CommentLecturer)
104+
async def http_comment_lecturer(lecturer_id: int, comment: LecturerCommentPost) -> CommentLecturer:
105+
return CommentLecturer.from_orm(DbCommentLecturer.create(lecturer_id=lecturer_id, session=db.session, **comment.dict()))
102106

103107

104-
@lecturer_router.patch("/{id}/comment", response_model=CommentLecturer)
105-
async def http_update_comment_lecturer(comment_id: int, new_text: str) -> CommentLecturer:
106-
return CommentLecturer.from_orm(await utils.update_comment_lecturer(comment_id, db.session, new_text))
108+
@lecturer_router.patch("/{lecturer_id}/comment/{id}", response_model=CommentLecturer)
109+
async def http_update_comment_lecturer(id: int, lecturer_id: int, comment_inp: LecturerCommentPatch) -> CommentLecturer:
110+
comment = DbCommentLecturer.get(id=id, session=db.session)
111+
if comment.lecturer_id != lecturer_id:
112+
raise ObjectNotFound(DbCommentLecturer, id)
113+
return CommentLecturer.from_orm(DbCommentLecturer.update(id, session=db.session, **comment_inp.dict(exclude_unset=True)))
107114

108115

109116
@lecturer_router.post("/{id}/avatar", response_model=LecturerGet)
110117
async def http_set_lecturer_avatar(id: int, photo_id: int) -> LecturerGet:
111118
return LecturerGet.from_orm(await utils.set_lecturer_avatar(id, photo_id, db.session))
119+
120+
121+
@lecturer_router.delete("/{lecturer_id}/comment/{id}", response_model=None)
122+
async def http_delete_comment(id: int, lecturer_id: int, _: auth.User = Depends(auth.get_current_user)) -> None:
123+
comment = DbCommentLecturer.get(id, session=db.session)
124+
if comment.lecturer_id != lecturer_id:
125+
raise ObjectNotFound(DbCommentLecturer, id)
126+
return DbCommentLecturer.delete(id=id, session=db.session)
127+
128+
129+
@lecturer_router.get("/{lecturer_id}/comment/{id}", response_model=CommentLecturer)
130+
async def http_get_comment(id: int, lecturer_id: int) -> CommentLecturer:
131+
comment = DbCommentLecturer.get(id, session=db.session)
132+
if not comment.lecturer_id == lecturer_id:
133+
raise ObjectNotFound(DbCommentLecturer, id)
134+
return CommentLecturer.from_orm(comment)
135+
136+
137+
@lecturer_router.delete("/{lecturer_id}/photo/{id}", response_model=None)
138+
async def http_delete_photo(id: int, lecturer_id: int) -> None:
139+
photo = DbPhoto.get(id, session=db.session)
140+
if photo.lecturer_id != lecturer_id:
141+
raise ObjectNotFound(DbPhoto, id)
142+
return DbPhoto.delete(id=id, session=db.session)
143+
144+
145+
@lecturer_router.get("/{lecturer_id}/comment/", response_model=LecturerComments)
146+
async def http_get_all_lecturer_comments(lecturer_id: int, limit: int = 10, offset: int = 0) -> LecturerComments:
147+
res = DbCommentLecturer.get_all(session=db.session).filter(DbCommentLecturer.lecturer_id == lecturer_id)
148+
if limit:
149+
cnt, res = res.count(), res.offset(offset).limit(limit).all()
150+
else:
151+
cnt, res = res.count(), res.offset(offset).all()
152+
return LecturerComments(**{
153+
"items": res,
154+
"limit": limit,
155+
"offset": offset,
156+
"total": cnt
157+
})
158+
159+
160+
@lecturer_router.get("/{lecturer_id}/photo/{id}", response_model=Photo)
161+
async def get_photo(id: int, lecturer_id: int) -> Photo:
162+
photo = DbPhoto.get(id, session=db.session)
163+
if photo.lecturer_id != lecturer_id:
164+
raise ObjectNotFound(DbPhoto, id)
165+
return Photo.from_orm(photo)
166+

calendar_backend/routes/models/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
LecturerPatch,
66
LecturerPhotos,
77
LecturerEvents,
8-
CommentLecturer,
98
GetListLecturer,
109
Photo,
10+
LecturerCommentPost,
11+
LecturerCommentPatch,
12+
LecturerComments
1113
)
1214
from .room import RoomPost, RoomPatch, RoomEvents, GetListRoom
1315
from .event import (
@@ -16,5 +18,6 @@
1618
Event,
1719
GetListEvent,
1820
CommentEventGet,
21+
EventComments
1922
)
2023
from .group import GroupPost, GroupPatch, GroupEvents, GetListGroup

calendar_backend/routes/models/event.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,20 @@ class GetListEvent(Base):
5151
limit: int
5252
offset: int
5353
total: int
54+
55+
56+
class EventCommentPost(Base):
57+
text: str
58+
author_name: str
59+
60+
61+
class EventCommentPatch(Base):
62+
text: str
63+
author_name: str
64+
65+
66+
class EventComments(Base):
67+
items: list[CommentEventGet]
68+
limit: int
69+
offset: int
70+
total: int

calendar_backend/routes/models/lecturer.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
from .base import Base, LecturerGet, EventGet, CommentLecturer
22

33

4-
class LecturerPhotos(LecturerGet):
5-
links: list[str]
4+
class LecturerPhotos(Base):
5+
items: list[str]
6+
limit: int
7+
offset: int
8+
total: int
69

710

811
class LecturerPatch(Base):
@@ -41,3 +44,20 @@ class Photo(Base):
4144

4245
class LecturerEvents(LecturerGet):
4346
events: list[EventGet] = []
47+
48+
49+
class LecturerCommentPost(Base):
50+
author_name: str
51+
text: str
52+
53+
54+
class LecturerCommentPatch(Base):
55+
author_name: str | None
56+
text: str | None
57+
58+
59+
class LecturerComments(Base):
60+
items: list[CommentLecturer]
61+
limit: int
62+
offset: int
63+
total: int

0 commit comments

Comments
 (0)