Queer European MD passionate about IT
Переглянути джерело

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 місяців тому
батько
коміт
6759e5c704
3 змінених файлів з 27 додано та 12 видалено
  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"
 __credits__ = ["Marco Origlia", "Nick Lee @Nickoala"]
 __license__ = "GNU General Public License v3.0"
-__version__ = "2.10.6"
+__version__ = "2.10.7"
 __maintainer__ = "Davide Testa"
 __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.
     """
     await bot.get_me()
+    if len(bot.administrators) > 0:
+        return
     bot.administration_token = get_secure_key(length=10)
     print(f"To become administrator click "
             f"https://t.me/{bot.name}?start="
@@ -2132,6 +2134,4 @@ def init(telegram_bot: Bot,
                                     update=update,
                                     user_record=user_record,
                                     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.packages = [sys.modules['davtelepot']]
         self._documents_max_dimension = None
+        self._getting_me = False
+        self._got_me = False
         # Add `users` table with its fields if missing
         if 'users' not in self.db.tables:
             table = self.db.create_table(
@@ -2804,9 +2806,7 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
         """
         if not callable(condition):
             raise TypeError(
-                'Condition {c} is not a callable'.format(
-                    c=condition.__name__
-                )
+                f'Condition {condition.__name__} is not a callable'
             )
 
         def query_decorator(handler):
@@ -3147,26 +3147,41 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
 
         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:
             me = await self.getMe()
             if isinstance(me, Exception):
                 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._telegram_id = me['id']
         except Exception as e:
             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)
+            if self._got_me:
+                return
             self.__class__.stop(
                 message="Information about this bot could not be retrieved.\n"
                         "Restarting...",
                 final_state=65
             )
+        self._getting_me = False
+        self._got_me = True
 
     def setup(self):
         """Make bot ask for updates and handle responses."""