Merge pull request #182 from Ars2014/dev-2.x

Create AdminFilter and rename IdFilter to IDFilter
This commit is contained in:
Alex Root Junior 2019-08-15 16:53:28 +03:00 committed by GitHub
commit ca55fad4ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 112 additions and 8 deletions

View file

@ -9,7 +9,7 @@ import aiohttp
from aiohttp.helpers import sentinel
from .filters import Command, ContentTypeFilter, ExceptionsFilter, FiltersFactory, HashTag, Regexp, \
RegexpCommandsFilter, StateFilter, Text, IdFilter
RegexpCommandsFilter, StateFilter, Text, IDFilter, AdminFilter
from .handler import Handler
from .middlewares import MiddlewareManager
from .storage import BaseStorage, DELTA, DisabledStorage, EXCEEDED_COUNT, FSMContext, \
@ -128,7 +128,15 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
filters_factory.bind(ExceptionsFilter, event_handlers=[
self.errors_handlers,
])
filters_factory.bind(IdFilter, event_handlers=[
filters_factory.bind(AdminFilter, event_handlers=[
self.message_handlers,
self.edited_message_handlers,
self.channel_post_handlers,
self.edited_channel_post_handlers,
self.callback_query_handlers,
self.inline_query_handlers,
])
filters_factory.bind(IDFilter, event_handlers=[
self.message_handlers,
self.edited_message_handlers,
self.channel_post_handlers,

View file

@ -1,5 +1,5 @@
from .builtin import Command, CommandHelp, CommandPrivacy, CommandSettings, CommandStart, ContentTypeFilter, \
ExceptionsFilter, HashTag, Regexp, RegexpCommandsFilter, StateFilter, Text, IdFilter
ExceptionsFilter, HashTag, Regexp, RegexpCommandsFilter, StateFilter, Text, IDFilter, AdminFilter
from .factory import FiltersFactory
from .filters import AbstractFilter, BoundFilter, Filter, FilterNotPassed, FilterRecord, execute_filter, \
check_filters, get_filter_spec, get_filters_spec
@ -23,7 +23,8 @@ __all__ = [
'Regexp',
'StateFilter',
'Text',
'IdFilter',
'IDFilter',
'AdminFilter',
'get_filter_spec',
'get_filters_spec',
'execute_filter',

View file

@ -9,7 +9,7 @@ from babel.support import LazyProxy
from aiogram import types
from aiogram.dispatcher.filters.filters import BoundFilter, Filter
from aiogram.types import CallbackQuery, Message, InlineQuery, Poll
from aiogram.types import CallbackQuery, Message, InlineQuery, Poll, ChatType
class Command(Filter):
@ -510,7 +510,7 @@ class ExceptionsFilter(BoundFilter):
return False
class IdFilter(Filter):
class IDFilter(Filter):
def __init__(self,
user_id: Optional[Union[Iterable[Union[int, str]], str, int]] = None,
@ -571,3 +571,57 @@ class IdFilter(Filter):
return chat_id in self.chat_id
return False
class AdminFilter(Filter):
"""
Checks if user is admin in a chat.
If is_chat_admin is not set, the filter will check in the current chat (correct only for messages).
is_chat_admin is required for InlineQuery.
"""
def __init__(self, is_chat_admin: Optional[Union[Iterable[Union[int, str]], str, int, bool]] = None):
self._check_current = False
self._chat_ids = None
if is_chat_admin is False:
raise ValueError("is_chat_admin cannot be False")
if is_chat_admin:
if isinstance(is_chat_admin, bool):
self._check_current = is_chat_admin
if isinstance(is_chat_admin, Iterable):
self._chat_ids = list(is_chat_admin)
else:
self._chat_ids = [is_chat_admin]
else:
self._check_current = True
@classmethod
def validate(cls, full_config: typing.Dict[str, typing.Any]) -> typing.Optional[typing.Dict[str, typing.Any]]:
result = {}
if "is_chat_admin" in full_config:
result["is_chat_admin"] = full_config.pop("is_chat_admin")
return result
async def check(self, obj: Union[Message, CallbackQuery, InlineQuery]) -> bool:
user_id = obj.from_user.id
if self._check_current:
if isinstance(obj, Message):
message = obj
elif isinstance(obj, CallbackQuery) and obj.message:
message = obj.message
else:
return False
if ChatType.is_private(message): # there is no admin in private chats
return False
chat_ids = [message.chat.id]
else:
chat_ids = self._chat_ids
admins = [member.user.id for chat_id in chat_ids for member in await obj.bot.get_chat_administrators(chat_id)]
return user_id in admins

View file

@ -111,10 +111,18 @@ ExceptionsFilter
:show-inheritance:
IdFilter
IDFilter
----------------
.. autoclass:: aiogram.dispatcher.filters.builtin.IdFilter
.. autoclass:: aiogram.dispatcher.filters.builtin.IDFilter
:members:
:show-inheritance:
AdminFilter
----------------
.. autoclass:: aiogram.dispatcher.filters.builtin.AdminFilter
:members:
:show-inheritance:

View file

@ -0,0 +1,33 @@
import logging
from aiogram import Bot, Dispatcher, types, executor
API_TOKEN = 'API_TOKEN_HERE'
logging.basicConfig(level=logging.DEBUG)
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot=bot)
# checks specified chat
@dp.message_handler(is_chat_admin=-1001241113577)
async def handle_specified(msg: types.Message):
await msg.answer("You are an admin of the specified chat!")
# checks multiple chats
@dp.message_handler(is_chat_admin=[-1001241113577, -320463906])
async def handle_multiple(msg: types.Message):
await msg.answer("You are an admin of multiple chats!")
# checks current chat
@dp.message_handler(is_chat_admin=True)
async def handler3(msg: types.Message):
await msg.answer("You are an admin of the current chat!")
if __name__ == '__main__':
executor.start_polling(dp)