Upload files to "/"
This commit is contained in:
+156
@@ -0,0 +1,156 @@
|
||||
import re
|
||||
|
||||
def truncate_text(text, max_length):
|
||||
"""Обрезает текст до максимальной длины с учетом границ слов"""
|
||||
if text is None or not text:
|
||||
return ""
|
||||
|
||||
if len(text) <= max_length:
|
||||
return text
|
||||
|
||||
# Ищем последний пробел перед максимальной длиной
|
||||
truncated = text[:max_length]
|
||||
last_space = truncated.rfind(' ')
|
||||
|
||||
if last_space > 0:
|
||||
return truncated[:last_space] + "..."
|
||||
return truncated[:max_length-3] + "..."
|
||||
|
||||
def safe_text(text):
|
||||
"""Обеспечивает безопасное использование текста (заменяет None на пустую строку)"""
|
||||
return text if text is not None else ""
|
||||
|
||||
def replace_vk_links(text):
|
||||
"""
|
||||
Заменяет ссылки на сообщества ВК в форматах:
|
||||
[club123|Название сообщества] -> Название сообщества
|
||||
[id456|Имя пользователя] -> Имя пользователя
|
||||
"""
|
||||
if not text:
|
||||
return text
|
||||
|
||||
# Регулярное выражение для поиска ссылок формата [типID|Текст]
|
||||
pattern = r'\[(?:club|id)\d+\|([^\]]+)\]'
|
||||
|
||||
# Заменяем все вхождения на текст внутри ссылки
|
||||
return re.sub(pattern, r'\1', text)
|
||||
|
||||
def remove_html_tags(text):
|
||||
"""Удаляет HTML-теги с учетом специальной обработки <p> и <a>"""
|
||||
if not text:
|
||||
return text
|
||||
|
||||
# Заменяем <p> и </p> на переносы строк
|
||||
text = re.sub(r'</?p\s*/?>', '\n', text, flags=re.IGNORECASE)
|
||||
|
||||
# Обрабатываем ссылки <a href="URL">Текст</a> -> Текст (URL)
|
||||
def replace_a_tag(match):
|
||||
url = match.group(1)
|
||||
link_text = match.group(2)
|
||||
return f"{link_text} ({url})"
|
||||
|
||||
text = re.sub(
|
||||
r'<a\s+href="([^"]*)"[^>]*>(.*?)</a>',
|
||||
replace_a_tag,
|
||||
text,
|
||||
flags=re.IGNORECASE | re.DOTALL
|
||||
)
|
||||
|
||||
# Удаляем все оставшиеся HTML-теги
|
||||
text = re.sub(r'<[^>]+>', '', text)
|
||||
|
||||
# Схлопываем множественные переносы строк
|
||||
text = re.sub(r'\n+', '\n', text)
|
||||
|
||||
return text.strip()
|
||||
|
||||
def get_event_text(text, limit=950):
|
||||
"""
|
||||
Обрабатывает текст: удаляет HTML-теги и VK-ссылки, обрезает до указанной длины
|
||||
:param text: исходный текст
|
||||
:param limit: максимальная длина текста (по умолчанию 950)
|
||||
:return: обработанный текст
|
||||
"""
|
||||
if not text:
|
||||
return ""
|
||||
|
||||
# Удаляем HTML-теги
|
||||
cleaned_text = remove_html_tags(text)
|
||||
# Обрабатываем VK-ссылки
|
||||
cleaned_text = replace_vk_links(cleaned_text)
|
||||
# Обрезаем текст до указанной длины
|
||||
return truncate_text(cleaned_text, limit)
|
||||
|
||||
def get_post_text(post_data, max_caption_length=1000, max_text_length=4000):
|
||||
"""
|
||||
Форматирует пост для публикации в Telegram
|
||||
Возвращает словарь с элементами:
|
||||
{
|
||||
'base_text': основной текст поста,
|
||||
'image_url': URL изображения (или None),
|
||||
'vk_link': HTML-ссылка на оригинал в ВК,
|
||||
'caption': подпись для изображения (с учетом ограничений длины),
|
||||
'text_message': текстовое сообщение (с учетом ограничений длины),
|
||||
'has_poll': есть ли опрос,
|
||||
'is_event': является ли пост событием,
|
||||
'poll_question': вопрос опроса,
|
||||
'poll_options': варианты ответов опроса,
|
||||
'poll_multiple': разрешен ли множественный выбор
|
||||
}
|
||||
"""
|
||||
# Извлекаем данные из кортежа
|
||||
vk_post_id = post_data[0]
|
||||
text_content = safe_text(post_data[1])
|
||||
image_url = safe_text(post_data[2])
|
||||
vk_post_url = safe_text(post_data[3])
|
||||
poll_question = safe_text(post_data[4])
|
||||
poll_options = safe_text(post_data[5])
|
||||
poll_multiple = post_data[6]
|
||||
is_event = post_data[7]
|
||||
has_poll = post_data[8] # Извлекаем значение is_poll
|
||||
|
||||
# Обрабатываем текст: заменяем ссылки на сообщества ВК
|
||||
text_content = replace_vk_links(text_content)
|
||||
|
||||
# Базовый текст - только содержимое поста
|
||||
base_text = text_content
|
||||
|
||||
vk_link = f'<a href="{vk_post_url}">Оригинал в ВК</a>' if vk_post_url else ""
|
||||
|
||||
# Формируем подпись для изображения
|
||||
caption = None
|
||||
if image_url:
|
||||
full_caption = f"{base_text}\n\n{vk_link}" if vk_link else base_text
|
||||
|
||||
if len(full_caption) > max_caption_length:
|
||||
available_length = max_caption_length - (len(vk_link) + 10) if vk_link else 0
|
||||
truncated_text = truncate_text(base_text, available_length)
|
||||
caption = f"{truncated_text}\n\n{vk_link}" if vk_link else truncated_text
|
||||
else:
|
||||
caption = full_caption
|
||||
|
||||
# Формируем текстовое сообщение (для постов без изображения)
|
||||
text_message = None
|
||||
if not image_url:
|
||||
full_message = f"{base_text}\n\n{vk_link}" if vk_link else base_text
|
||||
|
||||
if len(full_message) > max_text_length:
|
||||
available_length = max_text_length - (len(vk_link) + 10) if vk_link else 0
|
||||
truncated_text = truncate_text(base_text, available_length)
|
||||
text_message = f"{truncated_text}\n\n{vk_link}" if vk_link else truncated_text
|
||||
else:
|
||||
text_message = full_message
|
||||
|
||||
return {
|
||||
'vk_post_id': vk_post_id,
|
||||
'base_text': base_text,
|
||||
'image_url': image_url if image_url else None,
|
||||
'vk_link': vk_link,
|
||||
'caption': caption,
|
||||
'text_message': text_message,
|
||||
'has_poll': has_poll, # Используем прямое значение из кортежа
|
||||
'is_event': is_event,
|
||||
'poll_question': poll_question,
|
||||
'poll_options': poll_options,
|
||||
'poll_multiple': poll_multiple
|
||||
}
|
||||
Reference in New Issue
Block a user