Advertisement
Andrexxelles

Untitled

Mar 25th, 2021
771
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.90 KB | None | 0 0
  1. import aioredis
  2. from aiogram import types, Dispatcher
  3. from aiogram.dispatcher.handler import CancelHandler, current_handler
  4. from aiogram.dispatcher.middlewares import BaseMiddleware
  5. from aiogram.utils.exceptions import Throttled
  6.  
  7. from config import DEFUALT_RATE_LIMIT, MAX_STANDART_FLOOD_TIME
  8. from language import language
  9.  
  10.  
  11. def anti_flood(limit: int, key=None):
  12.     def decorator(func):
  13.         setattr(func, 'throttling_limit', limit)
  14.         return func
  15.  
  16.     return decorator
  17.  
  18.  
  19. # noinspection PyAttributeOutsideInit
  20. class ThrottlingMiddleware(BaseMiddleware):
  21.  
  22.     def __init__(self, limit=DEFUALT_RATE_LIMIT, key_prefix='antiflood_'):
  23.         self.rate_limit = limit
  24.         self.prefix = key_prefix
  25.         super(ThrottlingMiddleware, self).__init__()
  26.  
  27.     async def on_process_message(self, message: types.Message, data: dict):
  28.         handler = current_handler.get()
  29.         self.lang = data['lang']
  30.  
  31.         if handler:
  32.             self.limit = getattr(handler, 'throttling_limit', self.rate_limit)
  33.             self.key = getattr(handler, 'throttling_key', f"{self.prefix}_{handler.__name__}")
  34.  
  35.         else:
  36.             self.limit = self.rate_limit
  37.             self.key = f"{self.prefix}_message"
  38.  
  39.         if self.limit <= MAX_STANDART_FLOOD_TIME:
  40.             await message.reply(self.limit)
  41.             await self.standart_flood(message)
  42.  
  43.         else:
  44.             await self.redis_flood(message)
  45.  
  46.     async def standart_flood(self, message: types.Message):
  47.         dispatcher = Dispatcher.get_current()
  48.  
  49.         try:
  50.             await dispatcher.throttle(self.key, rate=self.limit)
  51.  
  52.         except Throttled as t:
  53.             await self.message_throttled(message, t)
  54.             raise CancelHandler
  55.  
  56.     async def message_throttled(self, message: types.Message, throttled: Throttled):
  57.  
  58.         if throttled.exceeded_count == 2:
  59.             await message.reply(language['throttled_request'][self.lang])
  60.  
  61.     async def redis_flood(self, message: types.Message):
  62.  
  63.         handler = current_handler.get()
  64.         throttling_limit = getattr(handler, 'throttling_limit', self.limit)
  65.  
  66.         redis = await aioredis.create_redis_pool(
  67.             'redis://server:port',
  68.             password='password'
  69.         )
  70.  
  71.         if not await redis.exists(message.chat.id):
  72.             await redis.setex(
  73.                 message.chat.id,
  74.                 throttling_limit,
  75.                 value=handler.__name__
  76.             )
  77.  
  78.             redis.close()
  79.             await redis.wait_closed()
  80.             return
  81.  
  82.         elif handler.__name__ == await redis.get(message.chat.id, encoding='utf-8'):
  83.  
  84.             await message.reply(f"{language['throttled_request'][self.lang]}\n"
  85.                                 f"{language['throttled_time'][self.lang].format(await redis.ttl(message.chat.id))}")
  86.  
  87.             redis.close()
  88.             await redis.wait_closed()
  89.             raise CancelHandler
  90.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement