|
6 | 6 | import typing |
7 | 7 |
|
8 | 8 | from . import files as _files |
9 | | -from .user_status import _UserStatus |
10 | 9 |
|
11 | 10 |
|
12 | 11 | class ConversationType(enum.IntEnum): |
@@ -91,7 +90,7 @@ class ListableScope(enum.IntEnum): |
91 | 90 | class NotificationLevel(enum.IntEnum): |
92 | 91 | """The notification level for the user. |
93 | 92 |
|
94 | | - .. note:: Default: ``1`` for one-to-one conversations, ``2`` for other conversations. |
| 93 | + .. note:: Default: ``1`` for ``one-to-one`` conversations, ``2`` for other conversations. |
95 | 94 | """ |
96 | 95 |
|
97 | 96 | DEFAULT = 0 |
@@ -309,8 +308,29 @@ def to_fs_node(self) -> _files.FsNode: |
309 | 308 | ) |
310 | 309 |
|
311 | 310 |
|
| 311 | +@dataclasses.dataclass |
| 312 | +class _TalkUserStatus: |
| 313 | + def __init__(self, raw_data: dict): |
| 314 | + self._raw_data = raw_data |
| 315 | + |
| 316 | + @property |
| 317 | + def status_message(self) -> str: |
| 318 | + """Message of the status.""" |
| 319 | + return str(self._raw_data.get("statusMessage", "") or "") |
| 320 | + |
| 321 | + @property |
| 322 | + def status_icon(self) -> str: |
| 323 | + """The icon picked by the user (must be one emoji).""" |
| 324 | + return str(self._raw_data.get("statusIcon", "") or "") |
| 325 | + |
| 326 | + @property |
| 327 | + def status_type(self) -> str: |
| 328 | + """Status type, on of the: online, away, dnd, invisible, offline.""" |
| 329 | + return str(self._raw_data.get("status", "") or "") |
| 330 | + |
| 331 | + |
312 | 332 | @dataclasses.dataclass(init=False) |
313 | | -class Conversation(_UserStatus): |
| 333 | +class Conversation(_TalkUserStatus): |
314 | 334 | """Talk conversation.""" |
315 | 335 |
|
316 | 336 | @property |
@@ -447,7 +467,7 @@ def can_start_call(self) -> bool: |
447 | 467 | def can_delete_conversation(self) -> bool: |
448 | 468 | """Flag if the user can delete the conversation for everyone. |
449 | 469 |
|
450 | | - .. note: Not possible without moderator permissions or in one-to-one conversations. |
| 470 | + .. note: Not possible without moderator permissions or in ``one-to-one`` conversations. |
451 | 471 | """ |
452 | 472 | return bool(self._raw_data.get("canDeleteConversation", False)) |
453 | 473 |
|
@@ -597,6 +617,74 @@ def recording_status(self) -> CallRecordingStatus: |
597 | 617 | """ |
598 | 618 | return CallRecordingStatus(self._raw_data.get("callRecording", CallRecordingStatus.NO_RECORDING)) |
599 | 619 |
|
| 620 | + @property |
| 621 | + def status_clear_at(self) -> typing.Optional[int]: |
| 622 | + """Unix Timestamp representing the time to clear the status. |
| 623 | +
|
| 624 | + .. note:: Available only for ``one-to-one`` conversations. |
| 625 | + """ |
| 626 | + return self._raw_data.get("statusClearAt", None) |
| 627 | + |
| 628 | + |
| 629 | +@dataclasses.dataclass(init=False) |
| 630 | +class Participant(_TalkUserStatus): |
| 631 | + """Conversation participant information.""" |
| 632 | + |
| 633 | + @property |
| 634 | + def attendee_id(self) -> int: |
| 635 | + """Unique attendee id.""" |
| 636 | + return self._raw_data["attendeeId"] |
| 637 | + |
| 638 | + @property |
| 639 | + def actor_type(self) -> str: |
| 640 | + """The actor type of the participant that voted: **users**, **groups**, **circles**, **guests**, **emails**.""" |
| 641 | + return self._raw_data["actorType"] |
| 642 | + |
| 643 | + @property |
| 644 | + def actor_id(self) -> str: |
| 645 | + """The unique identifier for the given actor type.""" |
| 646 | + return self._raw_data["actorId"] |
| 647 | + |
| 648 | + @property |
| 649 | + def display_name(self) -> str: |
| 650 | + """Can be empty for guests.""" |
| 651 | + return self._raw_data["displayName"] |
| 652 | + |
| 653 | + @property |
| 654 | + def participant_type(self) -> ParticipantType: |
| 655 | + """Permissions level, see: :py:class:`~nc_py_api.talk.ParticipantType`.""" |
| 656 | + return ParticipantType(self._raw_data["participantType"]) |
| 657 | + |
| 658 | + @property |
| 659 | + def last_ping(self) -> int: |
| 660 | + """Timestamp of the last ping. Should be used for sorting.""" |
| 661 | + return self._raw_data["lastPing"] |
| 662 | + |
| 663 | + @property |
| 664 | + def participant_flags(self) -> InCallFlags: |
| 665 | + """Current call flags.""" |
| 666 | + return InCallFlags(self._raw_data.get("inCall", InCallFlags.DISCONNECTED)) |
| 667 | + |
| 668 | + @property |
| 669 | + def permissions(self) -> AttendeePermissions: |
| 670 | + """Final permissions, combined :py:class:`~nc_py_api.talk.AttendeePermissions` values.""" |
| 671 | + return AttendeePermissions(self._raw_data["permissions"]) |
| 672 | + |
| 673 | + @property |
| 674 | + def attendee_permissions(self) -> AttendeePermissions: |
| 675 | + """Dedicated permissions for the current participant, if not ``Custom``, they are not the resulting ones.""" |
| 676 | + return AttendeePermissions(self._raw_data["attendeePermissions"]) |
| 677 | + |
| 678 | + @property |
| 679 | + def session_ids(self) -> list[str]: |
| 680 | + """A list of session IDs, each one 512 characters long, or empty if there is no session.""" |
| 681 | + return self._raw_data["sessionIds"] |
| 682 | + |
| 683 | + @property |
| 684 | + def breakout_token(self) -> str: |
| 685 | + """Only available with breakout-rooms-v1 capability.""" |
| 686 | + return self._raw_data.get("roomToken", "") |
| 687 | + |
600 | 688 |
|
601 | 689 | @dataclasses.dataclass |
602 | 690 | class BotInfoBasic: |
|
0 commit comments