mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Merge remote-tracking branch 'upstream/dev-1.x' into dev-1.x
# Conflicts: # aiogram/types/user.py - update hashing in user type
This commit is contained in:
commit
19f67a2e99
24 changed files with 245 additions and 89 deletions
|
|
@ -2,6 +2,7 @@ from . import base
|
|||
from . import fields
|
||||
from .animation import Animation
|
||||
from .audio import Audio
|
||||
from .auth_widget_data import AuthWidgetData
|
||||
from .callback_game import CallbackGame
|
||||
from .callback_query import CallbackQuery
|
||||
from .chat import Chat, ChatActions, ChatType
|
||||
|
|
@ -56,6 +57,7 @@ __all__ = (
|
|||
'AllowedUpdates',
|
||||
'Animation',
|
||||
'Audio',
|
||||
'AuthWidgetData',
|
||||
'CallbackGame',
|
||||
'CallbackQuery',
|
||||
'Chat',
|
||||
|
|
|
|||
|
|
@ -15,11 +15,3 @@ class Audio(base.TelegramObject, mixins.Downloadable):
|
|||
title: base.String = fields.Field()
|
||||
mime_type: base.String = fields.Field()
|
||||
file_size: base.Integer = fields.Field()
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.file_id) + \
|
||||
self.duration + \
|
||||
hash(self.performer) + \
|
||||
hash(self.title) + \
|
||||
hash(self.mime_type) + \
|
||||
self.file_size
|
||||
|
|
|
|||
47
aiogram/types/auth_widget_data.py
Normal file
47
aiogram/types/auth_widget_data.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
from aiohttp import web
|
||||
|
||||
from . import base
|
||||
from . import fields
|
||||
|
||||
|
||||
class AuthWidgetData(base.TelegramObject):
|
||||
id: base.Integer = fields.Field()
|
||||
first_name: base.String = fields.Field()
|
||||
last_name: base.String = fields.Field()
|
||||
username: base.String = fields.Field()
|
||||
photo_url: base.String = fields.Field()
|
||||
auth_date: base.String = fields.DateTimeField()
|
||||
hash: base.String = fields.Field()
|
||||
|
||||
@classmethod
|
||||
def parse(cls, request: web.Request) -> 'AuthWidgetData':
|
||||
"""
|
||||
Parse request as Telegram auth widget data.
|
||||
|
||||
:param request:
|
||||
:return: :obj:`AuthWidgetData`
|
||||
:raise :obj:`aiohttp.web.HTTPBadRequest`
|
||||
"""
|
||||
try:
|
||||
query = dict(request.query)
|
||||
query['id'] = int(query['id'])
|
||||
query['auth_date'] = int(query['auth_date'])
|
||||
widget = AuthWidgetData(**query)
|
||||
except (ValueError, KeyError):
|
||||
raise web.HTTPBadRequest(text='Invalid auth data')
|
||||
else:
|
||||
return widget
|
||||
|
||||
def validate(self):
|
||||
return self.bot.check_auth_widget(self.to_python())
|
||||
|
||||
@property
|
||||
def full_name(self):
|
||||
result = self.first_name
|
||||
if self.last_name:
|
||||
result += ' '
|
||||
result += self.last_name
|
||||
return result
|
||||
|
||||
def __hash__(self):
|
||||
return self.id
|
||||
|
|
@ -244,3 +244,28 @@ class TelegramObject(metaclass=MetaTelegramObject):
|
|||
"""
|
||||
for _, value in self:
|
||||
yield value
|
||||
|
||||
def __hash__(self):
|
||||
def _hash(obj):
|
||||
buf = 0
|
||||
if isinstance(obj, list):
|
||||
for item in obj:
|
||||
buf += _hash(item)
|
||||
elif isinstance(obj, dict):
|
||||
for dict_key, dict_value in obj.items():
|
||||
buf += hash(dict_key) + _hash(dict_value)
|
||||
else:
|
||||
try:
|
||||
buf += hash(obj)
|
||||
except TypeError: # Skip unhashable objects
|
||||
pass
|
||||
return buf
|
||||
|
||||
result = 0
|
||||
for key, value in sorted(self.values.items()):
|
||||
result += hash(key) + _hash(value)
|
||||
|
||||
return result
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, self.__class__) and hash(other) == hash(self)
|
||||
|
|
|
|||
|
|
@ -56,3 +56,6 @@ class CallbackQuery(base.TelegramObject):
|
|||
:rtype: :obj:`base.Boolean`"""
|
||||
await self.bot.answer_callback_query(callback_query_id=self.id, text=text,
|
||||
show_alert=show_alert, url=url, cache_time=cache_time)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.id)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ class Chat(base.TelegramObject):
|
|||
sticker_set_name: base.String = fields.Field()
|
||||
can_set_sticker_set: base.Boolean = fields.Field()
|
||||
|
||||
def __hash__(self):
|
||||
return self.id
|
||||
|
||||
@property
|
||||
def full_name(self):
|
||||
if self.type == ChatType.PRIVATE:
|
||||
|
|
|
|||
|
|
@ -73,3 +73,6 @@ class ChatPhoto(base.TelegramObject):
|
|||
|
||||
async def get_big_file(self):
|
||||
return await self.bot.get_file(self.big_file_id)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.small_file_id) + hash(self.big_file_id)
|
||||
|
|
|
|||
|
|
@ -19,3 +19,6 @@ class Contact(base.TelegramObject):
|
|||
if self.last_name is not None:
|
||||
name += ' ' + self.last_name
|
||||
return name
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.phone_number)
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ class Message(base.TelegramObject):
|
|||
return text
|
||||
|
||||
async def reply(self, text, parse_mode=None, disable_web_page_preview=None,
|
||||
disable_notification=None, reply_markup=None, reply=False) -> 'Message':
|
||||
disable_notification=None, reply_markup=None, reply=True) -> 'Message':
|
||||
"""
|
||||
Reply to this message
|
||||
|
||||
|
|
@ -630,6 +630,30 @@ class Message(base.TelegramObject):
|
|||
"""
|
||||
return await self.bot.delete_message(self.chat.id, self.message_id)
|
||||
|
||||
async def reply_sticker(self, sticker: typing.Union[base.InputFile, base.String],
|
||||
disable_notification: typing.Union[base.Boolean, None] = None,
|
||||
reply_markup=None, reply=True) -> 'Message':
|
||||
"""
|
||||
Use this method to send .webp stickers.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#sendsticker
|
||||
|
||||
:param sticker: Sticker to send.
|
||||
:type sticker: :obj:`typing.Union[base.InputFile, base.String]`
|
||||
:param disable_notification: Sends the message silently. Users will receive a notification with no sound.
|
||||
:type disable_notification: :obj:`typing.Union[base.Boolean, None]`
|
||||
:param reply_markup: Additional interface options.
|
||||
:type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup,
|
||||
types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]`
|
||||
:param reply: fill 'reply_to_message_id'
|
||||
:return: On success, the sent Message is returned.
|
||||
:rtype: :obj:`types.Message`
|
||||
"""
|
||||
return await self.bot.send_sticker(chat_id=self.chat.id, sticker=sticker,
|
||||
disable_notification=disable_notification,
|
||||
reply_to_message_id=self.message_id if reply else None,
|
||||
reply_markup=reply_markup)
|
||||
|
||||
async def pin(self, disable_notification: bool = False):
|
||||
"""
|
||||
Pin message
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ class MessageEntity(base.TelegramObject):
|
|||
|
||||
def _apply(self, text, func):
|
||||
return text[:self.offset] + \
|
||||
func(text[self.offset:self.offset + self.length]) + \
|
||||
text[self.offset + self.length:]
|
||||
func(text[self.offset:self.offset + self.length]) + \
|
||||
text[self.offset + self.length:]
|
||||
|
||||
def apply_md(self, text):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -44,3 +44,6 @@ class Downloadable:
|
|||
return self
|
||||
else:
|
||||
return await self.bot.get_file(self.file_id)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.file_id)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
from . import base
|
||||
from . import fields
|
||||
from . import mixins
|
||||
from .mask_position import MaskPosition
|
||||
from .photo_size import PhotoSize
|
||||
|
||||
|
||||
class Sticker(base.TelegramObject):
|
||||
class Sticker(base.TelegramObject, mixins.Downloadable):
|
||||
"""
|
||||
This object represents a sticker.
|
||||
|
||||
|
|
@ -18,11 +19,3 @@ class Sticker(base.TelegramObject):
|
|||
set_name: base.String = fields.Field()
|
||||
mask_position: MaskPosition = fields.Field(base=MaskPosition)
|
||||
file_size: base.Integer = fields.Field()
|
||||
|
||||
def __hash__(self):
|
||||
return self.file_id
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, type(self)):
|
||||
return other.file_id == self.file_id
|
||||
return self.file_id == other
|
||||
|
|
|
|||
|
|
@ -79,10 +79,7 @@ class User(base.TelegramObject):
|
|||
return await self.bot.get_user_profile_photos(self.id, offset, limit)
|
||||
|
||||
def __hash__(self):
|
||||
return self.id + \
|
||||
hash(self.is_bot) + \
|
||||
hash(self.full_name) + \
|
||||
(hash(self.username) if self.username else 0)
|
||||
return self.id
|
||||
|
||||
def __int__(self):
|
||||
return self.id
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
from . import base
|
||||
from . import fields
|
||||
from . import mixins
|
||||
from .photo_size import PhotoSize
|
||||
|
||||
|
||||
class Video(base.TelegramObject):
|
||||
class Video(base.TelegramObject, mixins.Downloadable):
|
||||
"""
|
||||
This object represents a video file.
|
||||
|
||||
|
|
@ -16,11 +17,3 @@ class Video(base.TelegramObject):
|
|||
thumb: PhotoSize = fields.Field(base=PhotoSize)
|
||||
mime_type: base.String = fields.Field()
|
||||
file_size: base.Integer = fields.Field()
|
||||
|
||||
def __hash__(self):
|
||||
return self.file_id
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, type(self)):
|
||||
return other.file_id == self.file_id
|
||||
return self.file_id == other
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
from . import base
|
||||
from . import fields
|
||||
from . import mixins
|
||||
from .photo_size import PhotoSize
|
||||
|
||||
|
||||
class VideoNote(base.TelegramObject):
|
||||
class VideoNote(base.TelegramObject, mixins.Downloadable):
|
||||
"""
|
||||
This object represents a video message (available in Telegram apps as of v.4.0).
|
||||
|
||||
|
|
@ -14,11 +15,3 @@ class VideoNote(base.TelegramObject):
|
|||
duration: base.Integer = fields.Field()
|
||||
thumb: PhotoSize = fields.Field(base=PhotoSize)
|
||||
file_size: base.Integer = fields.Field()
|
||||
|
||||
def __hash__(self):
|
||||
return self.file_id
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, type(self)):
|
||||
return other.file_id == self.file_id
|
||||
return self.file_id == other
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
from . import base
|
||||
from . import fields
|
||||
from . import mixins
|
||||
|
||||
|
||||
class Voice(base.TelegramObject):
|
||||
class Voice(base.TelegramObject, mixins.Downloadable):
|
||||
"""
|
||||
This object represents a voice note.
|
||||
|
||||
|
|
@ -12,11 +13,3 @@ class Voice(base.TelegramObject):
|
|||
duration: base.Integer = fields.Field()
|
||||
mime_type: base.String = fields.Field()
|
||||
file_size: base.Integer = fields.Field()
|
||||
|
||||
def __hash__(self):
|
||||
return self.file_id
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, type(self)):
|
||||
return other.file_id == self.file_id
|
||||
return self.file_id == other
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue