diff --git a/requirements/requirements.base.txt b/requirements/requirements.base.txt index 1e3d88598b0031f64b67a1a9037f192a86404fc8..d23a95b5a25f078d37521cdb4ed0e9fc3a5c4c2f 100644 --- a/requirements/requirements.base.txt +++ b/requirements/requirements.base.txt @@ -1,4 +1,3 @@ -autocorrect==2.0.0 Flask==1.1.2 httpx==0.13.* pydantic==1.5.1 diff --git a/src/actions/speller.py b/src/actions/speller.py index db0b093cccfdc95cc0d33af9794952990728271f..4a165ca87989cf7553f268611396c03e146b2a3d 100644 --- a/src/actions/speller.py +++ b/src/actions/speller.py @@ -1,7 +1,16 @@ +import asyncio +import re +from datetime import datetime + from src.config import config from src.utils.responses import mark_unread +from src.utils.str_helpers import Rotor, replace_by_index from telethon import events +rotatable_swearing = ["[Бб]лÑ", "[СÑ]ука", "[Ии]ди нахуй", "[Eе]бать"] + +rotatable_pattern = f"({'|'.join(rotatable_swearing)})" + def check_missing_dot(message: str): if not message: @@ -13,12 +22,8 @@ def check_missing_dot(message: str): ) -def check_spell(message: str): - return message != config.speller.autocorrect_sentence(message) - - @config.telegram_client.on( - events.NewMessage(pattern=check_missing_dot, incoming=False, forwards=False,) + events.NewMessage(pattern=check_missing_dot, incoming=False, forwards=False) ) @mark_unread async def add_dot(event: events.NewMessage.Event): @@ -27,12 +32,28 @@ async def add_dot(event: events.NewMessage.Event): @config.telegram_client.on( - events.NewMessage(pattern=check_spell, incoming=False, forwards=False,) + events.NewMessage( + pattern=re.compile(f".*{rotatable_pattern}.*", re.DOTALL), + outgoing=True, + forwards=False, + ) ) -@mark_unread -async def fix_misspelling(event: events.NewMessage.Event): +async def rotate_words(event: events.NewMessage.Event): text = event.message.text - corrected_text = config.speller.autocorrect_sentence(text) - if check_missing_dot(corrected_text): - corrected_text += "." - await event.message.edit(corrected_text) + swearing_match = re.finditer(rotatable_pattern, text) + rotors = [] + for swear in swearing_match: + start_index, stop_index = swear.span() + rotors.append(Rotor(swear.group(), start_index, stop_index)) + + rotation_start = datetime.now() + current_time = rotation_start + while (current_time - rotation_start).seconds < 10: + target_text = text + for rotor in rotors: + new_rotation = rotor.next_rotation + target_text = replace_by_index(target_text, new_rotation, rotor.start) + await asyncio.sleep(0.3) + await event.message.edit(target_text) + current_time = datetime.now() + await event.message.edit(text) diff --git a/src/config.py b/src/config.py index 54722f5c65d79d4f24365f53f4614971c7bb39d7..3ed8fd8f29f0a4ff1443e4c4add5fc9439c5a62e 100644 --- a/src/config.py +++ b/src/config.py @@ -1,4 +1,3 @@ -from autocorrect import Speller from pydantic import BaseSettings from pydantic.fields import Field from telethon import TelegramClient @@ -25,7 +24,5 @@ class Config(BaseSettings): telegram_client: TelegramClient = None - speller: Speller = None - config = Config() diff --git a/src/initializator.py b/src/initializator.py index 141ff10513c94b0cc940facfd61add5bf5142af3..9f04cb172cb07b6749fde75a2e590bad1d85dd60 100644 --- a/src/initializator.py +++ b/src/initializator.py @@ -2,7 +2,6 @@ import asyncio import logging from multiprocessing import Manager, Process -from autocorrect import Speller from src.config import config from src.server_app import create_web_app from telethon import TelegramClient @@ -40,7 +39,6 @@ def init(): client.start( phone=config.telegram_account_phone, code_callback=get_code_from_web(token) ) - config.speller = Speller("ru") config.telegram_client = client from src.actions import finish diff --git a/src/utils/str_helpers.py b/src/utils/str_helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..0d0c0dcabcc10a738f2efb181405d42697815aa9 --- /dev/null +++ b/src/utils/str_helpers.py @@ -0,0 +1,34 @@ +class Rotor: + """ + Class for text rotation. E.G. + abcd + bcda + cdab + ... + """ + + original: str + start: int + stop: int + + def __init__(self, original, start, stop): + self.original = original + self.start = start + self.stop = stop + self.rotation = original + " " + + @property + def next_rotation(self): + first = self.rotation[0] + self.rotation = self.rotation[1:] + first + return self.rotation[:-1] + + +def replace_by_index(base, replacement, index): + if index < 0: # add it to the beginning + return replacement + base + if index > len(base): # add it to the end + return base + replacement + replacement_len = len(replacement) + # insert the new string between "slices" of the original + return base[:index] + replacement + base[index + replacement_len :]