2022-02-25 02:22:50 -05:00
|
|
|
# matrix-appservice-kakaotalk - A Matrix-KakaoTalk puppeting bridge.
|
|
|
|
# Copyright (C) 2022 Tulir Asokan, Andrew Ferrazzutti
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU Affero General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU Affero General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2022-03-09 02:25:28 -05:00
|
|
|
from typing import Generic, Type, TypeVar, Union, Iterable
|
2022-02-25 02:22:50 -05:00
|
|
|
|
|
|
|
from attr import dataclass
|
|
|
|
from enum import IntEnum
|
|
|
|
|
2022-03-09 02:25:28 -05:00
|
|
|
from mautrix.types import Serializable, SerializableAttrs, JSON
|
2022-02-25 02:22:50 -05:00
|
|
|
|
|
|
|
from .api.auth_api_client import KnownAuthStatusCode
|
|
|
|
|
|
|
|
|
|
|
|
class KnownDataStatusCode(IntEnum):
|
|
|
|
SUCCESS = 0
|
|
|
|
INVALID_USER = -1
|
|
|
|
CLIENT_ERROR = -200
|
|
|
|
NOT_LOGON = -201
|
|
|
|
INVALID_METHOD = -202
|
|
|
|
INVALID_PARAMETER = -203
|
|
|
|
INVALID_BODY = -203
|
|
|
|
INVALID_HEADER = -204
|
|
|
|
UNAUTHORIZED_CHAT_DELETE = -210
|
|
|
|
MEDIA_SERVER_ERROR = -300
|
|
|
|
CHAT_SPAM_LIMIT = -303
|
|
|
|
RESTRICTED_APP = -304
|
|
|
|
LOGINLIST_CHATLIST_FAILED = -305
|
|
|
|
MEDIA_NOT_FOUND = -306
|
|
|
|
MEDIA_THUMB_GEN_FAILED = -307
|
|
|
|
UNSUPPORTED = -308
|
|
|
|
PARTIAL = -310
|
|
|
|
LINK_JOIN_TPS_EXCEEDED = -312
|
|
|
|
CHAT_SEND_RESTRICTED = -321
|
|
|
|
CHANNEL_CREATE_TEMP_RESTRICTED = -322
|
|
|
|
CHANNEL_CREATE_RESTRICTED = -323
|
|
|
|
OPENLINK_UNAVAILABLE = -324
|
|
|
|
INVITE_COUNT_LIMITED = -325
|
|
|
|
OPENLINK_CREATE_RESTRICTED = -326
|
|
|
|
INVALID_CHANNEL = -401
|
|
|
|
CHAT_BLOCKED_BY_FRIEND = -402
|
|
|
|
NOT_CHATABLE_USER = -403
|
|
|
|
GAME_MESSAGE_BLOCKED = -406
|
|
|
|
BLOCKED_IP = -444
|
|
|
|
BACKGROUND_LOGIN_BLOCKED = -445
|
|
|
|
OPERATION_DENIED = -500
|
|
|
|
CHANNEL_USER_LIMITED = -501
|
|
|
|
TEMP_RESTRICTED = -805
|
|
|
|
WRITE_WHILE_BLOCKED = -814
|
|
|
|
OPENCHAT_REJOIN_REQUIRED = -815
|
|
|
|
OPENCHAT_TIME_RESTRICTED = -819
|
|
|
|
INVALID_ACCESS_TOKEN = -950
|
|
|
|
BLOCKED_ACCOUNT = -997
|
|
|
|
AUTH_REQUIRED = -998
|
|
|
|
UPDATE_REQUIRED = -999
|
|
|
|
SERVER_UNDER_MAINTENANCE = -9797
|
|
|
|
|
2022-02-26 04:06:26 -05:00
|
|
|
DataStatusCode = Union[KnownDataStatusCode, int]
|
2022-02-25 02:22:50 -05:00
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class ResponseState(SerializableAttrs):
|
2022-02-26 04:06:26 -05:00
|
|
|
status: Union[DataStatusCode, KnownAuthStatusCode] # NOTE Added KnownAuthStatusCode
|
2022-02-25 02:22:50 -05:00
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class RootCommandResult(ResponseState):
|
|
|
|
"""For brevity, this also encompasses CommandResultFailed and CommandResultDoneVoid"""
|
|
|
|
success: bool
|
|
|
|
|
2022-03-18 03:52:55 -04:00
|
|
|
@classmethod
|
|
|
|
def deserialize(cls, data: JSON) -> "RootCommandResult":
|
|
|
|
if not data or "success" not in data or "status" not in data:
|
|
|
|
return RootCommandResult(
|
|
|
|
success=True,
|
|
|
|
status=KnownDataStatusCode.SUCCESS
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
return super().deserialize(data)
|
|
|
|
|
2022-02-25 02:22:50 -05:00
|
|
|
|
2022-03-09 02:25:28 -05:00
|
|
|
ResultType = TypeVar("ResultType", bound=Serializable)
|
|
|
|
|
|
|
|
def ResultListType(result_type: Type[ResultType]):
|
|
|
|
class _ResultListType(list[result_type], Serializable):
|
|
|
|
def serialize(self) -> list[JSON]:
|
|
|
|
return [v.serialize() for v in self]
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def deserialize(cls, data: list[JSON]) -> "_ResultListType":
|
2022-04-06 12:49:23 -04:00
|
|
|
return [result_type.deserialize(item) for item in data]
|
2022-03-09 02:25:28 -05:00
|
|
|
|
|
|
|
return _ResultListType
|
|
|
|
|
2022-02-25 02:22:50 -05:00
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class CommandResultDoneValue(RootCommandResult, Generic[ResultType]):
|
|
|
|
result: ResultType
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def deserialize_result(
|
|
|
|
cls, result_type: Type[ResultType], data: JSON
|
|
|
|
) -> "CommandResultDoneValue[ResultType]":
|
|
|
|
data["result"] = result_type.deserialize(data["result"])
|
|
|
|
return cls.deserialize(data)
|
|
|
|
|
|
|
|
|
|
|
|
def deserialize_result(
|
|
|
|
result_type: Type[ResultType], data: JSON
|
2022-02-26 04:06:26 -05:00
|
|
|
) -> Union[CommandResultDoneValue[ResultType], RootCommandResult]:
|
2022-02-25 02:22:50 -05:00
|
|
|
"""Returns equivalent of CommandResult<T>. Does no consistency checking on success & result properties."""
|
2022-03-23 03:09:30 -04:00
|
|
|
if "result" in data and data.get("success"):
|
2022-02-25 02:22:50 -05:00
|
|
|
# TODO Allow arbitrary result object?
|
|
|
|
return CommandResultDoneValue.deserialize_result(result_type, data)
|
|
|
|
else:
|
|
|
|
return RootCommandResult.deserialize(data)
|
|
|
|
|
|
|
|
|
|
|
|
__all__ = [
|
|
|
|
"KnownDataStatusCode",
|
|
|
|
"DataStatusCode",
|
|
|
|
"ResponseState",
|
|
|
|
"RootCommandResult",
|
|
|
|
"CommandResultDoneValue",
|
|
|
|
]
|