[ZILANT] коррекция логики проверки добавленных ссылок
This commit is contained in:
@@ -20,4 +20,4 @@ alwaysApply: true
|
|||||||
|
|
||||||
5. Не поднимать версию за косметические правки без изменения поведения.
|
5. Не поднимать версию за косметические правки без изменения поведения.
|
||||||
|
|
||||||
Текущая базовая версия: **1.1.3**.
|
Текущая базовая версия: **1.1.4**.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Zilant / VOLK — Telegram poster и подписки
|
# Zilant / VOLK — Telegram poster и подписки
|
||||||
|
|
||||||
**Версия:** 1.1.3 ([`VERSION`](VERSION))
|
**Версия:** 1.1.4 ([`VERSION`](VERSION))
|
||||||
|
|
||||||
Автоматическая публикация постов и событий в Telegram-канал, веб-редактор, бот подписок с сезонными deep link.
|
Автоматическая публикация постов и событий в Telegram-канал, веб-редактор, бот подписок с сезонными deep link.
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,16 @@
|
|||||||
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/).
|
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/).
|
||||||
Версия проекта — в файле [`VERSION`](../VERSION) (SemVer).
|
Версия проекта — в файле [`VERSION`](../VERSION) (SemVer).
|
||||||
|
|
||||||
|
## [1.1.4] - 2026-09-02
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Проверка footer-ссылок после edit: убрано сравнение `min_length` (HTML длиннее plain text от Telegram) — лишние retry, мигание ссылок и обрыв пакетной публикации из UI.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Проверка footer-ссылок: убрано сравнение `min_length` (HTML длиннее plain text от Telegram).
|
||||||
|
|
||||||
## [1.1.3] - 2026-09-02
|
## [1.1.3] - 2026-09-02
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
+5
-9
@@ -134,7 +134,7 @@ async def download_image(image_url, httpx_client):
|
|||||||
|
|
||||||
|
|
||||||
async def _edit_event_add_links(
|
async def _edit_event_add_links(
|
||||||
httpx_client, has_image, message_id, final_text, entity_label, expected_urls, min_length
|
httpx_client, has_image, message_id, final_text, entity_label, expected_urls
|
||||||
):
|
):
|
||||||
"""Edit caption/text со ссылками; повтор до подтверждения всех expected_urls в text_link."""
|
"""Edit caption/text со ссылками; повтор до подтверждения всех expected_urls в text_link."""
|
||||||
await asyncio.sleep(EDIT_LINKS_INITIAL_DELAY_SEC)
|
await asyncio.sleep(EDIT_LINKS_INITIAL_DELAY_SEC)
|
||||||
@@ -179,9 +179,7 @@ async def _edit_event_add_links(
|
|||||||
result = data.get('result') or {}
|
result = data.get('result') or {}
|
||||||
result_text = result.get(field) or ""
|
result_text = result.get(field) or ""
|
||||||
entities = result.get(entities_field) or []
|
entities = result.get(entities_field) or []
|
||||||
if published_message_has_expected_links(
|
if published_message_has_expected_links(entities, expected_urls):
|
||||||
entities, expected_urls, result_text=result_text, min_length=min_length
|
|
||||||
):
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Ссылки добавлены для {entity_label} "
|
f"Ссылки добавлены для {entity_label} "
|
||||||
f"(попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS})"
|
f"(попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS})"
|
||||||
@@ -191,8 +189,7 @@ async def _edit_event_add_links(
|
|||||||
logger.warning(
|
logger.warning(
|
||||||
f"edit ok, но footer-ссылки не подтверждены "
|
f"edit ok, но footer-ссылки не подтверждены "
|
||||||
f"(попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS}) для {entity_label}; "
|
f"(попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS}) для {entity_label}; "
|
||||||
f"ожидались {expected_urls}, найдены text_link: {found}, "
|
f"ожидались {expected_urls}, найдены text_link: {found}"
|
||||||
f"len(text)={len(result_text)}, min_len={min_length}"
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
error_code = data.get('error_code')
|
error_code = data.get('error_code')
|
||||||
@@ -548,7 +545,6 @@ async def tg_post_event(httpx_client, event_data):
|
|||||||
expected_urls.append(
|
expected_urls.append(
|
||||||
subscription_start_link(RESPONDER_BOT_NAME, "event", message_id)
|
subscription_start_link(RESPONDER_BOT_NAME, "event", message_id)
|
||||||
)
|
)
|
||||||
min_length = len(final_text) - 15
|
|
||||||
|
|
||||||
# Проверяем, изменился ли текст. Если нет - не редактируем сообщение
|
# Проверяем, изменился ли текст. Если нет - не редактируем сообщение
|
||||||
if final_text == initial_text:
|
if final_text == initial_text:
|
||||||
@@ -558,12 +554,12 @@ async def tg_post_event(httpx_client, event_data):
|
|||||||
entity_label = f"события {event_data['number']}"
|
entity_label = f"события {event_data['number']}"
|
||||||
links_ok = await _edit_event_add_links(
|
links_ok = await _edit_event_add_links(
|
||||||
httpx_client, message_is_photo, message_id, final_text, entity_label,
|
httpx_client, message_is_photo, message_id, final_text, entity_label,
|
||||||
expected_urls, min_length,
|
expected_urls,
|
||||||
)
|
)
|
||||||
if not links_ok and message_is_photo:
|
if not links_ok and message_is_photo:
|
||||||
links_ok = await _edit_event_add_links(
|
links_ok = await _edit_event_add_links(
|
||||||
httpx_client, False, message_id, final_text, entity_label,
|
httpx_client, False, message_id, final_text, entity_label,
|
||||||
expected_urls, min_length,
|
expected_urls,
|
||||||
)
|
)
|
||||||
if not links_ok:
|
if not links_ok:
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|||||||
+3
-19
@@ -72,27 +72,16 @@ def extract_text_link_urls(entities) -> list:
|
|||||||
return urls
|
return urls
|
||||||
|
|
||||||
|
|
||||||
def published_message_has_expected_links(
|
def published_message_has_expected_links(entities, expected_urls) -> bool:
|
||||||
entities,
|
|
||||||
expected_urls,
|
|
||||||
*,
|
|
||||||
result_text: str | None = None,
|
|
||||||
min_length: int | None = None,
|
|
||||||
) -> bool:
|
|
||||||
"""
|
"""
|
||||||
Проверка, что в сообщении есть именно footer-ссылки публикации.
|
Проверка, что в сообщении есть именно footer-ссылки публикации.
|
||||||
|
|
||||||
Нельзя проверять «любой text_link» или слова «Инфо»/«Подписка» в тексте:
|
Сравнение только по URL в text_link entities (plain text короче HTML).
|
||||||
в теле события могут быть свои <a href> из replace_vk_links.
|
|
||||||
"""
|
"""
|
||||||
expected_urls = [u for u in (expected_urls or []) if u]
|
expected_urls = [u for u in (expected_urls or []) if u]
|
||||||
if not expected_urls:
|
if not expected_urls:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if min_length is not None and result_text is not None:
|
|
||||||
if len(result_text) < min_length:
|
|
||||||
return False
|
|
||||||
|
|
||||||
found = set(extract_text_link_urls(entities))
|
found = set(extract_text_link_urls(entities))
|
||||||
return all(url in found for url in expected_urls)
|
return all(url in found for url in expected_urls)
|
||||||
|
|
||||||
@@ -100,12 +89,7 @@ def published_message_has_expected_links(
|
|||||||
def published_message_has_links(text: str, entities=None, expected_urls=None) -> bool:
|
def published_message_has_links(text: str, entities=None, expected_urls=None) -> bool:
|
||||||
"""Проверка footer-ссылок; expected_urls обязателен при вызове из publisher."""
|
"""Проверка footer-ссылок; expected_urls обязателен при вызове из publisher."""
|
||||||
if expected_urls is not None:
|
if expected_urls is not None:
|
||||||
return published_message_has_expected_links(
|
return published_message_has_expected_links(entities, expected_urls)
|
||||||
entities,
|
|
||||||
expected_urls,
|
|
||||||
result_text=text,
|
|
||||||
min_length=None,
|
|
||||||
)
|
|
||||||
return bool(extract_text_link_urls(entities))
|
return bool(extract_text_link_urls(entities))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+4
-9
@@ -156,7 +156,7 @@ async def download_image(image_url, httpx_client):
|
|||||||
|
|
||||||
|
|
||||||
async def _edit_post_add_links(
|
async def _edit_post_add_links(
|
||||||
bot, message_id, message_has_image, final_text, vk_post_id, expected_urls, min_length
|
bot, message_id, message_has_image, final_text, vk_post_id, expected_urls
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Второй шаг публикации: editMessageCaption/Text со ссылками.
|
Второй шаг публикации: editMessageCaption/Text со ссылками.
|
||||||
@@ -186,9 +186,7 @@ async def _edit_post_add_links(
|
|||||||
published_text = edited.text or ""
|
published_text = edited.text or ""
|
||||||
entities = edited.entities or []
|
entities = edited.entities or []
|
||||||
|
|
||||||
if published_message_has_expected_links(
|
if published_message_has_expected_links(entities, expected_urls):
|
||||||
entities, expected_urls, result_text=published_text, min_length=min_length
|
|
||||||
):
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Ссылки добавлены для записи VK ID {vk_post_id} "
|
f"Ссылки добавлены для записи VK ID {vk_post_id} "
|
||||||
f"(попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS})"
|
f"(попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS})"
|
||||||
@@ -199,8 +197,7 @@ async def _edit_post_add_links(
|
|||||||
logger.warning(
|
logger.warning(
|
||||||
f"editMessage* ok, но footer-ссылки не подтверждены "
|
f"editMessage* ok, но footer-ссылки не подтверждены "
|
||||||
f"(попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS}) для VK ID {vk_post_id}; "
|
f"(попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS}) для VK ID {vk_post_id}; "
|
||||||
f"ожидались {expected_urls}, найдены text_link: {found}, "
|
f"ожидались {expected_urls}, найдены text_link: {found}"
|
||||||
f"len(text)={len(published_text)}, min_len={min_length}"
|
|
||||||
)
|
)
|
||||||
except TimedOut as e:
|
except TimedOut as e:
|
||||||
if attempt >= EDIT_LINKS_MAX_ATTEMPTS:
|
if attempt >= EDIT_LINKS_MAX_ATTEMPTS:
|
||||||
@@ -534,11 +531,9 @@ async def publish_to_tg(vk_post_id):
|
|||||||
expected_urls.append(
|
expected_urls.append(
|
||||||
subscription_start_link(RESPONDER_BOT_NAME, "post", message_id)
|
subscription_start_link(RESPONDER_BOT_NAME, "post", message_id)
|
||||||
)
|
)
|
||||||
min_length = len(final_text) - 15
|
|
||||||
|
|
||||||
if not await _edit_post_add_links(
|
if not await _edit_post_add_links(
|
||||||
bot, message_id, message_has_image, final_text, vk_post_id,
|
bot, message_id, message_has_image, final_text, vk_post_id,
|
||||||
expected_urls, min_length,
|
expected_urls,
|
||||||
):
|
):
|
||||||
logger.error(
|
logger.error(
|
||||||
f"Запись VK ID {vk_post_id}: сообщение отправлено (id={message_id}), "
|
f"Запись VK ID {vk_post_id}: сообщение отправлено (id={message_id}), "
|
||||||
|
|||||||
Reference in New Issue
Block a user