Implemented hashtag/cashtag filter

This commit is contained in:
Alex Root Junior 2018-09-28 03:40:10 +03:00
parent 09293063d3
commit 0185af25c1
3 changed files with 74 additions and 4 deletions

View file

@ -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,

View file

@ -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',

View file

@ -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