| 
					
				 | 
			
			
				@@ -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!") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |