Files
fckbot/core/utils/layout_converter.py
Markov Andrey bf563a4a69 Add new file
2026-06-30 09:26:13 +00:00

71 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
Конвертер раскладки клавиатуры: определяет, в какой раскладке (русской или английской)
набран текст, и при необходимости переключает её.
Используется для исправления сообщений, набранных по ошибке не в той раскладке.
"""
import logging
logger = logging.getLogger(__name__)
def convert_layout(text: str) -> str:
"""
Определяет, в какой раскладке набран текст, и переключает, если нужно.
Команды (начинающиеся с ! или /) и ссылки (http://) не трогает.
Алгоритм:
1. Если текст начинается с http://, https://, ! или / возвращается без изменений.
2. Составляем таблицы перевода: английские символы -> русские и наоборот.
3. Если в тексте есть и русские, и английские символы считаем, что всё правильно (не переключаем).
4. Считаем количество гласных букв в английской и русской раскладках для исходного текста
и для его переведённых вариантов.
5. Выбираем вариант с наибольшим количеством гласных (вероятная правильная раскладка).
6. Если гласных поровну или нет ни одной, возвращаем исходный текст.
"""
if not text:
return text
# Не трогаем команды и ссылки
if text.startswith('http') or text.startswith(('!', '/')):
return text
# Таблицы соответствия символов (раскладка QWERTY / ЙЦУКЕН)
en_chars = "qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?~"
ru_chars = "йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,Ё"
to_ru = str.maketrans(en_chars, ru_chars) # таблица для перевода английской раскладки в русскую
to_en = str.maketrans(ru_chars, en_chars) # таблица для перевода русской раскладки в английскую
# Проверяем, есть ли символы обеих раскладок в тексте
has_russian = any('а' <= c <= 'я' or 'А' <= c <= 'Я' for c in text)
has_english = any('a' <= c <= 'z' or 'A' <= c <= 'Z' for c in text)
if has_russian and has_english:
# Смесь вероятно, уже правильно
return text
# Гласные буквы для подсчёта (в английской и русской раскладках)
eng_vowels = "aeiouyAEIOUY"
ru_vowels = "аеёиоуыэюяАЕЁИОУЫЭЮЯ"
orig_en_vowels = sum(1 for c in text if c in eng_vowels)
orig_ru_vowels = sum(1 for c in text if c in ru_vowels)
# Переводим текст в другую раскладку
translated_en = text.translate(to_en) # русская -> английская
translated_ru = text.translate(to_ru) # английская -> русская
trans_en_vowels = sum(1 for c in translated_en if c in eng_vowels)
trans_ru_vowels = sum(1 for c in translated_ru if c in ru_vowels)
# Если в исходном тексте нет русских символов, но при переводе в русскую раскладку
# появляется больше гласных, значит, текст был набран в английской раскладке.
if not has_russian and trans_ru_vowels > orig_en_vowels:
return translated_ru
# Если в исходном тексте нет английских символов, но при переводе в английскую раскладку
# появляется больше гласных, значит, текст был набран в русской раскладке.
if has_russian and trans_en_vowels > orig_ru_vowels:
return translated_en
return text