[ZILANT] отправлять картинки при посте событий как файл, а не как URL; делаем как при репосте ВК постов
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
+48
-5
@@ -6,6 +6,7 @@ import time
|
||||
import html
|
||||
import httpx
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from urllib.parse import urlparse, unquote
|
||||
from dotenv import load_dotenv
|
||||
from formatter import get_event_text
|
||||
from telegram_relay import bot_api_method_url
|
||||
@@ -92,6 +93,39 @@ def prepare_text(text):
|
||||
|
||||
return text
|
||||
|
||||
|
||||
def _filename_from_image_url(image_url):
|
||||
path = unquote(urlparse(image_url).path)
|
||||
name = os.path.basename(path) or "image.jpg"
|
||||
if "." not in name:
|
||||
name = f"{name}.jpg"
|
||||
return name
|
||||
|
||||
|
||||
async def download_image(image_url, httpx_client):
|
||||
"""Скачивает картинку самим сервером (как tg_publish), не отдаёт URL Telegram.
|
||||
|
||||
sendPhoto с photo=http://... Telegram качает сам и часто отвечает
|
||||
«failed to get HTTP URL content» (http, недоступность с DC Telegram).
|
||||
"""
|
||||
logger.info(f"Скачивание изображения: {image_url}")
|
||||
started = time.time()
|
||||
response = await httpx_client.get(
|
||||
image_url,
|
||||
timeout=httpx.Timeout(connect=10.0, read=60.0, write=30.0, pool=10.0),
|
||||
)
|
||||
response.raise_for_status()
|
||||
image_data = response.content
|
||||
content_type = (response.headers.get("content-type") or "image/jpeg").split(";")[0].strip()
|
||||
if not content_type.startswith("image/"):
|
||||
content_type = "image/jpeg"
|
||||
logger.info(
|
||||
f"Изображение скачано за {time.time() - started:.2f} с, "
|
||||
f"размер: {len(image_data)} байт, type={content_type}"
|
||||
)
|
||||
return image_data, content_type, _filename_from_image_url(image_url)
|
||||
|
||||
|
||||
async def tg_post_event(httpx_client, event_data):
|
||||
"""Публикация одного события"""
|
||||
try:
|
||||
@@ -197,15 +231,24 @@ async def tg_post_event(httpx_client, event_data):
|
||||
|
||||
if has_image:
|
||||
try:
|
||||
logger.info(f"Попытка отправки фото для события {event_data['number']}: chat_id={CHANNEL_ID}, caption_length={len(initial_text)}, image_url_length={len(image_url)}")
|
||||
photo_payload = {
|
||||
logger.info(
|
||||
f"Попытка отправки фото для события {event_data['number']}: "
|
||||
f"chat_id={CHANNEL_ID}, caption_length={len(initial_text)}, "
|
||||
f"image_url={image_url}"
|
||||
)
|
||||
image_data, content_type, filename = await download_image(image_url, httpx_client)
|
||||
photo_data = {
|
||||
'chat_id': CHANNEL_ID,
|
||||
'photo': image_url,
|
||||
'caption': initial_text,
|
||||
'parse_mode': 'HTML',
|
||||
'disable_notification': PUBLISH_SILENTLY
|
||||
'disable_notification': 'true' if PUBLISH_SILENTLY else 'false',
|
||||
}
|
||||
photo_response = await httpx_client.post(send_photo_url, json=photo_payload)
|
||||
photo_files = {
|
||||
'photo': (filename, image_data, content_type),
|
||||
}
|
||||
photo_response = await httpx_client.post(
|
||||
send_photo_url, data=photo_data, files=photo_files
|
||||
)
|
||||
|
||||
if photo_response.status_code == 200:
|
||||
photo_result = photo_response.json()
|
||||
|
||||
Reference in New Issue
Block a user