Queer European MD passionate about IT
Browse Source

Administrators may be set after administration module initialization

Do not check for administrators until bot has got information about itself. Prevent duplicate calls to bot.get_me() async method
Davte 5 months ago
parent
commit
6759e5c704
3 changed files with 27 additions and 12 deletions
  1. 1 1
      davtelepot/__init__.py
  2. 3 3
      davtelepot/administration_tools.py
  3. 23 8
      davtelepot/bot.py

+ 1 - 1
davtelepot/__init__.py

@@ -11,7 +11,7 @@ __author__ = "Davide Testa"
 __email__ = "davide@davte.it"
 __email__ = "davide@davte.it"
 __credits__ = ["Marco Origlia", "Nick Lee @Nickoala"]
 __credits__ = ["Marco Origlia", "Nick Lee @Nickoala"]
 __license__ = "GNU General Public License v3.0"
 __license__ = "GNU General Public License v3.0"
-__version__ = "2.10.6"
+__version__ = "2.10.7"
 __maintainer__ = "Davide Testa"
 __maintainer__ = "Davide Testa"
 __contact__ = "t.me/davte"
 __contact__ = "t.me/davte"
 
 

+ 3 - 3
davtelepot/administration_tools.py

@@ -1890,6 +1890,8 @@ async def create_promotion_command(bot: Bot):
         of the machine running the bot.
         of the machine running the bot.
     """
     """
     await bot.get_me()
     await bot.get_me()
+    if len(bot.administrators) > 0:
+        return
     bot.administration_token = get_secure_key(length=10)
     bot.administration_token = get_secure_key(length=10)
     print(f"To become administrator click "
     print(f"To become administrator click "
             f"https://t.me/{bot.name}?start="
             f"https://t.me/{bot.name}?start="
@@ -2132,6 +2134,4 @@ def init(telegram_bot: Bot,
                                     update=update,
                                     update=update,
                                     user_record=user_record,
                                     user_record=user_record,
                                     language=language)
                                     language=language)
-
-    if len(telegram_bot.administrators) == 0:
-        asyncio.ensure_future(create_promotion_command(bot=telegram_bot))
+    asyncio.ensure_future(create_promotion_command(bot=telegram_bot))

+ 23 - 8
davtelepot/bot.py

@@ -221,6 +221,8 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
         self.Role = None
         self.Role = None
         self.packages = [sys.modules['davtelepot']]
         self.packages = [sys.modules['davtelepot']]
         self._documents_max_dimension = None
         self._documents_max_dimension = None
+        self._getting_me = False
+        self._got_me = False
         # Add `users` table with its fields if missing
         # Add `users` table with its fields if missing
         if 'users' not in self.db.tables:
         if 'users' not in self.db.tables:
             table = self.db.create_table(
             table = self.db.create_table(
@@ -2804,9 +2806,7 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
         """
         """
         if not callable(condition):
         if not callable(condition):
             raise TypeError(
             raise TypeError(
-                'Condition {c} is not a callable'.format(
-                    c=condition.__name__
-                )
+                f'Condition {condition.__name__} is not a callable'
             )
             )
 
 
         def query_decorator(handler):
         def query_decorator(handler):
@@ -3147,26 +3147,41 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
 
 
         Restart bots if bot can't be got.
         Restart bots if bot can't be got.
         """
         """
+        for _ in range(60):
+            if not self._getting_me:
+                break
+            await asyncio.sleep(0.5)
+        else:
+            raise TimeoutError("Getting bot information was in progress but "
+                               "did not make it in 30 seconds...")
+        if self._got_me:
+            return
+        self._getting_me = True
         try:
         try:
             me = await self.getMe()
             me = await self.getMe()
             if isinstance(me, Exception):
             if isinstance(me, Exception):
                 raise me
                 raise me
-            elif me is None:
-                raise Exception('getMe returned None')
+            if me is None:
+                raise TypeError('getMe returned None')
             self._name = me["username"]
             self._name = me["username"]
             self._telegram_id = me['id']
             self._telegram_id = me['id']
         except Exception as e:
         except Exception as e:
             logging.error(
             logging.error(
-                f"API getMe method failed, information about this bot could "
-                f"not be retrieved. Restarting in 5 minutes...\n\n"
-                f"Error information:\n{e}"
+                "API getMe method failed, information about this bot could "
+                "not be retrieved. Restarting in 5 minutes...\n\n"
+                "Error information:\n%s", e
             )
             )
+            self._getting_me = False
             await asyncio.sleep(5*60)
             await asyncio.sleep(5*60)
+            if self._got_me:
+                return
             self.__class__.stop(
             self.__class__.stop(
                 message="Information about this bot could not be retrieved.\n"
                 message="Information about this bot could not be retrieved.\n"
                         "Restarting...",
                         "Restarting...",
                 final_state=65
                 final_state=65
             )
             )
+        self._getting_me = False
+        self._got_me = True
 
 
     def setup(self):
     def setup(self):
         """Make bot ask for updates and handle responses."""
         """Make bot ask for updates and handle responses."""