From 0185af25c1f51afd42e17551baf484b8bbe95704 Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Fri, 28 Sep 2018 03:40:10 +0300 Subject: [PATCH] Implemented hashtag/cashtag filter --- aiogram/dispatcher/dispatcher.py | 9 ++-- aiogram/dispatcher/filters/__init__.py | 3 +- aiogram/dispatcher/filters/builtin.py | 66 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/aiogram/dispatcher/dispatcher.py b/aiogram/dispatcher/dispatcher.py index 76eb9dcc..3e86b0ab 100644 --- a/aiogram/dispatcher/dispatcher.py +++ b/aiogram/dispatcher/dispatcher.py @@ -6,9 +6,8 @@ import time import typing from contextvars import ContextVar -from aiogram.dispatcher.filters import Command -from .filters import ContentTypeFilter, ExceptionsFilter, FiltersFactory, RegexpCommandsFilter, \ - Regexp, StateFilter, Text +from .filters import Command, ContentTypeFilter, ExceptionsFilter, FiltersFactory, HashTag, Regexp, \ + RegexpCommandsFilter, StateFilter, Text from .handler import Handler from .middlewares import MiddlewareManager from .storage import BaseStorage, DELTA, DisabledStorage, EXCEEDED_COUNT, FSMContext, \ @@ -93,6 +92,10 @@ class Dispatcher: self.channel_post_handlers, self.edited_channel_post_handlers, self.callback_query_handlers ]) + filters_factory.bind(HashTag, event_handlers=[ + self.message_handlers, self.edited_message_handlers, + self.channel_post_handlers, self.edited_channel_post_handlers + ]) filters_factory.bind(Regexp, event_handlers=[ self.message_handlers, self.edited_message_handlers, self.channel_post_handlers, self.edited_channel_post_handlers, diff --git a/aiogram/dispatcher/filters/__init__.py b/aiogram/dispatcher/filters/__init__.py index 950234cf..138174cc 100644 --- a/aiogram/dispatcher/filters/__init__.py +++ b/aiogram/dispatcher/filters/__init__.py @@ -1,5 +1,5 @@ from .builtin import Command, CommandHelp, CommandPrivacy, CommandSettings, CommandStart, ContentTypeFilter, \ - ExceptionsFilter, Regexp, RegexpCommandsFilter, StateFilter, Text + ExceptionsFilter, HashTag, Regexp, RegexpCommandsFilter, StateFilter, Text from .factory import FiltersFactory from .filters import AbstractFilter, BoundFilter, Filter, FilterNotPassed, FilterRecord, check_filter, check_filters @@ -13,6 +13,7 @@ __all__ = [ 'CommandSettings', 'ContentTypeFilter', 'ExceptionsFilter', + 'HashTag', 'Filter', 'FilterNotPassed', 'FilterRecord', diff --git a/aiogram/dispatcher/filters/builtin.py b/aiogram/dispatcher/filters/builtin.py index 432bc1b7..f5234472 100644 --- a/aiogram/dispatcher/filters/builtin.py +++ b/aiogram/dispatcher/filters/builtin.py @@ -181,6 +181,72 @@ class Text(Filter): return False +class HashTag(Filter): + """ + Filter for hashtag's and cashtag's + """ + + # TODO: allow to use regexp + + def __init__(self, hashtags=None, cashtags=None): + if not hashtags and not cashtags: + raise ValueError('No one hashtag or cashtag is specified!') + + if hashtags is None: + hashtags = [] + elif isinstance(hashtags, str): + hashtags = [hashtags] + + if cashtags is None: + cashtags = [] + elif isinstance(cashtags, str): + cashtags = [cashtags.upper()] + else: + cashtags = list(map(str.upper, cashtags)) + + self.hashtags = hashtags + self.cashtags = cashtags + + @classmethod + def validate(cls, full_config: Dict[str, Any]): + config = {} + if 'hashtags' in full_config: + config['hashtags'] = full_config.pop('hashtags') + if 'cashtags' in full_config: + config['cashtags'] = full_config.pop('cashtags') + return config + + async def check(self, message: types.Message): + if message.caption: + text = message.caption + entities = message.caption_entities + elif message.text: + text = message.text + entities = message.entities + else: + return False + + hashtags, cashtags = self._get_tags(text, entities) + if self.hashtags and set(hashtags) & set(self.hashtags) \ + or self.cashtags and set(cashtags) & set(self.cashtags): + return {'hashtags': hashtags, 'cashtags': cashtags} + + def _get_tags(self, text, entities): + hashtags = [] + cashtags = [] + + for entity in entities: + if entity.type == types.MessageEntityType.HASHTAG: + value = entity.get_text(text).lstrip('#') + hashtags.append(value) + + elif entity.type == types.MessageEntityType.CASHTAG: + value = entity.get_text(text).lstrip('$') + cashtags.append(value) + + return hashtags, cashtags + + class Regexp(Filter): """ Regexp filter for messages and callback query