diff --git a/README.md b/README.md index f3e3eff..6515d6a 100644 --- a/README.md +++ b/README.md @@ -131,13 +131,24 @@ Or use meta-flag "all" to exclude all flags in posts: ## Exclude text -You can filter out posts containing specific words or phrases using the `exclude_text` parameter. This allows for more flexible content filtering beyond the predefined flags. +You can filter out posts containing specific text patterns using the `exclude_text` parameter. This parameter accepts a regular expression pattern that will be matched against the post text. -For simple words without spaces: -``` curl https://pgbridge.example.com/rss/DragorWW_space?exclude_text=реклама,промо,акция ``` +The pattern is case-insensitive and supports all standard regex features. For example: -For phrases containing spaces, use quotes: -``` curl https://pgbridge.example.com/rss/DragorWW_space?exclude_text="специальное предложение","только сегодня",акция ``` +``` curl https://pgbridge.example.com/rss/DragorWW_space?exclude_text=все.*комикс|реклам.*канал ``` -The filtering is case-insensitive and will exclude any post containing any of the specified words or phrases. +This will exclude posts containing: + +- Any text starting with "все" and ending with "комикс" +- Any text containing "реклам" followed by "канал" + +You can use any regex pattern, including: + +- `.*` for any characters +- `\d+` for numbers +- `[а-яА-Я]+` for Russian letters +- `|` for alternative patterns +- And other standard regex features + +The pattern is matched against the entire post text, so you can create complex filtering rules. diff --git a/rss_generator.py b/rss_generator.py index b250bc1..a51ad29 100644 --- a/rss_generator.py +++ b/rss_generator.py @@ -4,6 +4,7 @@ from typing import Optional from feedgen.feed import FeedGenerator from post_parser import PostParser from config import get_settings +import re Config = get_settings() @@ -199,42 +200,15 @@ async def _render_messages_groups(messages_groups, post_parser, exclude_flags: s # Filter posts by exclude_text if exclude_text: - # Split by comma, but preserve commas inside quotes - exclude_text_list = [] - current_phrase = "" - in_quotes = False - - for char in exclude_text: - if char == '"' and (not current_phrase.endswith('\\') or current_phrase.endswith('\\\\')): - in_quotes = not in_quotes - current_phrase += char - elif char == ',' and not in_quotes: - if current_phrase: - # Remove surrounding quotes if present - if current_phrase.startswith('"') and current_phrase.endswith('"'): - current_phrase = current_phrase[1:-1] - exclude_text_list.append(current_phrase.strip().lower()) - current_phrase = "" - else: - current_phrase += char - - # Add the last phrase if any - if current_phrase: - if current_phrase.startswith('"') and current_phrase.endswith('"'): - current_phrase = current_phrase[1:-1] - exclude_text_list.append(current_phrase.strip().lower()) - - logger.debug(f"Parsed exclude_text into phrases: {exclude_text_list}") - + # Compile single regex pattern + exclude_pattern = re.compile(exclude_text.strip(), re.IGNORECASE) filtered_posts = [] for post in rendered_posts: - post_text = post['text'].lower() - # Check if any of the exclude_text items is in the post text (case-insensitive) - if not any(text in post_text for text in exclude_text_list): + # Check if pattern matches the post text + if not exclude_pattern.search(post['text']): filtered_posts.append(post) else: - matching_phrases = [text for text in exclude_text_list if text in post_text] - logger.debug(f"Excluded post {post['message_id']} containing phrases: {matching_phrases}") + logger.debug(f"excluded_post: message_id {post['message_id']}, pattern {exclude_pattern.pattern}") rendered_posts = filtered_posts # Sort by date