Skip to content

Commit e410974

Browse files
committed
Add Meeting class for meeting recordings
1 parent d67785e commit e410974

File tree

3 files changed

+94
-30
lines changed

3 files changed

+94
-30
lines changed

videodb/client.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from videodb.video import Video
1919
from videodb.audio import Audio
2020
from videodb.image import Image
21+
from videodb.meeting import Meeting
2122

2223
from videodb._upload import (
2324
upload,
@@ -299,7 +300,7 @@ def record_meeting(
299300
callback_url: str,
300301
callback_data: dict = {},
301302
time_zone: str = "UTC",
302-
) -> dict:
303+
) -> Meeting:
303304
"""Record a meeting and upload it to the default collection.
304305
305306
:param str link: Meeting link
@@ -308,8 +309,8 @@ def record_meeting(
308309
:param str callback_url: URL to receive callback once recording is done
309310
:param dict callback_data: Data to be sent in the callback (optional)
310311
:param str time_zone: Time zone for the meeting (default ``UTC``)
311-
:return: Response data from the API
312-
:rtype: dict
312+
:return: :class:`Meeting <Meeting>` object representing the recording bot
313+
:rtype: :class:`videodb.meeting.Meeting`
313314
"""
314315

315316
response = self.post(
@@ -323,14 +324,5 @@ def record_meeting(
323324
"time_zone": time_zone,
324325
},
325326
)
326-
return response
327-
328-
def get_meeting_info(self, bot_id: str) -> dict:
329-
"""Get the information of a given meeting bot.
330-
331-
:param str bot_id: ID returned when recording was initiated
332-
:return: Information of the meeting bot
333-
:rtype: dict
334-
"""
335-
336-
return self.get(path=f"{ApiPath.collection}/default/{ApiPath.meeting}/{bot_id}")
327+
meeting_id = response.get("meeting_id")
328+
return Meeting(self, id=meeting_id, collection_id="default", **response)

videodb/collection.py

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from videodb.video import Video
1313
from videodb.audio import Audio
1414
from videodb.image import Image
15+
from videodb.meeting import Meeting
1516
from videodb.rtstream import RTStream
1617
from videodb.search import SearchFactory, SearchResult
1718

@@ -493,7 +494,7 @@ def record_meeting(
493494
callback_url: str,
494495
callback_data: dict = {},
495496
time_zone: str = "UTC",
496-
) -> dict:
497+
) -> Meeting:
497498
"""Record a meeting and upload it to this collection.
498499
499500
:param str link: Meeting link
@@ -502,11 +503,11 @@ def record_meeting(
502503
:param str callback_url: URL to receive callback once recording is done
503504
:param dict callback_data: Data to be sent in the callback (optional)
504505
:param str time_zone: Time zone for the meeting (default ``UTC``)
505-
:return: Response data from the API
506-
:rtype: dict
506+
:return: :class:`Meeting <Meeting>` object representing the recording bot
507+
:rtype: :class:`videodb.meeting.Meeting`
507508
"""
508509

509-
return self._connection.post(
510+
response = self._connection.post(
510511
path=f"{ApiPath.collection}/{self.id}/{ApiPath.meeting}/{ApiPath.record}",
511512
data={
512513
"link": link,
@@ -517,15 +518,5 @@ def record_meeting(
517518
"time_zone": time_zone,
518519
},
519520
)
520-
521-
def get_meeting_info(self, bot_id: str) -> dict:
522-
"""Get the recording info for a meeting bot in this collection.
523-
524-
:param str bot_id: ID returned when recording was initiated
525-
:return: Information of the meeting bot
526-
:rtype: dict
527-
"""
528-
529-
return self._connection.get(
530-
path=f"{ApiPath.collection}/{self.id}/{ApiPath.meeting}/{bot_id}"
531-
)
521+
meeting_id = response.get("meeting_id")
522+
return Meeting(self._connection, id=meeting_id, collection_id=self.id, **response)

videodb/meeting.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
from videodb._constants import ApiPath
2+
3+
from videodb.exceptions import (
4+
VideodbError,
5+
)
6+
7+
8+
class Meeting:
9+
"""Meeting class representing a meeting recording bot."""
10+
11+
def __init__(self, _connection, id: str, collection_id: str, **kwargs) -> None:
12+
self._connection = _connection
13+
self.id = id
14+
self.collection_id = collection_id
15+
self._update_attributes(kwargs)
16+
17+
def __repr__(self) -> str:
18+
return f"Meeting(id={self.id}, collection_id={self.collection_id}, name={self.name}, status={self.status}, bot_name={self.bot_name})"
19+
20+
def _update_attributes(self, data: dict) -> None:
21+
"""Update instance attributes from API response data."""
22+
self.bot_name = data.get("bot_name")
23+
self.name = data.get("meeting_name")
24+
self.meeting_url = data.get("meeting_url")
25+
self.status = data.get("status")
26+
self.time_zone = data.get("time_zone")
27+
28+
def refresh(self) -> "Meeting":
29+
"""Refresh meeting data from the server.
30+
31+
Returns:
32+
self: The Meeting instance with updated data
33+
34+
Raises:
35+
APIError: If the API request fails
36+
"""
37+
response = self._connection.get(
38+
path=f"{ApiPath.collection}/{self.collection_id}/{ApiPath.meeting}/{self.id}"
39+
)
40+
41+
if response:
42+
self._update_attributes(response)
43+
else:
44+
raise VideodbError(f"Failed to refresh meeting {self.id}")
45+
46+
return self
47+
48+
@property
49+
def is_active(self) -> bool:
50+
"""Check if the meeting is currently active."""
51+
return self.status in ["initializing", "processing"]
52+
53+
@property
54+
def is_completed(self) -> bool:
55+
"""Check if the meeting has completed."""
56+
return self.status in ["done"]
57+
58+
def wait_for_status(
59+
self, target_status: str, timeout: int = 14400, interval: int = 300
60+
) -> bool:
61+
"""Wait for the meeting to reach a specific status.
62+
63+
Args:
64+
target_status: The status to wait for
65+
timeout: Maximum time to wait in seconds
66+
interval: Time between status checks in seconds
67+
68+
Returns:
69+
bool: True if status reached, False if timeout
70+
"""
71+
import time
72+
73+
start_time = time.time()
74+
75+
while time.time() - start_time < timeout:
76+
self.refresh()
77+
if self.status == target_status:
78+
return True
79+
time.sleep(interval)
80+
81+
return False

0 commit comments

Comments
 (0)