Support full 2GB/2h video downloads via Local Bot API, clean VK wiki links and remove fallback links
This commit is contained in:
+4
-4
@@ -55,11 +55,11 @@ class Settings(BaseSettings):
|
||||
|
||||
# Media & Video Limits
|
||||
video_max_size_mb_cloud: int = 49
|
||||
video_max_size_mb_local: int = 500
|
||||
video_max_duration_sec: int = 600
|
||||
video_max_size_mb_local: int = 2000
|
||||
video_max_duration_sec: int = 7200
|
||||
video_max_height: int = 720
|
||||
media_download_timeout_sec: int = 60
|
||||
yt_dlp_timeout_sec: int = 300
|
||||
media_download_timeout_sec: int = 120
|
||||
yt_dlp_timeout_sec: int = 600
|
||||
|
||||
# Text Styling & Decoration
|
||||
header_text: str = ""
|
||||
|
||||
+1
-8
@@ -243,15 +243,8 @@ class MAXPoster:
|
||||
logger.warning("MAX bot token or chat ID is not set; skipping MAX post.")
|
||||
return [], None
|
||||
|
||||
link_only = [m for m in media_items if m.is_link_only]
|
||||
link_text = ""
|
||||
if link_only:
|
||||
lines = [f"- {m.media_type}: {m.original_url}" for m in link_only]
|
||||
link_text = "\n\nМедиа по ссылке:\n" + "\n".join(lines)
|
||||
|
||||
full_raw = (raw_text + link_text).strip()
|
||||
formatted_text = format_post_text(
|
||||
full_raw,
|
||||
raw_text,
|
||||
parse_mode="html",
|
||||
bold_first_line=settings.format_first_line_bold,
|
||||
vk_url=vk_url,
|
||||
|
||||
@@ -131,6 +131,7 @@ class MediaProcessor:
|
||||
f"best[height<={settings.video_max_height}][filesize<{max_size}]"
|
||||
f"/best[height<={settings.video_max_height}]"
|
||||
f"/bestvideo[height<={settings.video_max_height}][filesize<{max_size}]+bestaudio/best"
|
||||
f"/bestvideo[height<={settings.video_max_height}]+bestaudio/best"
|
||||
f"/best[filesize<{max_size}]"
|
||||
f"/best"
|
||||
),
|
||||
|
||||
+40
-12
@@ -43,6 +43,35 @@ def strip_trailing_hashtags(text: str) -> str:
|
||||
return "\n".join(lines).rstrip()
|
||||
|
||||
|
||||
def clean_vk_wiki_links(text: str, parse_mode: str = "html") -> str:
|
||||
"""
|
||||
Converts VK wiki links to clickable links:
|
||||
- [club12345|Name] -> <a href="https://vk.com/club12345">Name</a>
|
||||
- [id12345|Name] -> <a href="https://vk.com/id12345">Name</a>
|
||||
- [public12345|Name] -> <a href="https://vk.com/public12345">Name</a>
|
||||
- [event12345|Name] -> <a href="https://vk.com/event12345">Name</a>
|
||||
- [https://example.com|Title] -> <a href="https://example.com">Title</a>
|
||||
"""
|
||||
def _replace_vk(match: re.Match) -> str:
|
||||
prefix = match.group(1)
|
||||
obj_id = match.group(2)
|
||||
title = match.group(3)
|
||||
if parse_mode == "html":
|
||||
return f'<a href="https://vk.com/{prefix}{obj_id}">{html.escape(title)}</a>'
|
||||
return f"[{title}](https://vk.com/{prefix}{obj_id})"
|
||||
|
||||
def _replace_url(match: re.Match) -> str:
|
||||
url = match.group(1)
|
||||
title = match.group(2)
|
||||
if parse_mode == "html":
|
||||
return f'<a href="{html.escape(url, quote=True)}">{html.escape(title)}</a>'
|
||||
return f"[{title}]({url})"
|
||||
|
||||
text = re.sub(r"\[(club|id|public|event)(\d+)\|([^\]]+)\]", _replace_vk, text)
|
||||
text = re.sub(r"\[(https?://[^\s\|]+)\|([^\]]+)\]", _replace_url, text)
|
||||
return text
|
||||
|
||||
|
||||
def format_post_text(
|
||||
raw_text: str,
|
||||
*,
|
||||
@@ -68,31 +97,30 @@ def format_post_text(
|
||||
|
||||
formatted_lines: list[str] = []
|
||||
for idx, line in enumerate(lines):
|
||||
if idx == title_idx and bold_first_line and line.strip():
|
||||
cleaned_line = clean_vk_wiki_links(line, parse_mode=parse_mode) if parse_mode == "html" else line
|
||||
if idx == title_idx and bold_first_line and cleaned_line.strip():
|
||||
if parse_mode == "html":
|
||||
escaped = html.escape(line.strip())
|
||||
formatted_lines.append(f"<b>{escaped}</b>")
|
||||
# If clean_vk_wiki_links was run, keep existing <a> tags safe
|
||||
formatted_lines.append(f"<b>{cleaned_line.strip()}</b>")
|
||||
else:
|
||||
formatted_lines.append(f"**{line.strip()}**")
|
||||
formatted_lines.append(f"**{cleaned_line.strip()}**")
|
||||
# Blank line after header if next line is not empty
|
||||
if idx + 1 < len(lines) and lines[idx + 1].strip() != "":
|
||||
formatted_lines.append("")
|
||||
else:
|
||||
if parse_mode == "html":
|
||||
formatted_lines.append(html.escape(line))
|
||||
else:
|
||||
formatted_lines.append(line)
|
||||
formatted_lines.append(cleaned_line)
|
||||
|
||||
normalized_body = re.sub(r"\n{3,}", "\n\n", "\n".join(formatted_lines)).strip()
|
||||
raw_body = "\n".join(formatted_lines)
|
||||
normalized_body = re.sub(r"\n{3,}", "\n\n", raw_body).strip()
|
||||
|
||||
parts: list[str] = []
|
||||
if header:
|
||||
parts.append(html.escape(header) if parse_mode == "html" else header)
|
||||
parts.append(html.escape(header) if parse_mode == "html" and "<" not in header else header)
|
||||
if normalized_body:
|
||||
parts.append(normalized_body)
|
||||
if footer:
|
||||
parts.append(html.escape(footer) if parse_mode == "html" else footer)
|
||||
parts.append(html.escape(footer) if parse_mode == "html" and "<" not in footer else footer)
|
||||
if tags:
|
||||
parts.append(html.escape(tags) if parse_mode == "html" else tags)
|
||||
parts.append(html.escape(tags) if parse_mode == "html" and "<" not in tags else tags)
|
||||
|
||||
return "\n\n".join(part for part in parts if part).strip()
|
||||
|
||||
+1
-9
@@ -371,16 +371,8 @@ class TelegramPoster:
|
||||
3. Tries sendRichMessage first.
|
||||
4. If unavailable, falls back to legacy media groups / single media / text.
|
||||
"""
|
||||
# Append link-only media notice if any videos/photos couldn't be downloaded
|
||||
link_only = [m for m in media_items if m.is_link_only]
|
||||
link_text = ""
|
||||
if link_only:
|
||||
lines = [f"- {m.media_type}: <a href=\"{m.original_url}\">ссылка</a>" for m in link_only]
|
||||
link_text = "\n\n<i>Медиа по ссылке:</i>\n" + "\n".join(lines)
|
||||
|
||||
full_raw = (raw_text + link_text).strip()
|
||||
formatted_text = format_post_text(
|
||||
full_raw,
|
||||
raw_text,
|
||||
parse_mode="html",
|
||||
bold_first_line=settings.format_first_line_bold,
|
||||
vk_url=vk_url,
|
||||
|
||||
Reference in New Issue
Block a user