1- from datetime import datetime
1+ from datetime import datetime as dt
22from operator import attrgetter
33from typing import Any , Dict , List , Optional
44
55from fastapi import APIRouter , Depends , HTTPException , Request
6- from loguru import logger
76from sqlalchemy .exc import SQLAlchemyError
87from sqlalchemy .orm import Session
98from sqlalchemy .orm .exc import MultipleResultsFound , NoResultFound
1211
1312from app .database .database import get_db
1413from app .database .models import Event , User , UserEvent
14+ from app .dependencies import logger
1515from app .dependencies import templates
16- from app .internal .event import validate_zoom_link
16+ from app .internal .event import (raise_if_zoom_link_invalid , get_invited_emails ,
17+ get_uninvited_regular_emails )
1718from app .internal .utils import create_model
1819from app .routers .user import create_user
1920
21+ TIME_FORMAT = '%Y-%m-%d %H:%M'
22+
23+ UPDATE_EVENTS_FIELDS = {
24+ 'title' : str ,
25+ 'start' : dt ,
26+ 'end' : dt ,
27+ 'content' : (str , type (None )),
28+ 'location' : (str , type (None )),
29+ 'category_id' : (int , type (None ))
30+ }
31+
32+
2033router = APIRouter (
2134 prefix = "/event" ,
2235 tags = ["event" ],
@@ -35,10 +48,10 @@ async def create_new_event(request: Request, session=Depends(get_db)):
3548 data = await request .form ()
3649 title = data ['title' ]
3750 content = data ['description' ]
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' )
51+ start = dt .strptime (data ['start_date' ] + ' ' + data ['start_time' ],
52+ TIME_FORMAT )
53+ end = dt .strptime (data ['end_date' ] + ' ' + data ['end_time' ],
54+ TIME_FORMAT )
4255 user = session .query (User ).filter_by (id = 1 ).first ()
4356 user = user if user else create_user (username = "u" ,
4457 password = "p" ,
@@ -52,14 +65,20 @@ async def create_new_event(request: Request, session=Depends(get_db)):
5265 location = data ['location' ]
5366 category_id = data .get ('category_id' )
5467
68+ invited_emails = get_invited_emails (data ['invited' ])
69+ uninvited_contacts = get_uninvited_regular_emails (session , owner_id ,
70+ title , invited_emails )
71+
5572 if is_zoom :
56- validate_zoom_link (location )
73+ raise_if_zoom_link_invalid (location )
5774
5875 event = create_event (session , title , start , end , owner_id , content ,
59- location , category_id = category_id )
60- return RedirectResponse (router .url_path_for ('eventview' ,
61- event_id = event .id ),
62- status_code = status .HTTP_302_FOUND )
76+ location , invited_emails , category_id = category_id )
77+ message = ''
78+ if uninvited_contacts :
79+ message = f'Forgot to invite { ", " .join (uninvited_contacts )} maybe?'
80+ return RedirectResponse (router .url_path_for ('eventview' , event_id = event .id )
81+ + f'?{ message } ' , status_code = status .HTTP_302_FOUND )
6382
6483
6584@router .get ("/{event_id}" )
@@ -69,20 +88,12 @@ async def eventview(request: Request, event_id: int,
6988 start_format = '%A, %d/%m/%Y %H:%M'
7089 end_format = ('%H:%M' if event .start .date () == event .end .date ()
7190 else start_format )
91+ message = request .query_params .get ('message' , '' )
7292 return templates .TemplateResponse ("event/eventview.html" ,
7393 {"request" : request , "event" : event ,
7494 "start_format" : start_format ,
75- "end_format" : end_format })
76-
77-
78- UPDATE_EVENTS_FIELDS = {
79- 'title' : str ,
80- 'start' : datetime ,
81- 'end' : datetime ,
82- 'content' : (str , type (None )),
83- 'location' : (str , type (None )),
84- 'category_id' : (int , type (None ))
85- }
95+ "end_format" : end_format ,
96+ "message" : message })
8697
8798
8899def by_id (db : Session , event_id : int ) -> Event :
@@ -115,10 +126,8 @@ def by_id(db: Session, event_id: int) -> Event:
115126 return event
116127
117128
118- def is_end_date_before_start_date (
119- start_date : datetime , end_date : datetime ) -> bool :
129+ def is_end_date_before_start_date (start_date : dt , end_date : dt ) -> bool :
120130 """Check if the start date is earlier than the end date"""
121-
122131 return start_date > end_date
123132
124133
@@ -190,9 +199,12 @@ def update_event(event_id: int, event: Dict, db: Session
190199def create_event (db : Session , title : str , start , end , owner_id : int ,
191200 content : str = None ,
192201 location : str = None ,
202+ invitees : List [str ] = None ,
193203 category_id : int = None ):
194204 """Creates an event and an association."""
195205
206+ invitees_concatenated = ',' .join (invitees or [])
207+
196208 event = create_model (
197209 db , Event ,
198210 title = title ,
@@ -201,6 +213,7 @@ def create_event(db: Session, title: str, start, end, owner_id: int,
201213 content = content ,
202214 owner_id = owner_id ,
203215 location = location ,
216+ invitees = invitees_concatenated ,
204217 category_id = category_id ,
205218 )
206219 create_model (
@@ -221,13 +234,11 @@ def sort_by_date(events: List[Event]) -> List[Event]:
221234def get_participants_emails_by_event (db : Session , event_id : int ) -> List [str ]:
222235 """Returns a list of all the email address of the event invited users,
223236 by event id."""
224-
225- return [email [0 ] for email in db .query (User .email ).
226- select_from (Event ).
227- join (UserEvent , UserEvent .event_id == Event .id ).
228- join (User , User .id == UserEvent .user_id ).
229- filter (Event .id == event_id ).
230- all ()]
237+ return [email [0 ] for email in
238+ db .query (User .email ).select_from (Event ).join (
239+ UserEvent , UserEvent .event_id == Event .id ).join (
240+ User , User .id == UserEvent .user_id ).filter (
241+ Event .id == event_id ).all ()]
231242
232243
233244def _delete_event (db : Session , event : Event ):
@@ -254,7 +265,7 @@ def delete_event(event_id: int,
254265 event = by_id (db , event_id )
255266 participants = get_participants_emails_by_event (db , event_id )
256267 _delete_event (db , event )
257- if participants and event .start > datetime .now ():
268+ if participants and event .start > dt .now ():
258269 pass
259270 # TODO: Send them a cancellation notice
260271 # if the deletion is successful
0 commit comments