Add new file
This commit is contained in:
71
core/utils/layout_converter.py
Normal file
71
core/utils/layout_converter.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# -*- 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
|
||||||
Reference in New Issue
Block a user