mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-22 21:29:05 +00:00
* default platform fix * default platform fix * default platform fix * Update server/reflector/db/rooms.py Co-authored-by: pr-agent-monadical[bot] <198624643+pr-agent-monadical[bot]@users.noreply.github.com> * default platform fix --------- Co-authored-by: Igor Loskutov <igor.loskutoff@gmail.com> Co-authored-by: pr-agent-monadical[bot] <198624643+pr-agent-monadical[bot]@users.noreply.github.com>
176 lines
5.7 KiB
Python
176 lines
5.7 KiB
Python
from datetime import datetime, timedelta, timezone
|
|
|
|
import structlog
|
|
from celery import shared_task
|
|
from celery.utils.log import get_task_logger
|
|
|
|
from reflector.asynctask import asynctask
|
|
from reflector.db.calendar_events import calendar_events_controller
|
|
from reflector.db.meetings import meetings_controller
|
|
from reflector.db.rooms import Room, rooms_controller
|
|
from reflector.redis_cache import RedisAsyncLock
|
|
from reflector.services.ics_sync import SyncStatus, ics_sync_service
|
|
from reflector.video_platforms.factory import create_platform_client
|
|
|
|
logger = structlog.wrap_logger(get_task_logger(__name__))
|
|
|
|
|
|
@shared_task
|
|
@asynctask
|
|
async def sync_room_ics(room_id: str):
|
|
try:
|
|
room = await rooms_controller.get_by_id(room_id)
|
|
if not room:
|
|
logger.warning("Room not found for ICS sync", room_id=room_id)
|
|
return
|
|
|
|
if not room.ics_enabled or not room.ics_url:
|
|
logger.debug("ICS not enabled for room", room_id=room_id)
|
|
return
|
|
|
|
logger.info("Starting ICS sync for room", room_id=room_id, room_name=room.name)
|
|
result = await ics_sync_service.sync_room_calendar(room)
|
|
|
|
if result["status"] == SyncStatus.SUCCESS:
|
|
logger.info(
|
|
"ICS sync completed successfully",
|
|
room_id=room_id,
|
|
events_found=result.get("events_found", 0),
|
|
events_created=result.get("events_created", 0),
|
|
events_updated=result.get("events_updated", 0),
|
|
events_deleted=result.get("events_deleted", 0),
|
|
)
|
|
elif result["status"] == SyncStatus.UNCHANGED:
|
|
logger.debug("ICS content unchanged", room_id=room_id)
|
|
elif result["status"] == SyncStatus.ERROR:
|
|
logger.error("ICS sync failed", room_id=room_id, error=result.get("error"))
|
|
else:
|
|
logger.debug(
|
|
"ICS sync skipped", room_id=room_id, reason=result.get("reason")
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error("Unexpected error during ICS sync", room_id=room_id, error=str(e))
|
|
|
|
|
|
@shared_task
|
|
@asynctask
|
|
async def sync_all_ics_calendars():
|
|
try:
|
|
logger.info("Starting sync for all ICS-enabled rooms")
|
|
|
|
ics_enabled_rooms = await rooms_controller.get_ics_enabled()
|
|
logger.info(f"Found {len(ics_enabled_rooms)} rooms with ICS enabled")
|
|
|
|
for room in ics_enabled_rooms:
|
|
if not _should_sync(room):
|
|
logger.debug("Skipping room, not time to sync yet", room_id=room.id)
|
|
continue
|
|
|
|
sync_room_ics.delay(room.id)
|
|
|
|
logger.info("Queued sync tasks for all eligible rooms")
|
|
|
|
except Exception as e:
|
|
logger.error("Error in sync_all_ics_calendars", error=str(e))
|
|
|
|
|
|
def _should_sync(room) -> bool:
|
|
if not room.ics_last_sync:
|
|
return True
|
|
|
|
time_since_sync = datetime.now(timezone.utc) - room.ics_last_sync
|
|
return time_since_sync.total_seconds() >= room.ics_fetch_interval
|
|
|
|
|
|
MEETING_DEFAULT_DURATION = timedelta(hours=1)
|
|
|
|
|
|
async def create_upcoming_meetings_for_event(event, create_window, room: Room):
|
|
if event.start_time <= create_window:
|
|
return
|
|
existing_meeting = await meetings_controller.get_by_calendar_event(event.id, room)
|
|
|
|
if existing_meeting:
|
|
return
|
|
|
|
logger.info(
|
|
"Pre-creating meeting for calendar event",
|
|
room_id=room.id,
|
|
event_id=event.id,
|
|
event_title=event.title,
|
|
)
|
|
|
|
try:
|
|
end_date = event.end_time or (event.start_time + MEETING_DEFAULT_DURATION)
|
|
|
|
client = create_platform_client(room.platform)
|
|
|
|
meeting_data = await client.create_meeting(
|
|
room.name,
|
|
end_date=end_date,
|
|
room=room,
|
|
)
|
|
await client.upload_logo(meeting_data.room_name, "./images/logo.png")
|
|
|
|
meeting = await meetings_controller.create(
|
|
id=meeting_data.meeting_id,
|
|
room_name=meeting_data.room_name,
|
|
room_url=meeting_data.room_url,
|
|
host_room_url=meeting_data.host_room_url,
|
|
start_date=event.start_time,
|
|
end_date=end_date,
|
|
room=room,
|
|
calendar_event_id=event.id,
|
|
calendar_metadata={
|
|
"title": event.title,
|
|
"description": event.description,
|
|
"attendees": event.attendees,
|
|
},
|
|
)
|
|
|
|
logger.info(
|
|
"Meeting pre-created successfully",
|
|
meeting_id=meeting.id,
|
|
event_id=event.id,
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(
|
|
"Failed to pre-create meeting",
|
|
room_id=room.id,
|
|
event_id=event.id,
|
|
error=str(e),
|
|
)
|
|
|
|
|
|
@shared_task
|
|
@asynctask
|
|
async def create_upcoming_meetings():
|
|
async with RedisAsyncLock("create_upcoming_meetings", skip_if_locked=True) as lock:
|
|
if not lock.acquired:
|
|
logger.warning(
|
|
"Another worker is already creating upcoming meetings, skipping"
|
|
)
|
|
return
|
|
|
|
try:
|
|
logger.info("Starting creation of upcoming meetings")
|
|
|
|
ics_enabled_rooms = await rooms_controller.get_ics_enabled()
|
|
now = datetime.now(timezone.utc)
|
|
create_window = now - timedelta(minutes=6)
|
|
|
|
for room in ics_enabled_rooms:
|
|
events = await calendar_events_controller.get_upcoming(
|
|
room.id,
|
|
minutes_ahead=7,
|
|
)
|
|
|
|
for event in events:
|
|
await create_upcoming_meetings_for_event(event, create_window, room)
|
|
logger.info("Completed pre-creation check for upcoming meetings")
|
|
|
|
except Exception as e:
|
|
logger.error("Error in create_upcoming_meetings", error=str(e))
|