1- from datetime import datetime as dt
1+ from datetime import datetime
22from operator import attrgetter
33from typing import Any , Dict , List , Optional
44
5- from fastapi import APIRouter , Depends , Request
5+ from fastapi import APIRouter , Depends , HTTPException , Request
66from sqlalchemy .exc import SQLAlchemyError
77from sqlalchemy .orm import Session
8+ from sqlalchemy .orm .exc import MultipleResultsFound , NoResultFound
89from starlette import status
910from starlette .responses import RedirectResponse
1011from starlette .status import HTTP_302_FOUND
1112
1213from app .database .database import get_db
1314from app .database .models import Event , User , UserEvent
14- from app .dependencies import templates
15+ from app .dependencies import logger , templates
1516from app .internal .event import validate_zoom_link
1617from app .internal .utils import create_model
1718from app .routers .user import create_user
@@ -34,10 +35,10 @@ async def create_new_event(request: Request, session=Depends(get_db)):
3435 data = await request .form ()
3536 title = data ['title' ]
3637 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' )
4142 user = session .query (User ).filter_by (id = 1 ).first ()
4243 user = user if user else create_user ("u" , "p" , "e@mail.com" , session )
4344 owner_id = user .id
@@ -50,30 +51,86 @@ async def create_new_event(request: Request, session=Depends(get_db)):
5051
5152 event = create_event (session , title , start , end , owner_id , content ,
5253 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 ),
5456 status_code = HTTP_302_FOUND )
5557
5658
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 )
5971 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 )
6198
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 )
62105
63- def by_id (db : Session , event_id : int ) -> Event :
64- """Select event by id"""
65106
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
67124
68125
69- def is_date_before (start_date : dt , end_date : dt ) -> bool :
126+ def is_date_before (start_date : datetime , end_date : datetime ) -> bool :
70127 """Check if the start date is earlier than the end date"""
71128
72129 return start_date < end_date
73130
74131
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 :
77134 return is_date_before (
78135 event .get ('start' , old_event .start ),
79136 event .get ('end' , old_event .end ))
@@ -94,9 +151,13 @@ def update_event(event_id: int, event: Dict, db: Session
94151 if not event_to_update :
95152 return None
96153 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 ):
100161 return None
101162
102163 # Update database
@@ -107,7 +168,8 @@ def update_event(event_id: int, event: Dict, db: Session
107168 # TODO: Send emails to recipients.
108169 except (AttributeError , SQLAlchemyError , TypeError ):
109170 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 )
111173
112174
113175def 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]:
141203 """Returns a list of all the email address of the event invited users,
142204 by event id."""
143205
144- return [email [0 ] for email in db .query (User .email ).
206+ return (
207+ [email [0 ] for email in db .query (User .email ).
145208 select_from (Event ).
146209 join (UserEvent , UserEvent .event_id == Event .id ).
147210 join (User , User .id == UserEvent .user_id ).
148211 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