mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-09 09:22:03 +00:00
Refactoring.
This commit is contained in:
parent
62e7bd1cbe
commit
07c7c1f32a
38 changed files with 313 additions and 243 deletions
181
aiogram/bot.py
181
aiogram/bot.py
|
|
@ -4,15 +4,7 @@ import json
|
|||
import aiohttp
|
||||
|
||||
from . import api
|
||||
from .api import ApiMethods
|
||||
from .types.chat import Chat
|
||||
from .types.chat_member import ChatMember
|
||||
from .types.file import File
|
||||
from .types.message import Message
|
||||
from .types.update import Update
|
||||
from .types.user import User
|
||||
from .types.user_profile_photos import UserProfilePhotos
|
||||
from .types.webhook_info import WebhookInfo
|
||||
from . import types
|
||||
from .utils.payload import generate_payload
|
||||
|
||||
|
||||
|
|
@ -45,7 +37,7 @@ class AIOGramBot:
|
|||
return obj
|
||||
|
||||
@property
|
||||
async def me(self) -> User:
|
||||
async def me(self) -> types.User:
|
||||
if not hasattr(self, '_me'):
|
||||
setattr(self, '_me', await self.get_me())
|
||||
return getattr(self, '_me')
|
||||
|
|
@ -55,13 +47,13 @@ class AIOGramBot:
|
|||
|
||||
async def _send_file(self, file_type, file, payload):
|
||||
methods = {
|
||||
'photo': ApiMethods.SEND_PHOTO,
|
||||
'audio': ApiMethods.SEND_AUDIO,
|
||||
'document': ApiMethods.SEND_DOCUMENT,
|
||||
'sticker': ApiMethods.SEND_STICKER,
|
||||
'video': ApiMethods.SEND_VIDEO,
|
||||
'voice': ApiMethods.SEND_VOICE,
|
||||
'video_note': ApiMethods.SEND_VIDEO_NOTE
|
||||
'photo': api.ApiMethods.SEND_PHOTO,
|
||||
'audio': api.ApiMethods.SEND_AUDIO,
|
||||
'document': api.ApiMethods.SEND_DOCUMENT,
|
||||
'sticker': api.ApiMethods.SEND_STICKER,
|
||||
'video': api.ApiMethods.SEND_VIDEO,
|
||||
'voice': api.ApiMethods.SEND_VOICE,
|
||||
'video_note': api.ApiMethods.SEND_VIDEO_NOTE
|
||||
}
|
||||
|
||||
method = methods[file_type]
|
||||
|
|
@ -70,41 +62,41 @@ class AIOGramBot:
|
|||
req = self.request(method, payload)
|
||||
else:
|
||||
data = {file_type: file}
|
||||
req = self.request(ApiMethods.SEND_PHOTO, payload, data)
|
||||
req = self.request(api.ApiMethods.SEND_PHOTO, payload, data)
|
||||
|
||||
return self.prepare_object(Message.de_json(await req))
|
||||
return self.prepare_object(types.Message.de_json(await req))
|
||||
|
||||
async def get_me(self) -> User:
|
||||
raw = await self.request(ApiMethods.GET_ME)
|
||||
return self.prepare_object(User.de_json(raw))
|
||||
async def get_me(self) -> types.User:
|
||||
raw = await self.request(api.ApiMethods.GET_ME)
|
||||
return self.prepare_object(types.User.de_json(raw))
|
||||
|
||||
async def get_updates(self, offset=None, limit=None, timeout=None, allowed_updates=None):
|
||||
async def get_updates(self, offset=None, limit=None, timeout=None, allowed_updates=None) -> [types.Update]:
|
||||
payload = generate_payload(**locals())
|
||||
raw = await self.request(ApiMethods.GET_UPDATES, payload)
|
||||
return [self.prepare_object(Update.de_json(raw_update)) for raw_update in raw]
|
||||
raw = await self.request(api.ApiMethods.GET_UPDATES, payload)
|
||||
return [self.prepare_object(types.Update.de_json(raw_update)) for raw_update in raw]
|
||||
|
||||
async def set_webhook(self, url, certificate=None, max_connections=None, allowed_updates=None):
|
||||
async def set_webhook(self, url, certificate=None, max_connections=None, allowed_updates=None) -> types.WebhookInfo:
|
||||
payload = generate_payload(**locals(), exclude='certificate')
|
||||
if certificate:
|
||||
cert = {'certificate': certificate}
|
||||
req = self.request(ApiMethods.SET_WEBHOOK, payload, cert)
|
||||
req = self.request(api.ApiMethods.SET_WEBHOOK, payload, cert)
|
||||
else:
|
||||
req = self.request(ApiMethods.SET_WEBHOOK, payload)
|
||||
req = self.request(api.ApiMethods.SET_WEBHOOK, payload)
|
||||
|
||||
return self.prepare_object(WebhookInfo.de_json(await req))
|
||||
return self.prepare_object(types.WebhookInfo.de_json(await req))
|
||||
|
||||
async def delete_webhook(self):
|
||||
async def delete_webhook(self) -> bool:
|
||||
payload = {}
|
||||
await self.request(ApiMethods.DELETE_WEBHOOK, payload)
|
||||
await self.request(api.ApiMethods.DELETE_WEBHOOK, payload)
|
||||
return True
|
||||
|
||||
async def get_webhook_info(self):
|
||||
async def get_webhook_info(self) -> types.WebhookInfo:
|
||||
payload = {}
|
||||
webhook_info = await self.request(ApiMethods.GET_WEBHOOK_INFO, payload)
|
||||
webhook_info = await self.request(api.ApiMethods.GET_WEBHOOK_INFO, payload)
|
||||
return self.prepare_object(webhook_info)
|
||||
|
||||
async def send_message(self, chat_id, text, parse_mode=None, disable_web_page_preview=None,
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None):
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> types.Message:
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
||||
|
|
@ -112,16 +104,16 @@ class AIOGramBot:
|
|||
reply_to_message_id = reply_to_message_id.message_id
|
||||
|
||||
payload = generate_payload(**locals())
|
||||
message = await self.request(ApiMethods.SEND_MESSAGE, payload)
|
||||
return self.prepare_object(Message.de_json(message))
|
||||
message = await self.request(api.ApiMethods.SEND_MESSAGE, payload)
|
||||
return self.prepare_object(types.Message.de_json(message))
|
||||
|
||||
async def forward_message(self, chat_id, from_chat_id, message_id, disable_notification=None):
|
||||
async def forward_message(self, chat_id, from_chat_id, message_id, disable_notification=None) -> types.Message:
|
||||
payload = generate_payload(**locals())
|
||||
message = await self.request(ApiMethods.FORWARD_MESSAGE, payload)
|
||||
return self.prepare_object(Message.de_json(message))
|
||||
message = await self.request(api.ApiMethods.FORWARD_MESSAGE, payload)
|
||||
return self.prepare_object(types.Message.de_json(message))
|
||||
|
||||
async def send_photo(self, chat_id, photo, caption=None, disable_notification=None, reply_to_message_id=None,
|
||||
reply_markup=None) -> Message:
|
||||
reply_markup=None) -> types.Message:
|
||||
_message_type = 'photo'
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
|
@ -133,7 +125,7 @@ class AIOGramBot:
|
|||
return await self._send_file(_message_type, photo, payload)
|
||||
|
||||
async def send_audio(self, chat_id, audio, caption=None, duration=None, performer=None, title=None,
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> Message:
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> types.Message:
|
||||
_message_type = 'audio'
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
|
@ -145,7 +137,7 @@ class AIOGramBot:
|
|||
return await self._send_file(_message_type, audio, payload)
|
||||
|
||||
async def send_document(self, chat_id, document, caption=None, disable_notification=None, reply_to_message_id=None,
|
||||
reply_markup=None):
|
||||
reply_markup=None) -> types.Message:
|
||||
_message_type = 'document'
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
|
@ -157,7 +149,7 @@ class AIOGramBot:
|
|||
return await self._send_file(_message_type, document, payload)
|
||||
|
||||
async def send_sticker(self, chat_id, sticker, disable_notification=None, reply_to_message_id=None,
|
||||
reply_markup=None) -> Message:
|
||||
reply_markup=None) -> types.Message:
|
||||
_METHOD = 'sticker'
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
|
@ -169,7 +161,7 @@ class AIOGramBot:
|
|||
return await self._send_file(_METHOD, sticker, payload)
|
||||
|
||||
async def send_video(self, chat_id, video, duration=None, width=None, height=None, caption=None,
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> Message:
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> types.Message:
|
||||
_message_type = 'video'
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
|
@ -181,7 +173,7 @@ class AIOGramBot:
|
|||
return await self._send_file(_message_type, video, payload)
|
||||
|
||||
async def send_voice(self, chat_id, voice, caption=None, duration=None, disable_notification=None,
|
||||
reply_to_message_id=None, reply_markup=None) -> Message:
|
||||
reply_to_message_id=None, reply_markup=None) -> types.Message:
|
||||
_message_type = 'voice'
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
|
@ -193,7 +185,7 @@ class AIOGramBot:
|
|||
return await self._send_file(_message_type, voice, payload)
|
||||
|
||||
async def send_video_note(self, chat_id, video_note, duration=None, length=None, disable_notification=None,
|
||||
reply_to_message_id=None, reply_markup=None) -> Message:
|
||||
reply_to_message_id=None, reply_markup=None) -> types.Message:
|
||||
_message_type = 'video_note'
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
|
@ -205,7 +197,7 @@ class AIOGramBot:
|
|||
return await self._send_file(_message_type, video_note, payload)
|
||||
|
||||
async def send_location(self, chat_id, latitude, longitude, disable_notification=None, reply_to_message_id=None,
|
||||
reply_markup=None):
|
||||
reply_markup=None) -> types.Message:
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
||||
|
|
@ -213,11 +205,11 @@ class AIOGramBot:
|
|||
reply_to_message_id = reply_to_message_id.message_id
|
||||
|
||||
payload = generate_payload(**locals())
|
||||
message = await self.request(ApiMethods.SEND_LOCATION, payload)
|
||||
return self.prepare_object(Message.de_json(message))
|
||||
message = await self.request(api.ApiMethods.SEND_LOCATION, payload)
|
||||
return self.prepare_object(types.Message.de_json(message))
|
||||
|
||||
async def send_venue(self, chat_id, latitude, longitude, title, address, foursquare_id, disable_notification=None,
|
||||
reply_to_message_id=None, reply_markup=None):
|
||||
reply_to_message_id=None, reply_markup=None) -> types.Message:
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
||||
|
|
@ -225,11 +217,11 @@ class AIOGramBot:
|
|||
reply_to_message_id = reply_to_message_id.message_id
|
||||
|
||||
payload = generate_payload(**locals())
|
||||
message = await self.request(ApiMethods.SEND_VENUE, payload)
|
||||
return self.prepare_object(Message.de_json(message))
|
||||
message = await self.request(api.ApiMethods.SEND_VENUE, payload)
|
||||
return self.prepare_object(types.Message.de_json(message))
|
||||
|
||||
async def send_contact(self, chat_id, phone_number, first_name, last_name=None, disable_notification=None,
|
||||
reply_to_message_id=None, reply_markup=None):
|
||||
reply_to_message_id=None, reply_markup=None) -> types.Message:
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
||||
|
|
@ -237,61 +229,61 @@ class AIOGramBot:
|
|||
reply_to_message_id = reply_to_message_id.message_id
|
||||
|
||||
payload = generate_payload(**locals())
|
||||
message = await self.request(ApiMethods.SEND_CONTACT, payload)
|
||||
return self.prepare_object(Message.de_json(message))
|
||||
message = await self.request(api.ApiMethods.SEND_CONTACT, payload)
|
||||
return self.prepare_object(types.Message.de_json(message))
|
||||
|
||||
async def send_chat_action(self, chat_id, action):
|
||||
async def send_chat_action(self, chat_id, action) -> bool:
|
||||
payload = generate_payload(**locals())
|
||||
message = await self.request(ApiMethods.SEND_CHAT_ACTION, payload)
|
||||
return self.prepare_object(Message.de_json(message))
|
||||
return await self.request(api.ApiMethods.SEND_CHAT_ACTION, payload)
|
||||
|
||||
async def get_user_profile_photos(self, user_id, offset=None, limit=None):
|
||||
async def get_user_profile_photos(self, user_id, offset=None, limit=None) -> types.UserProfilePhotos:
|
||||
payload = generate_payload(**locals())
|
||||
message = await self.request(ApiMethods.GET_USER_PROFILE_PHOTOS, payload)
|
||||
return self.prepare_object(UserProfilePhotos.de_json(message))
|
||||
message = await self.request(api.ApiMethods.GET_USER_PROFILE_PHOTOS, payload)
|
||||
return self.prepare_object(types.UserProfilePhotos.de_json(message))
|
||||
|
||||
async def get_file(self, file_id):
|
||||
async def get_file(self, file_id) -> types.File:
|
||||
payload = generate_payload(**locals())
|
||||
message = await self.request(ApiMethods.GET_FILE, payload)
|
||||
return self.prepare_object(File.de_json(message))
|
||||
message = await self.request(api.ApiMethods.GET_FILE, payload)
|
||||
return self.prepare_object(types.File.de_json(message))
|
||||
|
||||
async def kick_chat_user(self, chat_id, user_id):
|
||||
async def kick_chat_user(self, chat_id, user_id) -> bool:
|
||||
payload = generate_payload(**locals())
|
||||
return await self.request(ApiMethods.KICK_CHAT_MEMBER, payload)
|
||||
return await self.request(api.ApiMethods.KICK_CHAT_MEMBER, payload)
|
||||
|
||||
async def unban_chat_member(self, chat_id, user_id):
|
||||
async def unban_chat_member(self, chat_id, user_id) -> bool:
|
||||
payload = generate_payload(**locals())
|
||||
return await self.request(ApiMethods.UNBAN_CHAT_MEMBER, payload)
|
||||
return await self.request(api.ApiMethods.UNBAN_CHAT_MEMBER, payload)
|
||||
|
||||
async def leave_chat(self, chat_id):
|
||||
async def leave_chat(self, chat_id) -> bool:
|
||||
payload = generate_payload(**locals())
|
||||
return await self.request(ApiMethods.LEAVE_CHAT, payload)
|
||||
return await self.request(api.ApiMethods.LEAVE_CHAT, payload)
|
||||
|
||||
async def get_chat(self, chat_id) -> Chat:
|
||||
async def get_chat(self, chat_id) -> types.Chat:
|
||||
payload = generate_payload(**locals())
|
||||
raw = await self.request(ApiMethods.GET_CHAT, payload)
|
||||
return self.prepare_object(Chat.de_json(raw))
|
||||
raw = await self.request(api.ApiMethods.GET_CHAT, payload)
|
||||
return self.prepare_object(types.Chat.de_json(raw))
|
||||
|
||||
async def get_chat_administrators(self, chat_id):
|
||||
async def get_chat_administrators(self, chat_id) -> [types.ChatMember]:
|
||||
payload = generate_payload(**locals())
|
||||
raw = await self.request(ApiMethods.GET_CHAT_ADMINISTRATORS, payload)
|
||||
return [self.prepare_object(ChatMember.de_json(raw_chat_member)) for raw_chat_member in raw]
|
||||
raw = await self.request(api.ApiMethods.GET_CHAT_ADMINISTRATORS, payload)
|
||||
return [self.prepare_object(types.ChatMember.de_json(raw_chat_member)) for raw_chat_member in raw]
|
||||
|
||||
async def get_chat_members_count(self, chat_id):
|
||||
async def get_chat_members_count(self, chat_id) -> int:
|
||||
payload = generate_payload(**locals())
|
||||
return await self.request(ApiMethods.GET_CHAT_MEMBERS_COUNT, payload)
|
||||
return await self.request(api.ApiMethods.GET_CHAT_MEMBERS_COUNT, payload)
|
||||
|
||||
async def get_chat_member(self, chat_id, user_id):
|
||||
async def get_chat_member(self, chat_id, user_id) -> types.ChatMember:
|
||||
payload = generate_payload(**locals())
|
||||
raw = await self.request(ApiMethods.GET_CHAT_MEMBER, payload)
|
||||
return self.prepare_object(ChatMember.de_json(raw))
|
||||
raw = await self.request(api.ApiMethods.GET_CHAT_MEMBER, payload)
|
||||
return self.prepare_object(types.ChatMember.de_json(raw))
|
||||
|
||||
async def answer_callback_query(self, callback_query_id, text=None, show_alert=None, url=None, cache_time=None):
|
||||
async def answer_callback_query(self, callback_query_id, text=None, show_alert=None, url=None,
|
||||
cache_time=None) -> bool:
|
||||
payload = generate_payload(**locals())
|
||||
return await self.request(ApiMethods.LEAVE_CHAT, payload)
|
||||
return await self.request(api.ApiMethods.LEAVE_CHAT, payload)
|
||||
|
||||
async def edit_message_text(self, text, chat_id=None, message_id=None, inline_message_id=None, parse_mode=None,
|
||||
disable_web_page_preview=None, reply_markup=None):
|
||||
disable_web_page_preview=None, reply_markup=None) -> types.Message or bool:
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
||||
|
|
@ -302,13 +294,13 @@ class AIOGramBot:
|
|||
inline_message_id = inline_message_id.message_id
|
||||
|
||||
payload = generate_payload(**locals())
|
||||
raw = await self.request(ApiMethods.EDIT_MESSAGE_TEXT, payload)
|
||||
raw = await self.request(api.ApiMethods.EDIT_MESSAGE_TEXT, payload)
|
||||
if raw is True:
|
||||
return raw
|
||||
return self.prepare_object(Message.de_json(raw))
|
||||
return self.prepare_object(types.Message.de_json(raw))
|
||||
|
||||
async def edit_message_caption(self, chat_id=None, message_id=None, inline_message_id=None, caption=None,
|
||||
reply_markup=None):
|
||||
reply_markup=None) -> types.Message or bool:
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
||||
|
|
@ -319,12 +311,13 @@ class AIOGramBot:
|
|||
inline_message_id = inline_message_id.message_id
|
||||
|
||||
payload = generate_payload(**locals())
|
||||
raw = await self.request(ApiMethods.EDIT_MESSAGE_TEXT, payload)
|
||||
raw = await self.request(api.ApiMethods.EDIT_MESSAGE_TEXT, payload)
|
||||
if raw is True:
|
||||
return raw
|
||||
return self.prepare_object(Message.de_json(raw))
|
||||
return self.prepare_object(types.Message.de_json(raw))
|
||||
|
||||
async def edit_message_reply_markup(self, chat_id=None, message_id=None, inline_message_id=None, reply_markup=None):
|
||||
async def edit_message_reply_markup(self, chat_id=None, message_id=None, inline_message_id=None,
|
||||
reply_markup=None) -> types.Message or bool:
|
||||
if reply_markup and hasattr(reply_markup, 'to_json'):
|
||||
reply_markup = json.dumps(reply_markup.to_json())
|
||||
|
||||
|
|
@ -335,13 +328,13 @@ class AIOGramBot:
|
|||
inline_message_id = inline_message_id.message_id
|
||||
|
||||
payload = generate_payload(**locals())
|
||||
raw = await self.request(ApiMethods.EDIT_MESSAGE_TEXT, payload)
|
||||
raw = await self.request(api.ApiMethods.EDIT_MESSAGE_TEXT, payload)
|
||||
if raw is True:
|
||||
return raw
|
||||
return self.prepare_object(Message.de_json(raw))
|
||||
return self.prepare_object(types.Message.de_json(raw))
|
||||
|
||||
async def delete_message(self, chat_id, message_id):
|
||||
async def delete_message(self, chat_id, message_id) -> bool:
|
||||
payload = generate_payload(**locals())
|
||||
|
||||
await self.request(ApiMethods.DELETE_MESSAGE, payload)
|
||||
await self.request(api.ApiMethods.DELETE_MESSAGE, payload)
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ class ValidationError(Exception):
|
|||
class TelegramAPIError(Exception):
|
||||
def __init__(self, message, method, status, body):
|
||||
super(TelegramAPIError, self).__init__(
|
||||
f"A request to the Telegram API was unsuccessful (Status code: {status}). {message}")
|
||||
f"A request to the Telegram API was unsuccessful.\n{message}")
|
||||
self.method = method
|
||||
self.status = status
|
||||
self.body = body
|
||||
|
|
|
|||
|
|
@ -1,107 +1,75 @@
|
|||
import datetime
|
||||
import json
|
||||
import time
|
||||
from .animation import Animation
|
||||
from .audio import Audio
|
||||
from .callback_query import CallbackQuery
|
||||
from .chat import Chat
|
||||
from .chat_member import ChatMember
|
||||
from .chosen_inline_result import ChosenInlineResult
|
||||
from .contact import Contact
|
||||
from .document import Document
|
||||
from .file import File
|
||||
from .force_reply import ForceReply
|
||||
from .game import Game
|
||||
from .game_high_score import GameHighScore
|
||||
from .inline_keyboard import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from .inline_query import InlineQuery
|
||||
from .invoice import Invoice
|
||||
from .location import Location
|
||||
from .message import Message
|
||||
from .message_entity import MessageEntity
|
||||
from .order_info import OrderInfo
|
||||
from .photo_size import PhotoSize
|
||||
from .pre_checkout_query import PreCheckoutQuery
|
||||
from .reply_keyboard import KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove
|
||||
from .shipping_address import ShippingAddress
|
||||
from .shipping_query import ShippingQuery
|
||||
from .sticker import Sticker
|
||||
from .successful_payment import SuccessfulPayment
|
||||
from .update import Update
|
||||
from .user import User
|
||||
from .user_profile_photos import UserProfilePhotos
|
||||
from .venue import Venue
|
||||
from .video import Video
|
||||
from .video_note import VideoNote
|
||||
from .voice import Voice
|
||||
from .webhook_info import WebhookInfo
|
||||
|
||||
|
||||
def deserialize(deserializable, data):
|
||||
if data:
|
||||
return deserializable.de_json(data)
|
||||
|
||||
|
||||
def deserialize_array(deserializable, array):
|
||||
if array:
|
||||
return [deserialize(deserializable, item) for item in array]
|
||||
|
||||
|
||||
class Serializable:
|
||||
def to_json(self):
|
||||
"""
|
||||
Returns a JSON string representation of this class.
|
||||
|
||||
This function must be overridden by subclasses.
|
||||
:return: a JSON formatted string.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Deserializable:
|
||||
"""
|
||||
Subclasses of this class are guaranteed to be able to be created from a json-style dict or json formatted string.
|
||||
All subclasses of this class must override de_json.
|
||||
"""
|
||||
|
||||
def to_json(self):
|
||||
result = {}
|
||||
for name, attr in self.__dict__.items():
|
||||
if not attr or name == '_bot':
|
||||
continue
|
||||
if hasattr(attr, 'to_json'):
|
||||
attr = getattr(attr, 'to_json')()
|
||||
elif isinstance(attr, datetime.datetime):
|
||||
attr = int(time.mktime(attr.timetuple()))
|
||||
result[name] = attr
|
||||
return result
|
||||
|
||||
@property
|
||||
def bot(self):
|
||||
if not hasattr(self, '_bot'):
|
||||
raise AttributeError(f"{self.__class__.__name__} is not configured.")
|
||||
return getattr(self, '_bot')
|
||||
|
||||
@bot.setter
|
||||
def bot(self, bot):
|
||||
setattr(self, '_bot', bot)
|
||||
for name, attr in self.__dict__.items():
|
||||
if hasattr(attr, 'de_json'):
|
||||
attr.bot = bot
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
return getattr(self, '_parent', None)
|
||||
|
||||
@parent.setter
|
||||
def parent(self, value):
|
||||
setattr(self, '_parent', value)
|
||||
for name, attr in self.__dict__.items():
|
||||
if name.startswith('_'):
|
||||
continue
|
||||
if hasattr(attr, 'de_json'):
|
||||
attr.parent = self
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, raw_data):
|
||||
"""
|
||||
Returns an instance of this class from the given json dict or string.
|
||||
|
||||
This function must be overridden by subclasses.
|
||||
:return: an instance of this class created from the given json dict or string.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def check_json(raw_data) -> dict:
|
||||
"""
|
||||
Checks whether json_type is a dict or a string. If it is already a dict, it is returned as-is.
|
||||
If it is not, it is converted to a dict by means of json.loads(json_type)
|
||||
:param raw_data:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if isinstance(raw_data, dict):
|
||||
return raw_data
|
||||
elif isinstance(raw_data, str):
|
||||
return json.loads(raw_data)
|
||||
else:
|
||||
raise ValueError("data should be a json dict or string.")
|
||||
|
||||
def __str__(self):
|
||||
return json.dumps(self.to_json())
|
||||
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
|
||||
@classmethod
|
||||
def deserialize(cls, obj):
|
||||
if isinstance(obj, list):
|
||||
return deserialize_array(cls, obj)
|
||||
return deserialize(cls, obj)
|
||||
__all__ = [
|
||||
'Animation',
|
||||
'Audio',
|
||||
'Base',
|
||||
'CallbackQuery',
|
||||
'Chat',
|
||||
'ChatMember',
|
||||
'ChosenInlineResult',
|
||||
'Contact',
|
||||
'Document',
|
||||
'File',
|
||||
'ForceReply',
|
||||
'Game',
|
||||
'GameHighScore',
|
||||
'InlineKeyboardButton',
|
||||
'InlineKeyboardMarkup',
|
||||
'InlineQuery',
|
||||
'Invoice',
|
||||
'Location',
|
||||
'Message',
|
||||
'MessageEntity',
|
||||
'OrderInfo',
|
||||
'PhotoSize',
|
||||
'PreCheckoutQuery',
|
||||
'KeyboardButton',
|
||||
'ReplyKeyboardMarkup',
|
||||
'ReplyKeyboardRemove',
|
||||
'ShippingAddress',
|
||||
'ShippingQuery',
|
||||
'Sticker',
|
||||
'SuccessfulPayment',
|
||||
'Update',
|
||||
'User',
|
||||
'UserProfilePhotos',
|
||||
'Venue',
|
||||
'Video',
|
||||
'VideoNote',
|
||||
'Voice',
|
||||
'WebhookInfo'
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .photo_size import PhotoSize
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
|
||||
|
||||
class Audio(Deserializable):
|
||||
|
|
|
|||
107
aiogram/types/base.py
Normal file
107
aiogram/types/base.py
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import datetime
|
||||
import json
|
||||
import time
|
||||
|
||||
|
||||
def deserialize(deserializable, data):
|
||||
if data:
|
||||
return deserializable.de_json(data)
|
||||
|
||||
|
||||
def deserialize_array(deserializable, array):
|
||||
if array:
|
||||
return [deserialize(deserializable, item) for item in array]
|
||||
|
||||
|
||||
class Serializable:
|
||||
def to_json(self):
|
||||
"""
|
||||
Returns a JSON string representation of this class.
|
||||
|
||||
This function must be overridden by subclasses.
|
||||
:return: a JSON formatted string.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Deserializable:
|
||||
"""
|
||||
Subclasses of this class are guaranteed to be able to be created from a json-style dict or json formatted string.
|
||||
All subclasses of this class must override de_json.
|
||||
"""
|
||||
|
||||
def to_json(self):
|
||||
result = {}
|
||||
for name, attr in self.__dict__.items():
|
||||
if not attr or name == '_bot':
|
||||
continue
|
||||
if hasattr(attr, 'to_json'):
|
||||
attr = getattr(attr, 'to_json')()
|
||||
elif isinstance(attr, datetime.datetime):
|
||||
attr = int(time.mktime(attr.timetuple()))
|
||||
result[name] = attr
|
||||
return result
|
||||
|
||||
@property
|
||||
def bot(self):
|
||||
if not hasattr(self, '_bot'):
|
||||
raise AttributeError(f"{self.__class__.__name__} is not configured.")
|
||||
return getattr(self, '_bot')
|
||||
|
||||
@bot.setter
|
||||
def bot(self, bot):
|
||||
setattr(self, '_bot', bot)
|
||||
for name, attr in self.__dict__.items():
|
||||
if hasattr(attr, 'de_json'):
|
||||
attr.bot = bot
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
return getattr(self, '_parent', None)
|
||||
|
||||
@parent.setter
|
||||
def parent(self, value):
|
||||
setattr(self, '_parent', value)
|
||||
for name, attr in self.__dict__.items():
|
||||
if name.startswith('_'):
|
||||
continue
|
||||
if hasattr(attr, 'de_json'):
|
||||
attr.parent = self
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, raw_data):
|
||||
"""
|
||||
Returns an instance of this class from the given json dict or string.
|
||||
|
||||
This function must be overridden by subclasses.
|
||||
:return: an instance of this class created from the given json dict or string.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def check_json(raw_data) -> dict:
|
||||
"""
|
||||
Checks whether json_type is a dict or a string. If it is already a dict, it is returned as-is.
|
||||
If it is not, it is converted to a dict by means of json.loads(json_type)
|
||||
:param raw_data:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if isinstance(raw_data, dict):
|
||||
return raw_data
|
||||
elif isinstance(raw_data, str):
|
||||
return json.loads(raw_data)
|
||||
else:
|
||||
raise ValueError("data should be a json dict or string.")
|
||||
|
||||
def __str__(self):
|
||||
return json.dumps(self.to_json())
|
||||
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
|
||||
@classmethod
|
||||
def deserialize(cls, obj):
|
||||
if isinstance(obj, list):
|
||||
return deserialize_array(cls, obj)
|
||||
return deserialize(cls, obj)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .message import Message
|
||||
from .user import User
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
|
||||
|
||||
class Chat(Deserializable):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .user import User
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .location import Location
|
||||
from .user import User
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
|
||||
|
||||
class Contact(Deserializable):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .photo_size import PhotoSize
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
|
||||
|
||||
class File(Deserializable):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from aiogram.types import Serializable
|
||||
from .base import Serializable
|
||||
|
||||
|
||||
class ForceReply(Serializable):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from . import Deserializable
|
||||
from .animation import Animation
|
||||
from .base import Deserializable
|
||||
from .message_entity import MessageEntity
|
||||
from .photo_size import PhotoSize
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .user import User
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Serializable
|
||||
from .base import Serializable
|
||||
|
||||
|
||||
class InlineKeyboardMarkup(Serializable):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .location import Location
|
||||
from .user import User
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
|
||||
|
||||
class Invoice(Deserializable):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
|
||||
|
||||
class Location(Deserializable):
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import datetime
|
||||
|
||||
from aiogram.exceptions import TelegramAPIError
|
||||
from . import Deserializable
|
||||
from .audio import Audio
|
||||
from .base import Deserializable
|
||||
from .chat import Chat
|
||||
from .contact import Contact
|
||||
from .document import Document
|
||||
|
|
@ -18,6 +17,7 @@ from .venue import Venue
|
|||
from .video import Video
|
||||
from .video_note import VideoNote
|
||||
from .voice import Voice
|
||||
from ..exceptions import TelegramAPIError
|
||||
|
||||
|
||||
class Message(Deserializable):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .user import User
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .shipping_address import ShippingAddress
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable, deserialize
|
||||
from .base import deserialize, Deserializable
|
||||
|
||||
|
||||
class PhotoSize(Deserializable):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .order_info import OrderInfo
|
||||
from .user import User
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Serializable
|
||||
from .base import Serializable
|
||||
|
||||
|
||||
class ReplyKeyboardMarkup(Serializable):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
|
||||
|
||||
class ShippingAddress(Deserializable):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .shipping_address import ShippingAddress
|
||||
from .user import User
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .photo_size import PhotoSize
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .order_info import OrderInfo
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
from aiogram.types.callback_query import CallbackQuery
|
||||
from aiogram.types.chosen_inline_result import ChosenInlineResult
|
||||
from aiogram.types.inline_query import InlineQuery
|
||||
from aiogram.types.pre_checkout_query import PreCheckoutQuery
|
||||
from aiogram.types.shipping_query import ShippingQuery
|
||||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .callback_query import CallbackQuery
|
||||
from .chosen_inline_result import ChosenInlineResult
|
||||
from .inline_query import InlineQuery
|
||||
from .message import Message
|
||||
from .pre_checkout_query import PreCheckoutQuery
|
||||
from .shipping_query import ShippingQuery
|
||||
|
||||
|
||||
class Update(Deserializable):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import babel
|
||||
|
||||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
|
||||
|
||||
class User(Deserializable):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .photo_size import PhotoSize
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .location import Location
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .photo_size import PhotoSize
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
from .photo_size import PhotoSize
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
|
||||
|
||||
class Voice(Deserializable):
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import datetime
|
||||
|
||||
from . import Deserializable
|
||||
from .base import Deserializable
|
||||
|
||||
|
||||
class WebhookInfo(Deserializable):
|
||||
def __init__(self, url, has_custom_certificate, pending_update_count, last_error_date, last_error_message, max_connections, allowed_updates):
|
||||
def __init__(self, url, has_custom_certificate, pending_update_count, last_error_date, last_error_message,
|
||||
max_connections, allowed_updates):
|
||||
self.url: str = url
|
||||
self.has_custom_certificate: bool = has_custom_certificate
|
||||
self.pending_update_count: int = pending_update_count
|
||||
|
|
@ -29,4 +30,5 @@ class WebhookInfo(Deserializable):
|
|||
max_connections = raw_data.get('max_connections')
|
||||
allowed_updates = raw_data.get('allowed_updates')
|
||||
|
||||
return WebhookInfo(url, has_custom_certificate, pending_update_count, last_error_date, last_error_message, max_connections, allowed_updates)
|
||||
return WebhookInfo(url, has_custom_certificate, pending_update_count, last_error_date, last_error_message,
|
||||
max_connections, allowed_updates)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue