Added a script to implement missing methods from Telegram website
This commit is contained in:
parent
b0a2770177
commit
45ff81afbc
@ -1,6 +1,7 @@
|
|||||||
"""Get and parse Telegram API webpage."""
|
"""Get and parse Telegram API web page."""
|
||||||
|
|
||||||
# Standard library modules
|
# Standard library modules
|
||||||
|
import argparse
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -8,10 +9,20 @@ import logging
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
# Project modules
|
||||||
|
from . import api
|
||||||
|
|
||||||
api_url = "https://core.telegram.org/bots/api"
|
api_url = "https://core.telegram.org/bots/api"
|
||||||
|
|
||||||
|
|
||||||
class TelegramApiMethod(object):
|
class TelegramApiMethod(object):
|
||||||
|
types = {
|
||||||
|
'Array of String': "List[str]",
|
||||||
|
'Boolean': "bool",
|
||||||
|
'Integer': "int",
|
||||||
|
'Integer or String': "Union[int, str]",
|
||||||
|
'String': "str",
|
||||||
|
}
|
||||||
"""Telegram bot API method."""
|
"""Telegram bot API method."""
|
||||||
|
|
||||||
def __init__(self, name, description, table):
|
def __init__(self, name, description, table):
|
||||||
@ -19,6 +30,7 @@ class TelegramApiMethod(object):
|
|||||||
self._name = name
|
self._name = name
|
||||||
self._description = description
|
self._description = description
|
||||||
self._table = table
|
self._table = table
|
||||||
|
self._parameters = self.get_parameters_from_table()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
@ -35,7 +47,18 @@ class TelegramApiMethod(object):
|
|||||||
"""Return method parameters table."""
|
"""Return method parameters table."""
|
||||||
return self._table
|
return self._table
|
||||||
|
|
||||||
def get_parameters_from_table(self):
|
@property
|
||||||
|
def parameters(self):
|
||||||
|
return self._parameters
|
||||||
|
|
||||||
|
@property
|
||||||
|
def parameters_with_types(self):
|
||||||
|
return [
|
||||||
|
f"{parameter['name']}: {parameter['type']}"
|
||||||
|
for parameter in self._parameters
|
||||||
|
]
|
||||||
|
|
||||||
|
def print_parameters_table(self):
|
||||||
"""Extract parameters from API table."""
|
"""Extract parameters from API table."""
|
||||||
result = ''
|
result = ''
|
||||||
if self.table is None:
|
if self.table is None:
|
||||||
@ -54,11 +77,35 @@ class TelegramApiMethod(object):
|
|||||||
result += '\n'
|
result += '\n'
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def get_parameters_from_table(self):
|
||||||
|
if self.table is None:
|
||||||
|
return []
|
||||||
|
parameters = []
|
||||||
|
rows = self.table.tbody.find_all('tr') or []
|
||||||
|
for row in rows:
|
||||||
|
columns = row.find_all('td') or []
|
||||||
|
name, type_, *_ = map(lambda column: column.text.strip(), columns)
|
||||||
|
if type_ in self.types:
|
||||||
|
type_ = self.types[type_]
|
||||||
|
else:
|
||||||
|
type_ = f"'{type_}'"
|
||||||
|
parameters.append(
|
||||||
|
dict(
|
||||||
|
name=name,
|
||||||
|
type=type_
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return parameters
|
||||||
|
|
||||||
async def main(loop=None, filename=None):
|
|
||||||
"""Get information from Telegram bot API webpage."""
|
async def print_api_methods(loop=None,
|
||||||
|
filename=None,
|
||||||
|
print_all=False,
|
||||||
|
output_file=None):
|
||||||
|
"""Get information from Telegram bot API web page."""
|
||||||
if loop is None:
|
if loop is None:
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
implemented_methods = dir(api.TelegramBot)
|
||||||
async with aiohttp.ClientSession(
|
async with aiohttp.ClientSession(
|
||||||
loop=loop,
|
loop=loop,
|
||||||
timeout=aiohttp.ClientTimeout(
|
timeout=aiohttp.ClientTimeout(
|
||||||
@ -68,14 +115,15 @@ async def main(loop=None, filename=None):
|
|||||||
async with session.get(
|
async with session.get(
|
||||||
api_url
|
api_url
|
||||||
) as response:
|
) as response:
|
||||||
webpage = BeautifulSoup(
|
web_page = BeautifulSoup(
|
||||||
await response.text(),
|
await response.text(),
|
||||||
"html.parser"
|
"html.parser"
|
||||||
)
|
)
|
||||||
if filename is not None:
|
if filename is not None:
|
||||||
with open(filename, 'w') as _file:
|
with open(filename, 'w') as _file:
|
||||||
_file.write(webpage.decode())
|
_file.write(web_page.decode())
|
||||||
for method in webpage.find_all("h4"):
|
methods = []
|
||||||
|
for method in web_page.find_all("h4"):
|
||||||
method_name = method.text
|
method_name = method.text
|
||||||
description = ''
|
description = ''
|
||||||
parameters_table = None
|
parameters_table = None
|
||||||
@ -89,18 +137,83 @@ async def main(loop=None, filename=None):
|
|||||||
break # Stop searching in siblings if <table> is found
|
break # Stop searching in siblings if <table> is found
|
||||||
description += tag.get_text()
|
description += tag.get_text()
|
||||||
if method_name and method_name[0] == method_name[0].lower():
|
if method_name and method_name[0] == method_name[0].lower():
|
||||||
method = TelegramApiMethod(
|
methods.append(
|
||||||
method_name, description, parameters_table
|
TelegramApiMethod(
|
||||||
|
method_name,
|
||||||
|
description,
|
||||||
|
parameters_table
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
new_line = '\n'
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
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
|
||||||
|
)
|
||||||
|
else:
|
||||||
print(
|
print(
|
||||||
"NAME\n\t{m.name}\n"
|
'\n'.join(
|
||||||
"DESCRIPTION\n\t{m.description}\n"
|
f"NAME\n\t{method.name}\n"
|
||||||
f"TABLE\n\t{method.get_parameters_from_table()}\n\n".format(
|
f"PARAMETERS\n\t{', '.join(method.parameters_with_types)}\n"
|
||||||
m=method
|
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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
def main():
|
||||||
|
cli_parser = argparse.ArgumentParser(
|
||||||
|
description='Get Telegram API methods information from telegram '
|
||||||
|
'website.\n'
|
||||||
|
'Implement missing (or --all) methods in --out file, '
|
||||||
|
'or print methods information.',
|
||||||
|
allow_abbrev=False,
|
||||||
|
)
|
||||||
|
cli_parser.add_argument('--file', '-f', '--filename', type=str,
|
||||||
|
default=None,
|
||||||
|
required=False,
|
||||||
|
help='File path to store Telegram API web page')
|
||||||
|
cli_parser.add_argument('--all', '-a',
|
||||||
|
action='store_true',
|
||||||
|
help='Print all methods (default: print missing '
|
||||||
|
'methods only)')
|
||||||
|
cli_parser.add_argument('--out', '--output', '-o', type=str,
|
||||||
|
default=None,
|
||||||
|
required=False,
|
||||||
|
help='File path to store methods implementation')
|
||||||
|
cli_arguments = vars(cli_parser.parse_args())
|
||||||
|
filename = cli_arguments['file']
|
||||||
|
print_all = cli_arguments['all']
|
||||||
|
output_file = cli_arguments['out']
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
loop.run_until_complete(main(loop=loop, filename='prova.txt'))
|
loop.run_until_complete(
|
||||||
|
print_api_methods(loop=loop,
|
||||||
|
filename=filename,
|
||||||
|
print_all=print_all,
|
||||||
|
output_file=output_file)
|
||||||
|
)
|
||||||
logging.info("Done!")
|
logging.info("Done!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user