Compare commits

...

11 Commits
1.2.9 ... 1.3.4

View File

@@ -4,401 +4,219 @@ from datetime import datetime
from ..dependencies import users_token, permissions_checker, database from ..dependencies import users_token, permissions_checker, database
from ..models import events, users from ..models import events, users
from pydantic import EmailStr from pydantic import EmailStr
from typing import Annotated from typing import Annotated, Union
from bson import ObjectId from bson import ObjectId
from datetime import datetime from datetime import datetime
router = APIRouter() router = APIRouter()
def build_location_filter(min_lat, max_lat, min_lon, max_lon):
"""Build location-based query filters."""
if min_lat is not None and max_lat is not None and min_lon is not None and max_lon is not None:
return [
{"latitude": {"$gte": min_lat}},
{"latitude": {"$lte": max_lat}},
{"longitude": {"$gte": min_lon}},
{"longitude": {"$lte": max_lon}},
]
return []
def build_datetime_filter(current_datetime):
"""Build filters for current datetime."""
if current_datetime:
return {
"$or": [
{"start_date": {"$gte": current_datetime}}, # Upcoming events
{
"$and": [
{"start_date": {"$lte": current_datetime}}, # Already started
{"$or": [
{"end_date": {"$gte": current_datetime}}, # Ongoing
{"end_date": None}, # No end date
]},
],
},
],
}
return None
def build_date_filter(start_date, end_date):
"""Build date range filters."""
if start_date and end_date:
return [
{"start_date": {"$gte": datetime.combine(start_date, datetime.min.time())}},
{"start_date": {"$lte": datetime.combine(end_date, datetime.max.time())}},
]
return []
def build_text_filter(item):
"""Build text-based search filters."""
if item:
return {
"$or": [
{"name": {"$regex": item, "$options": "i"}},
{"tags": {"$regex": item, "$options": "i"}},
{"organizers": {"$regex": item, "$options": "i"}},
]
}
return None
@router.get("/events", tags=["events"], response_model=list[events.EventOut]) @router.get("/events", tags=["events"], response_model=list[events.EventOut])
async def read_events(authorize: Annotated[bool, Depends(permissions_checker.PermissionChecker(roles=["Admin", "User"]))], skip: int = 0, limit: int = 20, id_event: str | None = None, name: str | None = None, status: int = 1, tags: str | None = None, organizers: str | None = None, current_datetime: datetime | None = None, date_event: datetime |None = None): async def read_events(
authorize: Annotated[bool, Depends(permissions_checker.PermissionChecker(roles=["Admin", "User"]))],
skip: int = 0,
limit: int = 20,
id_event: str | None = None,
name: str | None = None,
status: int = 1,
tags: str | None = None,
organizers: str | None = None,
current_datetime: datetime | None = None,
date_event: datetime | None = None,
start_date: datetime | None = None,
end_date: datetime | None = None,
):
# Validate `skip` and `limit`
if limit < 1 or skip < 0 or limit < skip: if limit < 1 or skip < 0 or limit < skip:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="skip should be greater than 0 and limit should be greater than 1. Limit should be greater than skip" detail="`skip` should be >= 0 and `limit` should be > 0 and greater than `skip`.",
) )
limit = limit + skip limit = limit + skip
listEvents = []
event_repository = events.EventRepository(database=database.database)
object_search = {}
if date_event is not None:
start_of_day = datetime.combine(date_event, datetime.min.time()) # 2024-11-23 00:00:00
end_of_day = datetime.combine(date_event, datetime.max.time())
if current_datetime is not None:
object_search ={
"$or": [{"start_date": {"$gte": current_datetime}}, # Upcoming events
{"$and": [ # Ongoing events
{"start_date": {"$lte": current_datetime}}, # Already started
{"$or": [
{"end_date": {"$gte": current_datetime}}, # End date in the future
{"end_date": None} # No end date set
]}
]}
]
}
if date_event is not None:
object_search ={
"$and": [{"start_date": {"$gte": start_of_day}},
{"start_date": {"$lte": end_of_day}} # Upcoming events
]
}
if status is not 1:
object_search = {"status":{"$eq": status}}
if current_datetime is not None:
object_search = { "$and": [ {"status":{"$eq": status}},
{
"$or": [
{"start_date": {"$gte": current_datetime}}, # Upcoming events
{"$and": [ # Ongoing events
{"start_date": {"$lte": current_datetime}}, # Already started
{"$or": [
{"end_date": {"$gte": current_datetime}}, # End date in the future
{"end_date": None} # No end date set
]}
]}
]
}
]}
if date_event is not None:
object_search = { "$and": [ {"status":{"$eq": status}},
{"start_date": {"$gte": start_of_day}},
{"start_date": {"$lte": end_of_day}}
]}
if tags is not None:
object_search = {"$and":[{"tags":{"$eq": tags}}, {"status":{"$eq":status}}]}
if current_datetime is not None:
object_search = {"$and":[{"tags":{"$eq": tags}},
{"status":{"$eq":status}},
{
"$or": [
{"start_date": {"$gte": current_datetime}}, # Upcoming events
{"$and": [ # Ongoing events
{"start_date": {"$lte": current_datetime}}, # Already started
{"$or": [
{"end_date": {"$gte": current_datetime}}, # End date in the future
{"end_date": None} # No end date set
]}
]}
]
}
]
}
if date_event is not None:
object_search = {"$and":[{"tags":{"$eq": tags}},
{"status":{"$eq":status}},
{"start_date": {"$gte": start_of_day}},
{"start_date": {"$lte": end_of_day}}
]
}
if organizers is not None:
object_search = {"$and":[{"organizers":{"$eq": organizers}}, {"status":{"$eq":status}}]}
if current_datetime is not None:
object_search = {"$and":[{"organizers":{"$eq": organizers}},
{"status":{"$eq":status}},
{
"$or": [
{"start_date": {"$gte": current_datetime}}, # Upcoming events
{"$and": [ # Ongoing events
{"start_date": {"$lte": current_datetime}}, # Already started
{"$or": [
{"end_date": {"$gte": current_datetime}}, # End date in the future
{"end_date": None} # No end date set
]}
]}
]
}
]}
if date_event is not None:
object_search = {"$and":[{"organizers":{"$eq": organizers}},
{"status":{"$eq":status}},
{"start_date": {"$gte": start_of_day}},
{"start_date": {"$lte": end_of_day}}
]}
if id_event is not None:
eventid = ObjectId(id_event)
object_search = {"$and":[{"id":{"$regex": eventid}}, {"status":{"$eq":status}}]}
if current_datetime is not None:
object_search = {"$and":[{"id":{"$regex": eventid}},
{"status":{"$eq":status}},
{
"$or": [
{"start_date": {"$gte": current_datetime}}, # Upcoming events
{"$and": [ # Ongoing events
{"start_date": {"$lte": current_datetime}}, # Already started
{"$or": [
{"end_date": {"$gte": current_datetime}}, # End date in the future
{"end_date": None} # No end date set
]}
]}
]
}
]}
if date_event is not None:
object_search = {"$and":[{"id":{"$regex": eventid}},
{"status":{"$eq":status}},
{"start_date": {"$gte": start_of_day}},
{"start_date": {"$lte": end_of_day}}
]}
if name is not None:
object_search = {"$and":[{"name":{"$regex": name}}, {"status":{"$eq":status}}]}
if current_datetime is not None:
object_search = {"$and":[{"name":{"$regex": name}},
{"status":{"$eq":status}},
{
"$or": [
{"start_date": {"$gte": current_datetime}}, # Upcoming events
{"$and": [ # Ongoing events
{"start_date": {"$lte": current_datetime}}, # Already started
{"$or": [
{"end_date": {"$gte": current_datetime}}, # End date in the future
{"end_date": None} # No end date set
]}
]}
]
}
]}
if date_event is not None:
object_search = {"$and":[{"name":{"$regex": name}},
{"status":{"$eq":status}},
{"start_date": {"$gte": start_of_day}},
{"start_date": {"$lte": end_of_day}}
]}
# Initialize filters
filters = []
# Add status filter
filters.append({"status": {"$eq": status}})
# Add date filters
if date_event:
start_of_day = datetime.combine(date_event, datetime.min.time())
end_of_day = datetime.combine(date_event, datetime.max.time())
filters.extend(build_date_filter(start_of_day, end_of_day))
elif start_date and end_date:
filters.extend(build_date_filter(start_date, end_date))
# Add current datetime filter
datetime_filter = build_datetime_filter(current_datetime)
if datetime_filter:
filters.append(datetime_filter)
# Add text-based filters
if name:
filters.append(build_text_filter(name))
if tags:
filters.append({"tags": {"$eq": tags}})
if organizers:
filters.append({"organizers": {"$eq": organizers}})
# Add ID filter
if id_event:
try:
event_id = ObjectId(id_event)
filters.append({"_id": {"$eq": event_id}})
except Exception:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid event ID format.")
# Combine all filters
object_search = {"$and": filters} if filters else {}
# Fetch and return results
event_repository = events.EventRepository(database=database.database)
list_events = []
for event_index in event_repository.find_by(object_search, limit=limit, skip=skip): for event_index in event_repository.find_by(object_search, limit=limit, skip=skip):
event = events.EventOut(id=event_index.id, tags=event_index.tags, imgUrl=event_index.imgUrl, name=event_index.name, description=event_index.description, place=event_index.place, status=event_index.status, start_date=event_index.start_date, end_date=event_index.end_date) event = events.EventOut(
listEvents.append(event) id=event_index.id,
return listEvents tags=event_index.tags,
imgUrl=event_index.imgUrl,
name=event_index.name,
description=event_index.description,
place=event_index.place,
status=event_index.status,
start_date=event_index.start_date,
end_date=event_index.end_date,
)
list_events.append(event)
return list_events
@router.get("/events/search", tags=["events"], response_model=list[events.EventOut]) @router.get("/events/search", tags=["events"], response_model=list[events.EventOut])
async def search_events(authorize: Annotated[bool, Depends(permissions_checker.PermissionChecker(roles=["Admin", "User"]))], skip: int = 0, limit: int = 20, item: str | None = None, status: int = 1, min_lat: float | None = None, max_lat: float | None = None, min_lon: float | None = None, max_lon: float | None = None, current_datetime: datetime | None = None, date_event: datetime | None = None): async def search_events(
authorize: Annotated[bool, Depends(permissions_checker.PermissionChecker(roles=["Admin", "User"]))],
skip: int = 0,
limit: int = 20,
item: Union[str, None] = None,
status: int = 1,
min_lat: Union[float, None] = None,
max_lat: Union[float, None] = None,
min_lon: Union[float, None] = None,
max_lon: Union[float, None] = None,
current_datetime: Union[datetime, None] = None,
date_event: Union[datetime, None] = None,
start_date: Union[datetime, None] = None,
end_date: Union[datetime, None] = None,
tags: Union[List[str], None] = None,
):
if limit < 1 or skip < 0 or limit < skip: if limit < 1 or skip < 0 or limit < skip:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="skip should be greater than 0 and limit should be greater than 1. Limit should be greater than skip" detail="`skip` should be >= 0 and `limit` should be > 0 and greater than `skip`.",
) )
limit = limit + skip limit = limit + skip
listEvents = []
event_repository = events.EventRepository(database=database.database) # Initialize filters
object_search = {} filters = [{"status": {"$eq": status}}]
if date_event is not None:
start_of_day = datetime.combine(date_event, datetime.min.time()) # 2024-11-23 00:00:00 # Date filters
if date_event:
start_of_day = datetime.combine(date_event, datetime.min.time())
end_of_day = datetime.combine(date_event, datetime.max.time()) end_of_day = datetime.combine(date_event, datetime.max.time())
if min_lat is not None and max_lat is not None and min_lon is not None and max_lon is not None: filters.extend(build_date_filter(start_of_day, end_of_day))
object_search = { else:
"$and": [ filters.extend(build_date_filter(start_date, end_date))
{"status": {"$eq": status}},
{ # Add location filter
"latitude": {"$gte": min_lat}, # Minimum latitude filters.extend(build_location_filter(min_lat, max_lat, min_lon, max_lon))
},
{ # Add datetime filter
"latitude": {"$lte": max_lat}, # Maximum latitude datetime_filter = build_datetime_filter(current_datetime)
}, if datetime_filter:
{ filters.append(datetime_filter)
"longitude": {"$gte": min_lon}, # Minimum longitude
}, # Add text filter
{ text_filter = build_text_filter(item)
"longitude": {"$lte": max_lon}, # Maximum longitude if text_filter:
} filters.append(text_filter)
]
} if tags is not None:
if current_datetime is not None: filters.append({"tags": {"$in": tags}})
object_search = {
"$and": [ # Combine filters
{"status": {"$eq": status}}, object_search = {"$and": filters} if filters else {}
{
"latitude": {"$gte": min_lat}, # Minimum latitude # Fetch and return results
}, event_repository = events.EventRepository(database=database.database)
{ list_events = []
"latitude": {"$lte": max_lat}, # Maximum latitude
},
{
"longitude": {"$gte": min_lon}, # Minimum longitude
},
{
"longitude": {"$lte": max_lon}, # Maximum longitude
},
{
"$or": [
{"start_date": {"$gte": current_datetime}}, # Upcoming events
{"$and": [ # Ongoing events
{"start_date": {"$lte": current_datetime}}, # Already started
{"$or": [
{"end_date": {"$gte": current_datetime}}, # End date in the future
{"end_date": None} # No end date set
]}
]}
]
}
]
}
if date_event is not None:
object_search = {
"$and": [
{"status": {"$eq": status}},
{
"latitude": {"$gte": min_lat}, # Minimum latitude
},
{
"latitude": {"$lte": max_lat}, # Maximum latitude
},
{
"longitude": {"$gte": min_lon}, # Minimum longitude
},
{
"longitude": {"$lte": max_lon}, # Maximum longitude
},
{"start_date": {"$gte": start_of_day}},
{"start_date": {"$lte": end_of_day}}
]
}
if item is not None:
object_search = {
"$and": [
{
"$or": [
{"name": {"$regex": item}},
{"tags": {"$regex": item}},
{"organizers": {"$regex": item}}
]
},
{"status": {"$eq": status}}
]
}
if current_datetime is not None:
object_search = {
"$and": [
{
"$or": [
{"name": {"$regex": item}},
{"tags": {"$regex": item}},
{"organizers": {"$regex": item}}
]
},
{"status": {"$eq": status}},
{
"$or": [
{"start_date": {"$gte": current_datetime}}, # Upcoming events
{"$and": [ # Ongoing events
{"start_date": {"$lte": current_datetime}}, # Already started
{"$or": [
{"end_date": {"$gte": current_datetime}}, # End date in the future
{"end_date": None} # No end date set
]}
]}
]
}
]
}
if date_event is not None:
object_search = {
"$and": [
{
"$or": [
{"name": {"$regex": item}},
{"tags": {"$regex": item}},
{"organizers": {"$regex": item}}
]
},
{"status": {"$eq": status}},
{"start_date": {"$gte": start_of_day}},
{"start_date": {"$lte": end_of_day}}
]
}
if min_lat is not None and max_lat is not None and min_lon is not None and max_lon is not None:
object_search = {
"$and": [
{
"$or": [
{"name": {"$regex": item}},
{"tags": {"$regex": item}},
{"organizers": {"$regex": item}}
]
},
{"status": {"$eq": status}},
{
"latitude": {"$gte": min_lat}, # Minimum latitude
},
{
"latitude": {"$lte": max_lat}, # Maximum latitude
},
{
"longitude": {"$gte": min_lon}, # Minimum longitude
},
{
"longitude": {"$lte": max_lon}, # Maximum longitude
}
]
}
if current_datetime is not None:
object_search = {
"$and": [
{
"$or": [
{"name": {"$regex": item}},
{"tags": {"$regex": item}},
{"organizers": {"$regex": item}}
]
},
{"status": {"$eq": status}},
{
"latitude": {"$gte": min_lat}, # Minimum latitude
},
{
"latitude": {"$lte": max_lat}, # Maximum latitude
},
{
"longitude": {"$gte": min_lon}, # Minimum longitude
},
{
"longitude": {"$lte": max_lon}, # Maximum longitude
},
{
"$or": [
{"start_date": {"$gte": current_datetime}}, # Upcoming events
{"$and": [ # Ongoing events
{"start_date": {"$lte": current_datetime}}, # Already started
{"$or": [
{"end_date": {"$gte": current_datetime}}, # End date in the future
{"end_date": None} # No end date set
]}
]}
]
}
]
}
if date_event is not None:
object_search = {
"$and": [
{
"$or": [
{"name": {"$regex": item}},
{"tags": {"$regex": item}},
{"organizers": {"$regex": item}}
]
},
{"status": {"$eq": status}},
{
"latitude": {"$gte": min_lat}, # Minimum latitude
},
{
"latitude": {"$lte": max_lat}, # Maximum latitude
},
{
"longitude": {"$gte": min_lon}, # Minimum longitude
},
{
"longitude": {"$lte": max_lon}, # Maximum longitude
},
{"start_date": {"$gte": start_of_day}},
{"start_date": {"$lte": end_of_day}}
]
}
for event_index in event_repository.find_by(object_search, limit=limit, skip=skip): for event_index in event_repository.find_by(object_search, limit=limit, skip=skip):
event = events.EventOut(id=event_index.id, tags=event_index.tags, imgUrl=event_index.imgUrl, name=event_index.name, description=event_index.description, place=event_index.place, status=event_index.status, start_date=event_index.start_date, end_date=event_index.end_date) event = events.EventOut(
listEvents.append(event) id=event_index.id,
return listEvents tags=event_index.tags,
imgUrl=event_index.imgUrl,
name=event_index.name,
description=event_index.description,
place=event_index.place,
status=event_index.status,
start_date=event_index.start_date,
end_date=event_index.end_date,
)
list_events.append(event)
return list_events
@router.get("/events/me",tags=["events"]) @router.get("/events/me",tags=["events"])