Merge branch 'dev-2.x'

# Conflicts:
#	README.md
#	README.rst
#	aiogram/__init__.py
#	aiogram/bot/api.py
#	docs/source/index.rst
This commit is contained in:
Alex Root Junior 2020-04-26 00:26:35 +03:00
commit 52c76f53c7
11 changed files with 137 additions and 17 deletions

View file

@ -6,7 +6,7 @@
[![PyPi status](https://img.shields.io/pypi/status/aiogram.svg?style=flat-square)](https://pypi.python.org/pypi/aiogram)
[![Downloads](https://img.shields.io/pypi/dm/aiogram.svg?style=flat-square)](https://pypi.python.org/pypi/aiogram)
[![Supported python versions](https://img.shields.io/pypi/pyversions/aiogram.svg?style=flat-square)](https://pypi.python.org/pypi/aiogram)
[![Telegram Bot API](https://img.shields.io/badge/Telegram%20Bot%20API-4.7-blue.svg?style=flat-square&logo=telegram)](https://core.telegram.org/bots/api)
[![Telegram Bot API](https://img.shields.io/badge/Telegram%20Bot%20API-4.8-blue.svg?style=flat-square&logo=telegram)](https://core.telegram.org/bots/api)
[![Documentation Status](https://img.shields.io/readthedocs/aiogram?style=flat-square)](http://docs.aiogram.dev/en/latest/?badge=latest)
[![Github issues](https://img.shields.io/github/issues/aiogram/aiogram.svg?style=flat-square)](https://github.com/aiogram/aiogram/issues)
[![MIT License](https://img.shields.io/pypi/l/aiogram.svg?style=flat-square)](https://opensource.org/licenses/MIT)

View file

@ -21,7 +21,7 @@ AIOGramBot
:target: https://pypi.python.org/pypi/aiogram
:alt: Supported python versions
.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-4.7-blue.svg?style=flat-square&logo=telegram
.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-4.8-blue.svg?style=flat-square&logo=telegram
:target: https://core.telegram.org/bots/api
:alt: Telegram Bot API

View file

@ -38,5 +38,5 @@ __all__ = [
'utils'
]
__version__ = '2.7'
__api_version__ = '4.7'
__version__ = '2.8'
__api_version__ = '4.8'

View file

@ -153,7 +153,7 @@ class Methods(Helper):
"""
Helper for Telegram API Methods listed on https://core.telegram.org/bots/api
List is updated to Bot API 4.7
List is updated to Bot API 4.8
"""
mode = HelperMode.lowerCamelCase

View file

@ -870,6 +870,11 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
type: typing.Optional[base.String] = None,
allows_multiple_answers: typing.Optional[base.Boolean] = None,
correct_option_id: typing.Optional[base.Integer] = None,
explanation: typing.Optional[base.String] = None,
explanation_parse_mode: typing.Optional[base.String] = None,
open_period: typing.Union[base.Integer, None] = None,
close_date: typing.Union[
base.Integer, datetime.datetime, datetime.timedelta, None] = None,
is_closed: typing.Optional[base.Boolean] = None,
disable_notification: typing.Optional[base.Boolean] = None,
reply_to_message_id: typing.Optional[base.Integer] = None,
@ -888,17 +893,25 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
:param question: Poll question, 1-255 characters
:type question: :obj:`base.String`
:param options: List of answer options, 2-10 strings 1-100 characters each
:param options: :obj:`typing.List[base.String]`
:type options: :obj:`typing.List[base.String]`
:param is_anonymous: True, if the poll needs to be anonymous, defaults to True
:param is_anonymous: :obj:`typing.Optional[base.Boolean]`
:type is_anonymous: :obj:`typing.Optional[base.Boolean]`
:param type: Poll type, quiz or regular, defaults to regular
:param type: :obj:`typing.Optional[base.String]`
:type type: :obj:`typing.Optional[base.String]`
:param allows_multiple_answers: True, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to False
:param allows_multiple_answers: :obj:`typing.Optional[base.Boolean]`
:type allows_multiple_answers: :obj:`typing.Optional[base.Boolean]`
:param correct_option_id: 0-based identifier of the correct answer option, required for polls in quiz mode
:param correct_option_id: :obj:`typing.Optional[base.Integer]`
:type correct_option_id: :obj:`typing.Optional[base.Integer]`
:param explanation: Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing
:type explanation: :obj:`typing.Optional[base.String]`
:param explanation_parse_mode: Mode for parsing entities in the explanation. See formatting options for more details.
:type explanation_parse_mode: :obj:`typing.Optional[base.String]`
:param open_period: Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with close_date.
:type open_period: :obj:`typing.Union[base.Integer, None]`
:param close_date: Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with open_period.
:type close_date: :obj:`typing.Union[base.Integer, datetime.datetime, datetime.timedelta, None]`
:param is_closed: Pass True, if the poll needs to be immediately closed
:param is_closed: :obj:`typing.Optional[base.Boolean]`
:type is_closed: :obj:`typing.Optional[base.Boolean]`
:param disable_notification: Sends the message silently. Users will receive a notification with no sound.
:type disable_notification: :obj:`typing.Optional[Boolean]`
:param reply_to_message_id: If the message is a reply, ID of the original message
@ -911,13 +924,18 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
:rtype: :obj:`types.Message`
"""
options = prepare_arg(options)
open_period = prepare_arg(open_period)
close_date = prepare_arg(close_date)
payload = generate_payload(**locals())
if self.parse_mode:
payload.setdefault('explanation_parse_mode', self.parse_mode)
result = await self.request(api.Methods.SEND_POLL, payload)
return types.Message(**result)
async def send_dice(self, chat_id: typing.Union[base.Integer, base.String],
disable_notification: typing.Union[base.Boolean, None] = None,
emoji: typing.Union[base.String, None] = None,
reply_to_message_id: typing.Union[base.Integer, None] = None,
reply_markup: typing.Union[types.InlineKeyboardMarkup,
types.ReplyKeyboardMarkup,
@ -933,6 +951,8 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
:param chat_id: Unique identifier for the target chat or username of the target channel
:type chat_id: :obj:`typing.Union[base.Integer, base.String]`
:param emoji: Emoji on which the dice throw animation is based. Currently, must be one of 🎲 or 🎯. Defauts to 🎲
:type emoji: :obj:`typing.Union[base.String, None]`
: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_to_message_id: If the message is a reply, ID of the original message

View file

@ -182,7 +182,7 @@ class WebhookRequestHandler(web.View):
try:
try:
await waiter
except asyncio.futures.CancelledError:
except asyncio.CancelledError:
fut.remove_done_callback(cb)
fut.cancel()
raise

View file

@ -12,7 +12,7 @@ from .chat_permissions import ChatPermissions
from .chat_photo import ChatPhoto
from .chosen_inline_result import ChosenInlineResult
from .contact import Contact
from .dice import Dice
from .dice import Dice, DiceEmoji
from .document import Document
from .encrypted_credentials import EncryptedCredentials
from .encrypted_passport_element import EncryptedPassportElement
@ -85,6 +85,7 @@ __all__ = (
'ContentType',
'ContentTypes',
'Dice',
'DiceEmoji',
'Document',
'EncryptedCredentials',
'EncryptedPassportElement',

View file

@ -9,5 +9,10 @@ class Dice(base.TelegramObject):
https://core.telegram.org/bots/api#dice
"""
emoji: base.String = fields.Field()
value: base.Integer = fields.Field()
class DiceEmoji:
DICE = '🎲'
DART = '🎯'

View file

@ -150,7 +150,6 @@ class Message(base.TelegramObject):
if self.passport_data:
return ContentType.PASSPORT_DATA
return ContentType.UNKNOWN
def is_command(self):
@ -810,6 +809,39 @@ class Message(base.TelegramObject):
reply_to_message_id=self.message_id if reply else None,
reply_markup=reply_markup)
async def answer_dice(self, emoji: typing.Union[base.String, None] = None,
disable_notification: typing.Union[base.Boolean, None] = None,
reply_markup: typing.Union[InlineKeyboardMarkup,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
ForceReply, None] = None,
reply: base.Boolean = False) -> Message:
"""
Use this method to send a dice, which will have a random value from 1 to 6.
On success, the sent Message is returned.
(Yes, we're aware of the “proper” singular of die.
But it's awkward, and we decided to help it change. One dice at a time!)
Source: https://core.telegram.org/bots/api#senddice
:param emoji: Emoji on which the dice throw animation is based. Currently, must be one of 🎲 or 🎯. Defauts to 🎲
:type emoji: :obj:`typing.Union[base.String, None]`
: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. A JSON-serialized object for an inline keyboard,
custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user
: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_dice(chat_id=self.chat.id,
disable_notification=disable_notification,
emoji=emoji,
reply_to_message_id=self.message_id if reply else None,
reply_markup=reply_markup)
async def reply(self, text: base.String,
parse_mode: typing.Union[base.String, None] = None,
disable_web_page_preview: typing.Union[base.Boolean, None] = None,
@ -1352,6 +1384,38 @@ class Message(base.TelegramObject):
reply_to_message_id=self.message_id if reply else None,
reply_markup=reply_markup)
async def reply_dice(self, emoji: typing.Union[base.String, None] = None,
disable_notification: typing.Union[base.Boolean, None] = None,
reply_markup: typing.Union[InlineKeyboardMarkup,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
ForceReply, None] = None,
reply: base.Boolean = True) -> Message:
"""
Use this method to send a dice, which will have a random value from 1 to 6.
On success, the sent Message is returned.
(Yes, we're aware of the “proper” singular of die.
But it's awkward, and we decided to help it change. One dice at a time!)
Source: https://core.telegram.org/bots/api#senddice
:param emoji: Emoji on which the dice throw animation is based. Currently, must be one of 🎲 or 🎯. Defauts to 🎲
:type emoji: :obj:`typing.Union[base.String, None]`
: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. A JSON-serialized object for an inline keyboard,
custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user
: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_dice(chat_id=self.chat.id,
disable_notification=disable_notification,
reply_to_message_id=self.message_id if reply else None,
reply_markup=reply_markup)
async def forward(self, chat_id: typing.Union[base.Integer, base.String],
disable_notification: typing.Union[base.Boolean, None] = None) -> Message:
"""

View file

@ -1,8 +1,11 @@
import datetime
import typing
from ..utils import helper
from . import base, fields
from .message_entity import MessageEntity
from .user import User
from ..utils import helper
from ..utils.text_decorations import html_decoration, markdown_decoration
class PollOption(base.TelegramObject):
@ -44,6 +47,33 @@ class Poll(base.TelegramObject):
type: base.String = fields.Field()
allows_multiple_answers: base.Boolean = fields.Field()
correct_option_id: base.Integer = fields.Field()
explanation: base.String = fields.Field()
explanation_entities: base.String = fields.ListField(base=MessageEntity)
open_period: base.Integer = fields.Field()
close_date: datetime.datetime = fields.DateTimeField()
def parse_entities(self, as_html=True):
text_decorator = html_decoration if as_html else markdown_decoration
return text_decorator.unparse(self.explanation or '', self.explanation_entities or [])
@property
def md_explanation(self) -> str:
"""
Explanation formatted as markdown.
:return: str
"""
return self.parse_entities(False)
@property
def html_explanation(self) -> str:
"""
Explanation formatted as HTML
:return: str
"""
return self.parse_entities()
class PollType(helper.Helper):

View file

@ -22,7 +22,7 @@ Welcome to aiogram's documentation!
:target: https://pypi.python.org/pypi/aiogram
:alt: Supported python versions
.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-4.7-blue.svg?style=flat-square&logo=telegram
.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-4.8-blue.svg?style=flat-square&logo=telegram
:target: https://core.telegram.org/bots/api
:alt: Telegram Bot API