feat: add source websites with automated endpoint analysis, target queue dispatch ordering, and markdown styling

This commit is contained in:
mamad
2026-08-28 22:05:48 +03:30
parent 462ad3be93
commit 446f3ea041
11 changed files with 1100 additions and 32 deletions
+31 -15
View File
@@ -2,7 +2,7 @@ import os
import asyncio
import logging
from datetime import datetime, timedelta, timezone
from typing import Optional, List, Awaitable, Callable, Set, Tuple
from typing import Optional, List, Awaitable, Callable, Set, Tuple, Any
from telethon import TelegramClient
from telethon.errors import (
ChannelPrivateError,
@@ -35,6 +35,33 @@ PERMANENT_DELIVERY_ERRORS = (
PeerIdInvalidError,
)
async def send_styled_message(client: TelegramClient, entity: Any, text: str, file_path: Optional[str] = None):
"""Deliver message or media trying Markdown first, then HTML, then raw plain text."""
if not text and not file_path:
return None
# 1. Try standard Markdown first (AI's natural formatting)
try:
if file_path and os.path.exists(file_path):
return await client.send_file(entity, file=file_path, caption=text, parse_mode="md")
return await client.send_message(entity, text, parse_mode="md")
except Exception as md_err:
logger.debug(f"Markdown send failed ({md_err}), trying HTML...")
# 2. Try HTML format fallback
try:
if file_path and os.path.exists(file_path):
return await client.send_file(entity, file=file_path, caption=text, parse_mode="html")
return await client.send_message(entity, text, parse_mode="html")
except Exception as html_err:
logger.debug(f"HTML send failed ({html_err}), falling back to plain text...")
# 3. Plain text safety fallback
if file_path and os.path.exists(file_path):
return await client.send_file(entity, file=file_path, caption=text, parse_mode=None)
return await client.send_message(entity, text, parse_mode=None)
class PublisherService:
def __init__(
self,
@@ -129,7 +156,8 @@ class PublisherService:
continue
# 3. Pop next post payload for this target
payload = await self.queue.pop_target_post(target.id)
disp_order = getattr(target, "dispatch_order", "order") or "order"
payload = await self.queue.pop_target_post(target.id, dispatch_order=disp_order)
if not payload:
continue
@@ -138,19 +166,7 @@ class PublisherService:
media_path = payload.get("media_path")
try:
if media_path and os.path.exists(media_path):
await self.client.send_file(
target.channel_id,
file=media_path,
caption=text,
parse_mode="html"
)
else:
await self.client.send_message(
target.channel_id,
text,
parse_mode="html"
)
await send_styled_message(self.client, target.channel_id, text, file_path=media_path)
# Record publication in database
await self.repo.record_post_published_to_target(post_id, target.id, target.title or "Target")