1
- from datetime import datetime as dt
1
+ from datetime import datetime
2
2
from operator import attrgetter
3
3
from typing import Any , Dict , List , Optional
4
4
5
- from fastapi import APIRouter , Depends , Request
5
+ from fastapi import APIRouter , Depends , HTTPException , Request
6
6
from sqlalchemy .exc import SQLAlchemyError
7
7
from sqlalchemy .orm import Session
8
+ from sqlalchemy .orm .exc import MultipleResultsFound , NoResultFound
8
9
from starlette import status
9
10
from starlette .responses import RedirectResponse
10
11
from starlette .status import HTTP_302_FOUND
11
12
12
13
from app .database .database import get_db
13
14
from app .database .models import Event , User , UserEvent
14
- from app .dependencies import templates
15
+ from app .dependencies import logger , templates
15
16
from app .internal .event import validate_zoom_link
16
17
from app .internal .utils import create_model
17
18
from app .routers .user import create_user
@@ -34,10 +35,10 @@ async def create_new_event(request: Request, session=Depends(get_db)):
34
35
data = await request .form ()
35
36
title = data ['title' ]
36
37
content = data ['description' ]
37
- start = dt .strptime (data ['start_date' ] + ' ' + data ['start_time' ],
38
- '%Y-%m-%d %H:%M' )
39
- end = dt .strptime (data ['end_date' ] + ' ' + data ['end_time' ],
40
- '%Y-%m-%d %H:%M' )
38
+ start = datetime .strptime (data ['start_date' ] + ' ' + data ['start_time' ],
39
+ '%Y-%m-%d %H:%M' )
40
+ end = datetime .strptime (data ['end_date' ] + ' ' + data ['end_time' ],
41
+ '%Y-%m-%d %H:%M' )
41
42
user = session .query (User ).filter_by (id = 1 ).first ()
42
43
user = user if user else create_user ("u" , "p" , "e@mail.com" , session )
43
44
owner_id = user .id
@@ -50,30 +51,86 @@ async def create_new_event(request: Request, session=Depends(get_db)):
50
51
51
52
event = create_event (session , title , start , end , owner_id , content ,
52
53
location )
53
- return RedirectResponse (router .url_path_for ('eventview' , id = event .id ),
54
+ return RedirectResponse (router .url_path_for ('eventview' ,
55
+ event_id = event .id ),
54
56
status_code = HTTP_302_FOUND )
55
57
56
58
57
- @router .get ("/view/{id}" )
58
- async def eventview (request : Request , id : int ):
59
+ @router .get ("/{event_id}" )
60
+ async def eventview (request : Request , event_id : int ,
61
+ db : Session = Depends (get_db )):
62
+ try :
63
+ event = get_event_by_id (db , event_id )
64
+ except NoResultFound :
65
+ raise HTTPException (status_code = 404 , detail = "Event not found" )
66
+ except MultipleResultsFound :
67
+ raise HTTPException (status_code = 500 , detail = "Multiple events found" )
68
+ start_format = '%A, %d/%m/%Y %H:%M'
69
+ end_format = ('%H:%M' if event .start .date () == event .end .date ()
70
+ else start_format )
59
71
return templates .TemplateResponse ("event/eventview.html" ,
60
- {"request" : request , "event_id" : id })
72
+ {"request" : request , "event" : event ,
73
+ "start_format" : start_format ,
74
+ "end_format" : end_format })
75
+
76
+
77
+ @router .delete ("/{event_id}" )
78
+ def delete_event (request : Request , event_id : int ,
79
+ db : Session = Depends (get_db )):
80
+ # TODO: Check if the user is the owner of the event.
81
+ try :
82
+ event = get_event_by_id (db , event_id )
83
+ except NoResultFound :
84
+ raise HTTPException (status_code = 404 , detail = "Event not found" )
85
+ except MultipleResultsFound :
86
+ raise HTTPException (status_code = 500 , detail = "Multiple events found" )
87
+
88
+ participants = get_participants_emails_by_event (db , event_id )
89
+
90
+ try :
91
+ db .delete (event )
92
+ db .query (UserEvent ).filter_by (event_id = event_id ).delete ()
93
+ db .commit ()
94
+ except (SQLAlchemyError , TypeError ):
95
+ return templates .TemplateResponse (
96
+ "event/eventview.html" , {"request" : request , "event_id" : event_id },
97
+ status_code = status .HTTP_500_INTERNAL_SERVER_ERROR )
61
98
99
+ if participants and event .start > datetime .now ():
100
+ pass
101
+ # TODO: Send them a cancellation notice
102
+ # if the deletion is successful
103
+ return RedirectResponse (
104
+ url = "/calendar" , status_code = status .HTTP_200_OK )
62
105
63
- def by_id (db : Session , event_id : int ) -> Event :
64
- """Select event by id"""
65
106
66
- return db .query (Event ).filter (Event .id == event_id ).first ()
107
+ def get_event_by_id (db : Session , event_id : int ) -> Event :
108
+ """Gets a single event by id"""
109
+ if not isinstance (db , Session ):
110
+ raise AttributeError (
111
+ f'Could not connect to database. '
112
+ f'db instance type received: { type (db )} ' )
113
+ try :
114
+ event = db .query (Event ).filter_by (id = event_id ).one ()
115
+ except NoResultFound :
116
+ raise NoResultFound (f"Event ID does not exist. ID: { event_id } " )
117
+ except MultipleResultsFound :
118
+ error_message = (
119
+ f'Multiple results found when getting event. Expected only one. '
120
+ f'ID: { event_id } ' )
121
+ logger .critical (error_message )
122
+ raise MultipleResultsFound (error_message )
123
+ return event
67
124
68
125
69
- def is_date_before (start_date : dt , end_date : dt ) -> bool :
126
+ def is_date_before (start_date : datetime , end_date : datetime ) -> bool :
70
127
"""Check if the start date is earlier than the end date"""
71
128
72
129
return start_date < end_date
73
130
74
131
75
- def is_it_possible_to_change_dates (
76
- db : Session , old_event : Event , event : Dict [str , Any ]) -> bool :
132
+ def is_it_possible_to_change_dates (old_event : Event ,
133
+ event : Dict [str , Any ]) -> bool :
77
134
return is_date_before (
78
135
event .get ('start' , old_event .start ),
79
136
event .get ('end' , old_event .end ))
@@ -94,9 +151,13 @@ def update_event(event_id: int, event: Dict, db: Session
94
151
if not event_to_update :
95
152
return None
96
153
try :
97
- old_event = by_id (db = db , event_id = event_id )
98
- if old_event is None or not is_it_possible_to_change_dates (
99
- db , old_event , event_to_update ):
154
+ old_event = get_event_by_id (db , event_id )
155
+ except NoResultFound :
156
+ raise HTTPException (status_code = 404 , detail = "Event not found" )
157
+ except MultipleResultsFound :
158
+ raise HTTPException (status_code = 500 , detail = "Multiple events found" )
159
+ try :
160
+ if not is_it_possible_to_change_dates (old_event , event_to_update ):
100
161
return None
101
162
102
163
# Update database
@@ -107,7 +168,8 @@ def update_event(event_id: int, event: Dict, db: Session
107
168
# TODO: Send emails to recipients.
108
169
except (AttributeError , SQLAlchemyError , TypeError ):
109
170
return None
110
- return by_id (db = db , event_id = event_id )
171
+
172
+ return get_event_by_id (db = db , event_id = event_id )
111
173
112
174
113
175
def create_event (db , title , start , end , owner_id , content = None , location = None ):
@@ -141,38 +203,10 @@ def get_participants_emails_by_event(db: Session, event_id: int) -> List[str]:
141
203
"""Returns a list of all the email address of the event invited users,
142
204
by event id."""
143
205
144
- return [email [0 ] for email in db .query (User .email ).
206
+ return (
207
+ [email [0 ] for email in db .query (User .email ).
145
208
select_from (Event ).
146
209
join (UserEvent , UserEvent .event_id == Event .id ).
147
210
join (User , User .id == UserEvent .user_id ).
148
211
filter (Event .id == event_id ).
149
- all ()]
150
-
151
-
152
- @router .delete ("/{event_id}" )
153
- def delete_event (request : Request ,
154
- event_id : int ,
155
- db : Session = Depends (get_db )):
156
-
157
- # TODO: Check if the user is the owner of the event.
158
- event = by_id (db , event_id )
159
- participants = get_participants_emails_by_event (db , event_id )
160
- try :
161
- # Delete event
162
- db .delete (event )
163
-
164
- # Delete user_event
165
- db .query (UserEvent ).filter (UserEvent .event_id == event_id ).delete ()
166
-
167
- db .commit ()
168
-
169
- except (SQLAlchemyError , TypeError ):
170
- return templates .TemplateResponse (
171
- "event/eventview.html" , {"request" : request , "event_id" : event_id },
172
- status_code = status .HTTP_500_INTERNAL_SERVER_ERROR )
173
- if participants and event .start > dt .now ():
174
- pass
175
- # TODO: Send them a cancellation notice
176
- # if the deletion is successful
177
- return RedirectResponse (
178
- url = "/calendar" , status_code = status .HTTP_200_OK )
212
+ all ()])
0 commit comments