Identify edited methods (new or deprecated parameters) in addition to new methods.

This commit is contained in:
2020-11-16 15:36:25 +01:00
parent 15a7a58537
commit a3cc676432
2 changed files with 169 additions and 35 deletions

View File

@@ -1464,3 +1464,75 @@ class TelegramBot:
'setStickerSetThumb',
parameters=locals()
)
async def logOut(self):
"""Log out from the cloud Bot API server.
Use this method to log out from the cloud Bot API server
before launching the bot locally.
You must log out the bot before running it locally, otherwise there
is no guarantee that the bot will receive updates.
After a successful call, you can immediately log in on a local server,
but will not be able to log in back to the cloud Bot API server
for 10 minutes.
Returns True on success. Requires no parameters.
See https://core.telegram.org/bots/api#logout for details.
"""
return await self.api_request(
'logOut',
parameters=locals()
)
async def close(self):
"""Close bot instance in local server.
Use this method to close the bot instance before moving it from one
local server to another.
You need to delete the webhook before calling this method to ensure
that the bot isn't launched again after server restart.
The method will return error 429 in the first 10 minutes after the
bot is launched. Returns True on success.
Requires no parameters.
See https://core.telegram.org/bots/api#close for details.
"""
return await self.api_request(
'close',
parameters=locals()
)
async def copyMessage(self, chat_id: Union[int, str],
from_chat_id: Union[int, str],
message_id: int,
caption: str = None,
parse_mode: str = None,
caption_entities: list = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
allow_sending_without_reply: bool = None,
reply_markup=None):
"""Use this method to copy messages of any kind.
The method is analogous to the method forwardMessages, but the copied
message doesn't have a link to the original message.
Returns the MessageId of the sent message on success.
See https://core.telegram.org/bots/api#copymessage for details.
"""
return await self.api_request(
'copyMessage',
parameters=locals()
)
async def unpinAllChatMessages(self, chat_id: Union[int, str]):
"""Use this method to clear the list of pinned messages in a chat.
If the chat is not a private chat, the bot must be an administrator
in the chat for this to work and must have the 'can_pin_messages'
admin right in a supergroup or 'can_edit_messages' admin right in a
channel.
Returns True on success.
See https://core.telegram.org/bots/api#unpinallchatmessages for details.
"""
return await self.api_request(
'unpinAllChatMessages',
parameters=locals()
)

View File

@@ -3,9 +3,13 @@
# Standard library modules
import argparse
import asyncio
import inspect
import logging
# Third party modules
import os
from typing import List
import aiohttp
from bs4 import BeautifulSoup
@@ -52,7 +56,7 @@ class TelegramApiMethod(object):
return self._parameters
@property
def parameters_with_types(self):
def parameters_with_types(self) -> List[str]:
return [
f"{parameter['name']}: {parameter['type']}"
for parameter in self._parameters
@@ -101,22 +105,30 @@ class TelegramApiMethod(object):
async def print_api_methods(loop=None,
filename=None,
print_all=False,
output_file=None):
output_file=None,
input_file=None):
"""Get information from Telegram bot API web page."""
if loop is None:
loop = asyncio.get_event_loop()
implemented_methods = dir(TelegramBot)
async with aiohttp.ClientSession(
loop=loop,
timeout=aiohttp.ClientTimeout(
total=100
)
) as session:
async with session.get(
api_url
) as response:
if input_file is None or not os.path.isfile(input_file):
async with aiohttp.ClientSession(
loop=loop,
timeout=aiohttp.ClientTimeout(
total=100
)
) as session:
async with session.get(
api_url
) as response:
web_page = BeautifulSoup(
await response.text(),
"html.parser"
)
else:
with open(input_file, 'r') as local_web_page:
web_page = BeautifulSoup(
await response.text(),
''.join(local_web_page.readlines()),
"html.parser"
)
if filename is not None:
@@ -146,40 +158,84 @@ async def print_api_methods(loop=None,
)
)
new_line = '\n'
new_methods = []
edited_methods = []
for method in methods:
if print_all or method.name not in implemented_methods:
new_methods.append(method)
else:
parameters = set(parameter['name'] for parameter in method.parameters)
implemented_parameters = set(
parameter.strip('_') # Parameter `type` becomes `type_` in python
for parameter in inspect.signature(
getattr(TelegramBot,
method.name)
).parameters.keys()
if parameter != 'self'
)
new_parameters = parameters - implemented_parameters
deprecated_parameters = implemented_parameters - parameters
if new_parameters or deprecated_parameters:
edited_methods.append(
dict(
name=method.name,
new_parameters=new_parameters,
deprecated_parameters=deprecated_parameters
)
)
if output_file:
with open(output_file, 'w') as file:
file.write(
"from typing import List, Union\n"
"from davtelepot.api import TelegramBot\n"
"self = TelegramBot('fake_token')\n\n\n"
)
if new_methods:
file.write(
"from typing import List, Union\n"
"from davtelepot.api import TelegramBot\n\n\n"
"# noinspection PyPep8Naming\n"
"class Bot(TelegramBot):\n\n"
)
file.writelines(
f"async def {method.name}("
f"{', '.join(method.parameters_with_types)}"
"):\n"
" \"\"\""
f"{method.description.replace(new_line, new_line + ' ' * 4)}\n"
" See https://core.telegram.org/bots/api#"
f"{method.name.lower()} for details.\n"
" \"\"\"\n"
" return await self.api_request(\n"
f" '{method.name}',\n"
" parameters=locals()\n"
" )\n\n\n"
for method in methods
if print_all or method.name not in implemented_methods
f" async def {method.name}("
f"{', '.join(['self'] + method.parameters_with_types)}"
f"):\n"
f" \"\"\""
f" {method.description.replace(new_line, new_line + ' ' * 4)}\n"
f" See https://core.telegram.org/bots/api#"
f" {method.name.lower()} for details.\n"
f" \"\"\"\n"
f" return await self.api_request(\n"
f" '{method.name}',\n"
f" parameters=locals()\n"
f" )\n\n"
for method in new_methods
)
if edited_methods:
file.write('\n# === EDITED METHODS ===\n')
for method in edited_methods:
file.write(f'\n"""{method["name"]}\n')
if method['new_parameters']:
file.write(" New parameters: "
+ ", ".join(method['new_parameters'])
+ "\n")
if method['deprecated_parameters']:
file.write(" Deprecated parameters: "
+ ", ".join(method['deprecated_parameters'])
+ "\n")
file.write('"""\n')
else:
print(
'\n'.join(
f"NAME\n\t{method.name}\n"
f"PARAMETERS\n\t{', '.join(method.parameters_with_types)}\n"
f"PARAMETERS\n\t{', '.join(['self'] + method.parameters_with_types)}\n"
f"DESCRIPTION\n\t{method.description}\n"
f"TABLE\n\t{method.print_parameters_table()}\n\n"
for method in methods
if print_all or method.name not in implemented_methods
for method in new_methods
)
)
for method in edited_methods:
print(method['name'])
if method['new_parameters']:
print("\tNew parameters: " + ", ".join(method['new_parameters']))
if method['deprecated_parameters']:
print("\tDeprecated parameters: " + ", ".join(method['deprecated_parameters']))
def main():
@@ -202,16 +258,22 @@ def main():
default=None,
required=False,
help='File path to store methods implementation')
cli_parser.add_argument('--in', '--input', '-i', type=str,
default=None,
required=False,
help='File path to read Telegram API web page')
cli_arguments = vars(cli_parser.parse_args())
filename = cli_arguments['file']
print_all = cli_arguments['all']
output_file = cli_arguments['out']
input_file = cli_arguments['in']
loop = asyncio.get_event_loop()
loop.run_until_complete(
print_api_methods(loop=loop,
filename=filename,
print_all=print_all,
output_file=output_file)
output_file=output_file,
input_file=input_file)
)
logging.info("Done!")