mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 12:19:06 +00:00
Room config
This commit is contained in:
86
server/migrations/versions/62dea3db63a5_add_room_options.py
Normal file
86
server/migrations/versions/62dea3db63a5_add_room_options.py
Normal file
@@ -0,0 +1,86 @@
|
||||
"""Add room options
|
||||
|
||||
Revision ID: 62dea3db63a5
|
||||
Revises: 1340c04426b8
|
||||
Create Date: 2024-09-03 16:19:26.861027
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "62dea3db63a5"
|
||||
down_revision: Union[str, None] = "1340c04426b8"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column(
|
||||
"meeting",
|
||||
sa.Column(
|
||||
"is_locked", sa.Boolean(), server_default=sa.text("0"), nullable=False
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"meeting",
|
||||
sa.Column("room_mode", sa.String(), server_default="normal", nullable=False),
|
||||
)
|
||||
op.add_column(
|
||||
"meeting",
|
||||
sa.Column(
|
||||
"recording_type", sa.String(), server_default="cloud", nullable=False
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"meeting",
|
||||
sa.Column(
|
||||
"recording_trigger",
|
||||
sa.String(),
|
||||
server_default="automatic-2nd-participant",
|
||||
nullable=False,
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"room",
|
||||
sa.Column(
|
||||
"is_locked", sa.Boolean(), server_default=sa.text("0"), nullable=False
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"room",
|
||||
sa.Column("room_mode", sa.String(), server_default="normal", nullable=False),
|
||||
)
|
||||
op.add_column(
|
||||
"room",
|
||||
sa.Column(
|
||||
"recording_type", sa.String(), server_default="cloud", nullable=False
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"room",
|
||||
sa.Column(
|
||||
"recording_trigger",
|
||||
sa.String(),
|
||||
server_default="automatic-2nd-participant",
|
||||
nullable=False,
|
||||
),
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column("room", "recording_trigger")
|
||||
op.drop_column("room", "recording_type")
|
||||
op.drop_column("room", "room_mode")
|
||||
op.drop_column("room", "is_locked")
|
||||
op.drop_column("meeting", "recording_trigger")
|
||||
op.drop_column("meeting", "recording_type")
|
||||
op.drop_column("meeting", "room_mode")
|
||||
op.drop_column("meeting", "is_locked")
|
||||
# ### end Alembic commands ###
|
||||
@@ -1,9 +1,12 @@
|
||||
from datetime import datetime, timezone
|
||||
from typing import Literal
|
||||
|
||||
import sqlalchemy
|
||||
from fastapi import HTTPException
|
||||
from pydantic import BaseModel
|
||||
from reflector.db import database, metadata
|
||||
from reflector.db.rooms import Room
|
||||
from sqlalchemy.sql import false
|
||||
|
||||
meetings = sqlalchemy.Table(
|
||||
"meeting",
|
||||
@@ -17,6 +20,21 @@ meetings = sqlalchemy.Table(
|
||||
sqlalchemy.Column("end_date", sqlalchemy.DateTime),
|
||||
sqlalchemy.Column("user_id", sqlalchemy.String),
|
||||
sqlalchemy.Column("room_id", sqlalchemy.String),
|
||||
sqlalchemy.Column(
|
||||
"is_locked", sqlalchemy.Boolean, nullable=False, server_default=false()
|
||||
),
|
||||
sqlalchemy.Column(
|
||||
"room_mode", sqlalchemy.String, nullable=False, server_default="normal"
|
||||
),
|
||||
sqlalchemy.Column(
|
||||
"recording_type", sqlalchemy.String, nullable=False, server_default="cloud"
|
||||
),
|
||||
sqlalchemy.Column(
|
||||
"recording_trigger",
|
||||
sqlalchemy.String,
|
||||
nullable=False,
|
||||
server_default="automatic-2nd-participant",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -30,6 +48,12 @@ class Meeting(BaseModel):
|
||||
end_date: datetime
|
||||
user_id: str | None = None
|
||||
room_id: str | None = None
|
||||
is_locked: bool = False
|
||||
room_mode: Literal["normal", "group"] = "normal"
|
||||
recording_type: Literal["none", "local", "cloud"] = "cloud"
|
||||
recording_trigger: Literal[
|
||||
"none", "prompt", "automatic", "automatic-2nd-participant"
|
||||
] = "automatic-2nd-participant"
|
||||
|
||||
|
||||
class MeetingController:
|
||||
@@ -43,7 +67,7 @@ class MeetingController:
|
||||
start_date: datetime,
|
||||
end_date: datetime,
|
||||
user_id: str,
|
||||
room_id: str = None,
|
||||
room: Room,
|
||||
):
|
||||
"""
|
||||
Create a new meeting
|
||||
@@ -57,7 +81,11 @@ class MeetingController:
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
user_id=user_id,
|
||||
room_id=room_id,
|
||||
room_id=room.id,
|
||||
is_locked=room.is_locked,
|
||||
room_mode=room.room_mode,
|
||||
recording_type=room.recording_type,
|
||||
recording_trigger=room.recording_trigger,
|
||||
)
|
||||
query = meetings.insert().values(**meeting.model_dump())
|
||||
await database.execute(query)
|
||||
@@ -77,15 +105,23 @@ class MeetingController:
|
||||
|
||||
return Meeting(**result)
|
||||
|
||||
async def get_latest(self, room_id: str) -> Meeting:
|
||||
async def get_latest(self, room: Room) -> Meeting:
|
||||
"""
|
||||
Get latest meeting for a room.
|
||||
"""
|
||||
end_date = getattr(meetings.c, "end_date")
|
||||
query = (
|
||||
meetings.select()
|
||||
.where(meetings.c.room_id == room_id)
|
||||
.where(meetings.c.end_date > datetime.now(timezone.utc))
|
||||
.where(
|
||||
sqlalchemy.and_(
|
||||
meetings.c.room_id == room.id,
|
||||
meetings.c.is_locked == room.is_locked,
|
||||
meetings.c.room_mode == room.room_mode,
|
||||
meetings.c.recording_type == room.recording_type,
|
||||
meetings.c.recording_trigger == room.recording_trigger,
|
||||
meetings.c.end_date > datetime.now(timezone.utc),
|
||||
)
|
||||
)
|
||||
.order_by(end_date.desc())
|
||||
)
|
||||
result = await database.fetch_one(query)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from datetime import datetime
|
||||
from typing import Literal
|
||||
|
||||
import sqlalchemy
|
||||
from fastapi import HTTPException
|
||||
@@ -19,6 +20,21 @@ rooms = sqlalchemy.Table(
|
||||
),
|
||||
sqlalchemy.Column("zulip_stream", sqlalchemy.String),
|
||||
sqlalchemy.Column("zulip_topic", sqlalchemy.String),
|
||||
sqlalchemy.Column(
|
||||
"is_locked", sqlalchemy.Boolean, nullable=False, server_default=false()
|
||||
),
|
||||
sqlalchemy.Column(
|
||||
"room_mode", sqlalchemy.String, nullable=False, server_default="normal"
|
||||
),
|
||||
sqlalchemy.Column(
|
||||
"recording_type", sqlalchemy.String, nullable=False, server_default="cloud"
|
||||
),
|
||||
sqlalchemy.Column(
|
||||
"recording_trigger",
|
||||
sqlalchemy.String,
|
||||
nullable=False,
|
||||
server_default="automatic-2nd-participant",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -30,6 +46,12 @@ class Room(BaseModel):
|
||||
zulip_auto_post: bool = False
|
||||
zulip_stream: str = ""
|
||||
zulip_topic: str = ""
|
||||
is_locked: bool = False
|
||||
room_mode: Literal["normal", "group"] = "normal"
|
||||
recording_type: Literal["none", "local", "cloud"] = "cloud"
|
||||
recording_trigger: Literal[
|
||||
"none", "prompt", "automatic", "automatic-2nd-participant"
|
||||
] = "automatic-2nd-participant"
|
||||
|
||||
|
||||
class RoomController:
|
||||
|
||||
@@ -24,6 +24,10 @@ class Room(BaseModel):
|
||||
zulip_auto_post: bool
|
||||
zulip_stream: str
|
||||
zulip_topic: str
|
||||
is_locked: bool
|
||||
room_mode: str
|
||||
recording_type: str
|
||||
recording_trigger: str
|
||||
|
||||
|
||||
class Meeting(BaseModel):
|
||||
@@ -41,6 +45,10 @@ class CreateRoom(BaseModel):
|
||||
zulip_auto_post: bool
|
||||
zulip_stream: str
|
||||
zulip_topic: str
|
||||
is_locked: bool
|
||||
room_mode: str
|
||||
recording_type: str
|
||||
recording_trigger: str
|
||||
|
||||
|
||||
class UpdateRoom(BaseModel):
|
||||
@@ -48,6 +56,10 @@ class UpdateRoom(BaseModel):
|
||||
zulip_auto_post: bool
|
||||
zulip_stream: str
|
||||
zulip_topic: str
|
||||
is_locked: bool
|
||||
room_mode: str
|
||||
recording_type: str
|
||||
recording_trigger: str
|
||||
|
||||
|
||||
class DeletionStatus(BaseModel):
|
||||
@@ -126,11 +138,13 @@ async def rooms_create_meeting(
|
||||
if not room:
|
||||
raise HTTPException(status_code=404, detail="Room not found")
|
||||
|
||||
meeting = await meetings_controller.get_latest(room_id=room.id)
|
||||
meeting = await meetings_controller.get_latest(room=room)
|
||||
if meeting is None:
|
||||
start_date = datetime.now(timezone.utc)
|
||||
end_date = start_date + timedelta(hours=1)
|
||||
meeting = await create_meeting("", start_date=start_date, end_date=end_date)
|
||||
meeting = await create_meeting(
|
||||
"", start_date=start_date, end_date=end_date, room=room
|
||||
)
|
||||
|
||||
meeting = await meetings_controller.create(
|
||||
id=meeting["meetingId"],
|
||||
@@ -141,7 +155,10 @@ async def rooms_create_meeting(
|
||||
start_date=datetime.fromisoformat(meeting["startDate"]),
|
||||
end_date=datetime.fromisoformat(meeting["endDate"]),
|
||||
user_id=user_id,
|
||||
room_id=room.id,
|
||||
room=room,
|
||||
)
|
||||
|
||||
if user_id is None:
|
||||
meeting.host_room_url = ""
|
||||
|
||||
return meeting
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from datetime import datetime
|
||||
|
||||
import httpx
|
||||
from reflector.db.rooms import Room
|
||||
from reflector.settings import settings
|
||||
|
||||
|
||||
async def create_meeting(
|
||||
room_name_prefix: str, start_date: datetime, end_date: datetime
|
||||
room_name_prefix: str, start_date: datetime, end_date: datetime, room: Room
|
||||
):
|
||||
headers = {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
@@ -13,14 +14,14 @@ async def create_meeting(
|
||||
}
|
||||
data = {
|
||||
"templateType": "viewerMode",
|
||||
"isLocked": False,
|
||||
"isLocked": room.is_locked,
|
||||
"roomNamePrefix": room_name_prefix,
|
||||
"roomNamePattern": "uuid",
|
||||
"roomMode": "normal",
|
||||
"roomMode": room.room_mode,
|
||||
"startDate": start_date.isoformat(),
|
||||
"endDate": end_date.isoformat(),
|
||||
"recording": {
|
||||
"type": "cloud",
|
||||
"type": room.recording_type,
|
||||
"destination": {
|
||||
"provider": "s3",
|
||||
"bucket": settings.AWS_WHEREBY_S3_BUCKET,
|
||||
@@ -28,7 +29,7 @@ async def create_meeting(
|
||||
"accessKeySecret": settings.AWS_WHEREBY_ACCESS_KEY_SECRET,
|
||||
"fileFormat": "mp4",
|
||||
},
|
||||
"startTrigger": "automatic-2nd-participant",
|
||||
"startTrigger": room.recording_trigger,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user