response.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. # mautrix-instagram - A Matrix-Instagram puppeting bridge.
  2. # Copyright (C) 2020 Tulir Asokan
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU Affero General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU Affero General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. from typing import Optional, get_type_hints
  17. from aiohttp import ClientResponse
  18. from mautrix.types import JSON, Serializable
  19. from ..types import CheckpointResponse, LoginErrorResponse, LoginRequiredResponse, SpamResponse
  20. from .base import IGError
  21. class IGChallengeWrongCodeError(IGError):
  22. pass
  23. class IGResponseError(IGError):
  24. response: ClientResponse
  25. def __init__(self, response: ClientResponse, json: JSON) -> None:
  26. prefix = f"Request {response.request_info.method} {response.request_info.url.path} failed"
  27. message = f"HTTP {response.status}"
  28. self.response = response
  29. if "message" in json:
  30. message = json["message"]
  31. type_hint = get_type_hints(type(self)).get("body", JSON)
  32. if type_hint is not JSON and issubclass(type_hint, Serializable):
  33. self.body = type_hint.deserialize(json)
  34. super().__init__(f"{prefix}: {self._message_override or message}")
  35. @property
  36. def _message_override(self) -> Optional[str]:
  37. return None
  38. class IGActionSpamError(IGResponseError):
  39. body: SpamResponse
  40. @property
  41. def _message(self) -> str:
  42. return f"HTTP {self.body.message}"
  43. class IGNotFoundError(IGResponseError):
  44. pass
  45. class IGRateLimitError(IGResponseError):
  46. pass
  47. class IGCheckpointError(IGResponseError):
  48. body: CheckpointResponse
  49. @property
  50. def url(self) -> str:
  51. return self.body.challenge.api_path
  52. class IGNotLoggedInError(IGResponseError):
  53. body: LoginRequiredResponse
  54. class IGUserHasLoggedOutError(IGNotLoggedInError):
  55. pass
  56. class IGLoginRequiredError(IGNotLoggedInError):
  57. pass
  58. class IGPrivateUserError(IGResponseError):
  59. pass
  60. class IGSentryBlockError(IGResponseError):
  61. pass
  62. class IGInactiveUserError(IGResponseError):
  63. pass
  64. class IGLoginError(IGResponseError):
  65. body: LoginErrorResponse
  66. class IGLoginTwoFactorRequiredError(IGLoginError):
  67. pass
  68. class IGLoginBadPasswordError(IGLoginError):
  69. pass
  70. class IGLoginInvalidUserError(IGLoginError):
  71. pass
  72. class IGBad2FACodeError(IGResponseError):
  73. pass