mirror of
https://github.com/chatmail/core.git
synced 2026-04-02 05:22:14 +03:00
Compare commits
2 Commits
v1.138.1
...
link2xt/js
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfac9d0264 | ||
|
|
027509c629 |
@@ -0,0 +1,775 @@
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import TypeAlias, Union, Optional, Tuple, Any
|
||||
|
||||
|
||||
class AccountEnum:
|
||||
@dataclass(kw_only=True)
|
||||
class Configured:
|
||||
kind: str = "Configured"
|
||||
addr: Optional[str]
|
||||
color: str
|
||||
display_name: Optional[str]
|
||||
id: int
|
||||
profile_image: Optional[str]
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Unconfigured:
|
||||
kind: str = "Unconfigured"
|
||||
id: int
|
||||
|
||||
|
||||
Account: TypeAlias = AccountEnum.Configured | AccountEnum.Unconfigured
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class BasicChat:
|
||||
archived: bool
|
||||
chat_type: int
|
||||
color: str
|
||||
id: int
|
||||
is_contact_request: bool
|
||||
is_device_chat: bool
|
||||
is_muted: bool
|
||||
is_protected: bool
|
||||
is_self_talk: bool
|
||||
is_unpromoted: bool
|
||||
name: str
|
||||
profile_image: str
|
||||
|
||||
|
||||
class ChatListItemFetchResultEnum:
|
||||
@dataclass(kw_only=True)
|
||||
class ChatListItem:
|
||||
kind: str = "ChatListItem"
|
||||
avatar_path: Optional[str]
|
||||
color: str
|
||||
dm_chat_contact: Optional[int]
|
||||
fresh_message_counter: int
|
||||
id: int
|
||||
is_archived: bool
|
||||
is_broadcast: bool
|
||||
is_contact_request: bool
|
||||
is_device_talk: bool
|
||||
is_group: bool
|
||||
is_muted: bool
|
||||
is_pinned: bool
|
||||
is_protected: bool
|
||||
is_self_in_group: bool
|
||||
is_self_talk: bool
|
||||
is_sending_location: bool
|
||||
last_message_id: Optional[int]
|
||||
last_message_type: Optional["Viewtype"]
|
||||
last_updated: Optional[int]
|
||||
name: str
|
||||
summary_preview_image: Optional[str]
|
||||
summary_status: int
|
||||
summary_text1: str
|
||||
summary_text2: str
|
||||
was_seen_recently: bool
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ArchiveLink:
|
||||
kind: str = "ArchiveLink"
|
||||
fresh_message_counter: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Error:
|
||||
kind: str = "Error"
|
||||
error: str
|
||||
id: int
|
||||
|
||||
|
||||
ChatListItemFetchResult: TypeAlias = (
|
||||
ChatListItemFetchResultEnum.ChatListItem
|
||||
| ChatListItemFetchResultEnum.ArchiveLink
|
||||
| ChatListItemFetchResultEnum.Error
|
||||
)
|
||||
|
||||
|
||||
class ChatVisibility(Enum):
|
||||
NORMAL = "Normal"
|
||||
ARCHIVED = "Archived"
|
||||
PINNED = "Pinned"
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Contact:
|
||||
address: str
|
||||
auth_name: str
|
||||
color: str
|
||||
display_name: str
|
||||
id: int
|
||||
is_blocked: bool
|
||||
is_verified: bool
|
||||
last_seen: int
|
||||
name: str
|
||||
name_and_addr: str
|
||||
profile_image: str
|
||||
status: str
|
||||
verifier_addr: str
|
||||
verifier_id: int
|
||||
was_seen_recently: bool
|
||||
|
||||
|
||||
class DownloadState(Enum):
|
||||
DONE = "Done"
|
||||
AVAILABLE = "Available"
|
||||
FAILURE = "Failure"
|
||||
IN_PROGRESS = "InProgress"
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Event:
|
||||
context_id: int
|
||||
event: "EventType"
|
||||
|
||||
|
||||
class EventTypeEnum:
|
||||
@dataclass(kw_only=True)
|
||||
class Info:
|
||||
kind: str = "Info"
|
||||
msg: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class SmtpConnected:
|
||||
kind: str = "SmtpConnected"
|
||||
msg: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ImapConnected:
|
||||
kind: str = "ImapConnected"
|
||||
msg: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class SmtpMessageSent:
|
||||
kind: str = "SmtpMessageSent"
|
||||
msg: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ImapMessageDeleted:
|
||||
kind: str = "ImapMessageDeleted"
|
||||
msg: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ImapMessageMoved:
|
||||
kind: str = "ImapMessageMoved"
|
||||
msg: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ImapInboxIdle:
|
||||
kind: str = "ImapInboxIdle"
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class NewBlobFile:
|
||||
kind: str = "NewBlobFile"
|
||||
file: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class DeletedBlobFile:
|
||||
kind: str = "DeletedBlobFile"
|
||||
file: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Warning:
|
||||
kind: str = "Warning"
|
||||
msg: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Error:
|
||||
kind: str = "Error"
|
||||
msg: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ErrorSelfNotInGroup:
|
||||
kind: str = "ErrorSelfNotInGroup"
|
||||
msg: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class MsgsChanged:
|
||||
kind: str = "MsgsChanged"
|
||||
chat_id: int
|
||||
msg_id: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ReactionsChanged:
|
||||
kind: str = "ReactionsChanged"
|
||||
chat_id: int
|
||||
contact_id: int
|
||||
msg_id: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class IncomingMsg:
|
||||
kind: str = "IncomingMsg"
|
||||
chat_id: int
|
||||
msg_id: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class IncomingMsgBunch:
|
||||
kind: str = "IncomingMsgBunch"
|
||||
msg_ids: list[int]
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class MsgsNoticed:
|
||||
kind: str = "MsgsNoticed"
|
||||
chat_id: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class MsgDelivered:
|
||||
kind: str = "MsgDelivered"
|
||||
chat_id: int
|
||||
msg_id: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class MsgFailed:
|
||||
kind: str = "MsgFailed"
|
||||
chat_id: int
|
||||
msg_id: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class MsgRead:
|
||||
kind: str = "MsgRead"
|
||||
chat_id: int
|
||||
msg_id: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class MsgDeleted:
|
||||
kind: str = "MsgDeleted"
|
||||
chat_id: int
|
||||
msg_id: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ChatModified:
|
||||
kind: str = "ChatModified"
|
||||
chat_id: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ChatEphemeralTimerModified:
|
||||
kind: str = "ChatEphemeralTimerModified"
|
||||
chat_id: int
|
||||
timer: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ContactsChanged:
|
||||
kind: str = "ContactsChanged"
|
||||
contact_id: Optional[int]
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class LocationChanged:
|
||||
kind: str = "LocationChanged"
|
||||
contact_id: Optional[int]
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ConfigureProgress:
|
||||
kind: str = "ConfigureProgress"
|
||||
comment: Optional[str]
|
||||
progress: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ImexProgress:
|
||||
kind: str = "ImexProgress"
|
||||
progress: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ImexFileWritten:
|
||||
kind: str = "ImexFileWritten"
|
||||
path: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class SecurejoinInviterProgress:
|
||||
kind: str = "SecurejoinInviterProgress"
|
||||
contact_id: int
|
||||
progress: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class SecurejoinJoinerProgress:
|
||||
kind: str = "SecurejoinJoinerProgress"
|
||||
contact_id: int
|
||||
progress: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ConnectivityChanged:
|
||||
kind: str = "ConnectivityChanged"
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class SelfavatarChanged:
|
||||
kind: str = "SelfavatarChanged"
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class WebxdcStatusUpdate:
|
||||
kind: str = "WebxdcStatusUpdate"
|
||||
msg_id: int
|
||||
status_update_serial: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class WebxdcInstanceDeleted:
|
||||
kind: str = "WebxdcInstanceDeleted"
|
||||
msg_id: int
|
||||
|
||||
|
||||
EventType: TypeAlias = (
|
||||
EventTypeEnum.Info
|
||||
| EventTypeEnum.SmtpConnected
|
||||
| EventTypeEnum.ImapConnected
|
||||
| EventTypeEnum.SmtpMessageSent
|
||||
| EventTypeEnum.ImapMessageDeleted
|
||||
| EventTypeEnum.ImapMessageMoved
|
||||
| EventTypeEnum.ImapInboxIdle
|
||||
| EventTypeEnum.NewBlobFile
|
||||
| EventTypeEnum.DeletedBlobFile
|
||||
| EventTypeEnum.Warning
|
||||
| EventTypeEnum.Error
|
||||
| EventTypeEnum.ErrorSelfNotInGroup
|
||||
| EventTypeEnum.MsgsChanged
|
||||
| EventTypeEnum.ReactionsChanged
|
||||
| EventTypeEnum.IncomingMsg
|
||||
| EventTypeEnum.IncomingMsgBunch
|
||||
| EventTypeEnum.MsgsNoticed
|
||||
| EventTypeEnum.MsgDelivered
|
||||
| EventTypeEnum.MsgFailed
|
||||
| EventTypeEnum.MsgRead
|
||||
| EventTypeEnum.MsgDeleted
|
||||
| EventTypeEnum.ChatModified
|
||||
| EventTypeEnum.ChatEphemeralTimerModified
|
||||
| EventTypeEnum.ContactsChanged
|
||||
| EventTypeEnum.LocationChanged
|
||||
| EventTypeEnum.ConfigureProgress
|
||||
| EventTypeEnum.ImexProgress
|
||||
| EventTypeEnum.ImexFileWritten
|
||||
| EventTypeEnum.SecurejoinInviterProgress
|
||||
| EventTypeEnum.SecurejoinJoinerProgress
|
||||
| EventTypeEnum.ConnectivityChanged
|
||||
| EventTypeEnum.SelfavatarChanged
|
||||
| EventTypeEnum.WebxdcStatusUpdate
|
||||
| EventTypeEnum.WebxdcInstanceDeleted
|
||||
)
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class FullChat:
|
||||
archived: bool
|
||||
can_send: bool
|
||||
chat_type: int
|
||||
color: str
|
||||
contact_ids: list[int]
|
||||
contacts: list["Contact"]
|
||||
ephemeral_timer: int
|
||||
fresh_message_counter: int
|
||||
id: int
|
||||
is_contact_request: bool
|
||||
is_device_chat: bool
|
||||
is_muted: bool
|
||||
is_protected: bool
|
||||
is_self_talk: bool
|
||||
is_unpromoted: bool
|
||||
mailing_list_address: str
|
||||
name: str
|
||||
profile_image: str
|
||||
self_in_group: bool
|
||||
was_seen_recently: bool
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class HttpResponse:
|
||||
blob: str
|
||||
encoding: str
|
||||
mimetype: str
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Location:
|
||||
accuracy: float
|
||||
chat_id: int
|
||||
contact_id: int
|
||||
is_independent: bool
|
||||
latitude: float
|
||||
location_id: int
|
||||
longitude: float
|
||||
marker: str
|
||||
msg_id: int
|
||||
timestamp: int
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Message:
|
||||
chat_id: int
|
||||
dimensions_height: int
|
||||
dimensions_width: int
|
||||
download_state: "DownloadState"
|
||||
duration: int
|
||||
error: str
|
||||
file: str
|
||||
file_bytes: int
|
||||
file_mime: str
|
||||
file_name: str
|
||||
from_id: int
|
||||
has_deviating_timestamp: bool
|
||||
has_html: bool
|
||||
has_location: bool
|
||||
id: int
|
||||
is_bot: bool
|
||||
is_forwarded: bool
|
||||
is_info: bool
|
||||
is_setupmessage: bool
|
||||
override_sender_name: str
|
||||
parent_id: int
|
||||
quote: Optional["MessageQuote"]
|
||||
reactions: Optional["Reactions"]
|
||||
received_timestamp: int
|
||||
sender: "Contact"
|
||||
setup_code_begin: str
|
||||
show_padlock: bool
|
||||
sort_timestamp: int
|
||||
state: int
|
||||
subject: str
|
||||
system_message_type: "SystemMessageType"
|
||||
text: str
|
||||
timestamp: int
|
||||
videochat_type: int
|
||||
videochat_url: str
|
||||
view_type: "Viewtype"
|
||||
webxdc_info: Optional["WebxdcMessageInfo"]
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class MessageData:
|
||||
file: str
|
||||
html: str
|
||||
location: Tuple[float, float]
|
||||
override_sender_name: str
|
||||
quoted_message_id: int
|
||||
text: str
|
||||
viewtype: Optional["Viewtype"]
|
||||
|
||||
|
||||
class MessageListItemEnum:
|
||||
@dataclass(kw_only=True)
|
||||
class Message:
|
||||
kind: str = "Message"
|
||||
msg_id: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class DayMarker:
|
||||
kind: str = "DayMarker"
|
||||
timestamp: int
|
||||
|
||||
|
||||
MessageListItem: TypeAlias = MessageListItemEnum.Message | MessageListItemEnum.DayMarker
|
||||
|
||||
|
||||
class MessageLoadResultEnum:
|
||||
@dataclass(kw_only=True)
|
||||
class Message:
|
||||
kind: str = "Message"
|
||||
chat_id: int
|
||||
dimensions_height: int
|
||||
dimensions_width: int
|
||||
download_state: "DownloadState"
|
||||
duration: int
|
||||
error: Optional[str]
|
||||
file: Optional[str]
|
||||
file_bytes: int
|
||||
file_mime: Optional[str]
|
||||
file_name: Optional[str]
|
||||
from_id: int
|
||||
has_deviating_timestamp: bool
|
||||
has_html: bool
|
||||
has_location: bool
|
||||
id: int
|
||||
is_bot: bool
|
||||
is_forwarded: bool
|
||||
is_info: bool
|
||||
is_setupmessage: bool
|
||||
override_sender_name: Optional[str]
|
||||
parent_id: Optional[int]
|
||||
quote: Optional["MessageQuote"]
|
||||
reactions: Optional["Reactions"]
|
||||
received_timestamp: int
|
||||
sender: "Contact"
|
||||
setup_code_begin: Optional[str]
|
||||
show_padlock: bool
|
||||
sort_timestamp: int
|
||||
state: int
|
||||
subject: str
|
||||
system_message_type: "SystemMessageType"
|
||||
text: str
|
||||
timestamp: int
|
||||
videochat_type: Optional[int]
|
||||
videochat_url: Optional[str]
|
||||
view_type: "Viewtype"
|
||||
webxdc_info: Optional["WebxdcMessageInfo"]
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class LoadingError:
|
||||
kind: str = "LoadingError"
|
||||
error: str
|
||||
|
||||
|
||||
MessageLoadResult: TypeAlias = MessageLoadResultEnum.Message | MessageLoadResultEnum.LoadingError
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class MessageNotificationInfo:
|
||||
account_id: int
|
||||
chat_id: int
|
||||
chat_name: str
|
||||
chat_profile_image: str
|
||||
id: int
|
||||
image: str
|
||||
image_mime_type: str
|
||||
summary_prefix: str
|
||||
summary_text: str
|
||||
|
||||
|
||||
class MessageQuoteEnum:
|
||||
@dataclass(kw_only=True)
|
||||
class JustText:
|
||||
kind: str = "JustText"
|
||||
text: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class WithMessage:
|
||||
kind: str = "WithMessage"
|
||||
author_display_color: str
|
||||
author_display_name: str
|
||||
image: Optional[str]
|
||||
is_forwarded: bool
|
||||
message_id: int
|
||||
override_sender_name: Optional[str]
|
||||
text: str
|
||||
view_type: "Viewtype"
|
||||
|
||||
|
||||
MessageQuote: TypeAlias = MessageQuoteEnum.JustText | MessageQuoteEnum.WithMessage
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class MessageReadReceipt:
|
||||
contact_id: int
|
||||
timestamp: int
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class MessageSearchResult:
|
||||
author_color: str
|
||||
author_id: int
|
||||
author_name: str
|
||||
author_profile_image: str
|
||||
chat_color: str
|
||||
chat_name: str
|
||||
chat_profile_image: str
|
||||
chat_type: int
|
||||
id: int
|
||||
is_chat_archived: bool
|
||||
is_chat_contact_request: bool
|
||||
is_chat_protected: bool
|
||||
message: str
|
||||
timestamp: int
|
||||
|
||||
|
||||
class MuteDurationEnum:
|
||||
@dataclass(kw_only=True)
|
||||
class NotMuted:
|
||||
kind: str = "NotMuted"
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Forever:
|
||||
kind: str = "Forever"
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Until:
|
||||
kind: str = "Until"
|
||||
timestamp: int
|
||||
|
||||
|
||||
MuteDuration: TypeAlias = MuteDurationEnum.NotMuted | MuteDurationEnum.Forever | MuteDurationEnum.Until
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ProviderInfo:
|
||||
before_login_hint: str
|
||||
overview_page: str
|
||||
status: int
|
||||
|
||||
|
||||
class QrEnum:
|
||||
@dataclass(kw_only=True)
|
||||
class AskVerifyContact:
|
||||
kind: str = "AskVerifyContact"
|
||||
authcode: str
|
||||
contact_id: int
|
||||
fingerprint: str
|
||||
invitenumber: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class AskVerifyGroup:
|
||||
kind: str = "AskVerifyGroup"
|
||||
authcode: str
|
||||
contact_id: int
|
||||
fingerprint: str
|
||||
grpid: str
|
||||
grpname: str
|
||||
invitenumber: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class FprOk:
|
||||
kind: str = "FprOk"
|
||||
contact_id: int
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class FprMismatch:
|
||||
kind: str = "FprMismatch"
|
||||
contact_id: Optional[int]
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class FprWithoutAddr:
|
||||
kind: str = "FprWithoutAddr"
|
||||
fingerprint: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Account:
|
||||
kind: str = "Account"
|
||||
domain: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Backup:
|
||||
kind: str = "Backup"
|
||||
ticket: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class WebrtcInstance:
|
||||
kind: str = "WebrtcInstance"
|
||||
domain: str
|
||||
instance_pattern: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Addr:
|
||||
kind: str = "Addr"
|
||||
contact_id: int
|
||||
draft: Optional[str]
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Url:
|
||||
kind: str = "Url"
|
||||
url: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Text:
|
||||
kind: str = "Text"
|
||||
text: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class WithdrawVerifyContact:
|
||||
kind: str = "WithdrawVerifyContact"
|
||||
authcode: str
|
||||
contact_id: int
|
||||
fingerprint: str
|
||||
invitenumber: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class WithdrawVerifyGroup:
|
||||
kind: str = "WithdrawVerifyGroup"
|
||||
authcode: str
|
||||
contact_id: int
|
||||
fingerprint: str
|
||||
grpid: str
|
||||
grpname: str
|
||||
invitenumber: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ReviveVerifyContact:
|
||||
kind: str = "ReviveVerifyContact"
|
||||
authcode: str
|
||||
contact_id: int
|
||||
fingerprint: str
|
||||
invitenumber: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ReviveVerifyGroup:
|
||||
kind: str = "ReviveVerifyGroup"
|
||||
authcode: str
|
||||
contact_id: int
|
||||
fingerprint: str
|
||||
grpid: str
|
||||
grpname: str
|
||||
invitenumber: str
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Login:
|
||||
kind: str = "Login"
|
||||
address: str
|
||||
|
||||
|
||||
Qr: TypeAlias = (
|
||||
QrEnum.AskVerifyContact
|
||||
| QrEnum.AskVerifyGroup
|
||||
| QrEnum.FprOk
|
||||
| QrEnum.FprMismatch
|
||||
| QrEnum.FprWithoutAddr
|
||||
| QrEnum.Account
|
||||
| QrEnum.Backup
|
||||
| QrEnum.WebrtcInstance
|
||||
| QrEnum.Addr
|
||||
| QrEnum.Url
|
||||
| QrEnum.Text
|
||||
| QrEnum.WithdrawVerifyContact
|
||||
| QrEnum.WithdrawVerifyGroup
|
||||
| QrEnum.ReviveVerifyContact
|
||||
| QrEnum.ReviveVerifyGroup
|
||||
| QrEnum.Login
|
||||
)
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Reaction:
|
||||
count: int
|
||||
emoji: str
|
||||
is_from_self: bool
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Reactions:
|
||||
reactions: list["Reaction"]
|
||||
reactions_by_contact: dict[Any, list[str]]
|
||||
|
||||
|
||||
class SystemMessageType(Enum):
|
||||
UNKNOWN = "Unknown"
|
||||
GROUP_NAME_CHANGED = "GroupNameChanged"
|
||||
GROUP_IMAGE_CHANGED = "GroupImageChanged"
|
||||
MEMBER_ADDED_TO_GROUP = "MemberAddedToGroup"
|
||||
MEMBER_REMOVED_FROM_GROUP = "MemberRemovedFromGroup"
|
||||
AUTOCRYPT_SETUP_MESSAGE = "AutocryptSetupMessage"
|
||||
SECUREJOIN_MESSAGE = "SecurejoinMessage"
|
||||
LOCATION_STREAMING_ENABLED = "LocationStreamingEnabled"
|
||||
LOCATION_ONLY = "LocationOnly"
|
||||
CHAT_PROTECTION_ENABLED = "ChatProtectionEnabled"
|
||||
CHAT_PROTECTION_DISABLED = "ChatProtectionDisabled"
|
||||
WEBXDC_STATUS_UPDATE = "WebxdcStatusUpdate"
|
||||
EPHEMERAL_TIMER_CHANGED = "EphemeralTimerChanged"
|
||||
MULTI_DEVICE_SYNC = "MultiDeviceSync"
|
||||
WEBXDC_INFO_MESSAGE = "WebxdcInfoMessage"
|
||||
|
||||
|
||||
class Viewtype(Enum):
|
||||
UNKNOWN = "Unknown"
|
||||
TEXT = "Text"
|
||||
IMAGE = "Image"
|
||||
GIF = "Gif"
|
||||
STICKER = "Sticker"
|
||||
AUDIO = "Audio"
|
||||
VOICE = "Voice"
|
||||
VIDEO = "Video"
|
||||
FILE = "File"
|
||||
VIDEOCHAT_INVITATION = "VideochatInvitation"
|
||||
WEBXDC = "Webxdc"
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class WebxdcMessageInfo:
|
||||
document: str
|
||||
icon: str
|
||||
internet_access: bool
|
||||
name: str
|
||||
source_code_url: str
|
||||
summary: str
|
||||
@@ -2,6 +2,7 @@ import calendar
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union
|
||||
|
||||
from ._generated_types import MuteDurationEnum
|
||||
from ._utils import AttrDict
|
||||
from .const import ChatVisibility, ViewType
|
||||
from .contact import Contact
|
||||
@@ -54,14 +55,14 @@ class Chat:
|
||||
"""
|
||||
if duration is not None:
|
||||
assert duration > 0, "Invalid duration"
|
||||
dur: dict = {"kind": "Until", "duration": duration}
|
||||
dur: dict = MuteDurationEnum.Until(duration=duration)
|
||||
else:
|
||||
dur = {"kind": "Forever"}
|
||||
dur = MuteDurationEnum.Forever()
|
||||
self._rpc.set_chat_mute_duration(self.account.id, self.id, dur)
|
||||
|
||||
def unmute(self) -> None:
|
||||
"""Unmute this chat."""
|
||||
self._rpc.set_chat_mute_duration(self.account.id, self.id, {"kind": "NotMuted"})
|
||||
self._rpc.set_chat_mute_duration(self.account.id, self.id, MuteDurationEnum.NotMuted())
|
||||
|
||||
def pin(self) -> None:
|
||||
"""Pin this chat."""
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import dataclasses
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
@@ -12,6 +13,13 @@ class JsonRpcError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class DataclassEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
if dataclasses.is_dataclass(obj) and not isinstance(obj, type):
|
||||
return dataclasses.asdict(obj)
|
||||
return json.JSONEncoder.default(self, obj)
|
||||
|
||||
|
||||
class Rpc:
|
||||
def __init__(self, accounts_dir: Optional[str] = None, **kwargs):
|
||||
"""The given arguments will be passed to subprocess.Popen()"""
|
||||
@@ -109,7 +117,7 @@ class Rpc:
|
||||
request = self.request_queue.get()
|
||||
if not request:
|
||||
break
|
||||
data = (json.dumps(request) + "\n").encode()
|
||||
data = (json.dumps(request, cls=DataclassEncoder) + "\n").encode()
|
||||
self.process.stdin.write(data)
|
||||
self.process.stdin.flush()
|
||||
|
||||
|
||||
177
scripts/generate_openrpc_bindings.py
Executable file
177
scripts/generate_openrpc_bindings.py
Executable file
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
import json
|
||||
from pprint import pprint
|
||||
|
||||
|
||||
def from_camel_case(name):
|
||||
"""Convert a camelCase identifier to snake case."""
|
||||
l = len(name)
|
||||
name += "X"
|
||||
res = ""
|
||||
start = 0
|
||||
for i in range(len(name)):
|
||||
if i > 0 and name[i].isupper():
|
||||
res += name[start:i].lower()
|
||||
if i != l:
|
||||
res += "_"
|
||||
start = i
|
||||
return res
|
||||
|
||||
|
||||
def generate_method(method):
|
||||
assert method["paramStructure"] == "by-position"
|
||||
name = method["name"]
|
||||
params = method["params"]
|
||||
args_typed = ", ".join(
|
||||
[
|
||||
from_camel_case(param["name"])
|
||||
+ ": "
|
||||
+ (decode_type(param["schema"]) or "Any")
|
||||
for param in params
|
||||
]
|
||||
)
|
||||
args = ", ".join([from_camel_case(param["name"]) for param in params])
|
||||
result_type = decode_type(method["result"]["schema"])
|
||||
print(f"def {name}({args_typed}) -> {result_type}:")
|
||||
if "description" in method:
|
||||
description = method["description"]
|
||||
if "\n" in description:
|
||||
print(f' """{method["description"].lstrip()}\n """')
|
||||
else:
|
||||
print(f' """{method["description"].lstrip()}"""')
|
||||
print(f" rpc_call({args})")
|
||||
print()
|
||||
|
||||
|
||||
def generate_openrpc_methods(openrpc_spec):
|
||||
for method in openrpc_spec["methods"]:
|
||||
generate_method(method)
|
||||
|
||||
|
||||
def decode_type(property_desc):
|
||||
if "anyOf" in property_desc:
|
||||
t = property_desc["anyOf"]
|
||||
assert len(t) == 2
|
||||
assert t[1] == {"type": "null"}
|
||||
ref = t[0]["$ref"]
|
||||
assert ref.startswith("#/components/schemas/")
|
||||
return f'Optional["{ref.removeprefix("#/components/schemas/")}"]'
|
||||
elif "$ref" in property_desc:
|
||||
t = property_desc["$ref"]
|
||||
assert t.startswith("#/components/schemas/")
|
||||
t = t.removeprefix("#/components/schemas/")
|
||||
return f'"{t}"'
|
||||
elif property_desc["type"] == "null":
|
||||
return "None"
|
||||
elif "null" in property_desc["type"]:
|
||||
assert len(property_desc["type"]) == 2
|
||||
assert property_desc["type"][1] == "null"
|
||||
property_desc["type"] = property_desc["type"][0]
|
||||
t = decode_type(property_desc)
|
||||
if t:
|
||||
return f"Optional[{t}]"
|
||||
elif property_desc["type"] == "boolean":
|
||||
return "bool"
|
||||
elif property_desc["type"] == "integer":
|
||||
return "int"
|
||||
elif property_desc["type"] == "number" and property_desc["format"] == "double":
|
||||
return "float"
|
||||
elif property_desc["type"] == "string":
|
||||
return "str"
|
||||
elif property_desc["type"] == "array":
|
||||
if isinstance(property_desc["items"], list):
|
||||
items_desc = ", ".join(decode_type(x) for x in property_desc["items"])
|
||||
return f"Tuple[{items_desc}]"
|
||||
else:
|
||||
items_type = decode_type(property_desc["items"])
|
||||
return f"list[{items_type}]"
|
||||
elif "additionalProperties" in property_desc:
|
||||
additional_properties = property_desc["additionalProperties"]
|
||||
return f"dict[Any, {decode_type(additional_properties)}]"
|
||||
return None
|
||||
|
||||
|
||||
def generate_variant(variant) -> str:
|
||||
"""Prints generated type for enum variant.
|
||||
|
||||
Returns the name of the generated type.
|
||||
"""
|
||||
assert variant["type"] == "object"
|
||||
kind = variant["properties"]["kind"]
|
||||
assert kind["type"] == "string"
|
||||
assert len(kind["enum"]) == 1
|
||||
kind_name = kind["enum"][0]
|
||||
kind_name = kind_name[0].upper() + kind_name[1:]
|
||||
|
||||
print(f" @dataclass(kw_only=True)")
|
||||
print(f" class {kind_name}:")
|
||||
print(f" kind: str = \"{kind_name}\"")
|
||||
for property_name, property_desc in variant["properties"].items():
|
||||
property_name = from_camel_case(property_name)
|
||||
if property_name == "kind":
|
||||
continue
|
||||
if t := decode_type(property_desc):
|
||||
print(f" {property_name}: {t}")
|
||||
else:
|
||||
print("# TODO")
|
||||
pprint(property_name)
|
||||
pprint(property_desc)
|
||||
print()
|
||||
|
||||
return kind_name
|
||||
|
||||
|
||||
def generate_type(type_name, schema):
|
||||
if "oneOf" in schema:
|
||||
if all(x["type"] == "string" for x in schema["oneOf"]):
|
||||
# Simple enumeration consisting only of various string types.
|
||||
print(f"class {type_name}(Enum):")
|
||||
for x in schema["oneOf"]:
|
||||
for e in x["enum"]:
|
||||
print(f' {from_camel_case(e).upper()} = "{e}"')
|
||||
else:
|
||||
# Union type.
|
||||
namespace = f"{type_name}Enum"
|
||||
print(f"class {namespace}:")
|
||||
kind_names = [f"{namespace}.{generate_variant(x)}" for x in schema["oneOf"]]
|
||||
|
||||
print(f"{type_name}: TypeAlias = {' | '.join(kind_names)}")
|
||||
elif schema["type"] == "string":
|
||||
print(f"class {type_name}(Enum):")
|
||||
for e in schema["enum"]:
|
||||
print(f' {from_camel_case(e).upper()} = "{e}"')
|
||||
else:
|
||||
print("@dataclass(kw_only=True)")
|
||||
print(f"class {type_name}:")
|
||||
for property_name, property_desc in schema["properties"].items():
|
||||
property_name = from_camel_case(property_name)
|
||||
if decode_type(property_desc):
|
||||
print(f" {property_name}: {decode_type(property_desc)}")
|
||||
else:
|
||||
print(f"# TODO {property_name}")
|
||||
pprint(property_desc)
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def generate_openrpc_types(openrpc_spec):
|
||||
for type_name, schema in openrpc_spec["components"]["schemas"].items():
|
||||
generate_type(type_name, schema)
|
||||
|
||||
|
||||
def main():
|
||||
openrpc_spec = json.loads(
|
||||
subprocess.run(
|
||||
["deltachat-rpc-server", "--openrpc"], capture_output=True
|
||||
).stdout
|
||||
)
|
||||
print("from dataclasses import dataclass")
|
||||
print("from enum import Enum")
|
||||
print("from typing import TypeAlias, Union, Optional, Tuple, Any")
|
||||
generate_openrpc_types(openrpc_spec)
|
||||
generate_openrpc_methods(openrpc_spec)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user