From d01a17146ed35cbe6f879a5657f089a2a7ffbafa Mon Sep 17 00:00:00 2001 From: exostring Date: Fri, 4 Sep 2026 23:24:06 +0500 Subject: [PATCH] Retry oversized video downloads instead of giving up permanently MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VK can briefly serve a not-yet-transcoded master stream on a capped-height URL right after a video is published, tripping the size check on the very first attempt. Treat that as transient (retry with a longer backoff) instead of failing permanently, and merge the fallback note into a single "Смотреть видео в VK" link instead of two separate lines. Co-Authored-By: Claude Sonnet 5 --- src/media_processor.py | 13 +++++++++---- src/text_formatter.py | 18 +++++++++--------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/media_processor.py b/src/media_processor.py index 3a903e7..09fcfc1 100644 --- a/src/media_processor.py +++ b/src/media_processor.py @@ -112,11 +112,16 @@ class MediaProcessor: return path, err, is_permanent last_result = (path, err, is_permanent) if attempt <= settings.yt_dlp_retry_attempts: + # A fresh upload's lower-quality renditions can still be mid-transcode on + # VK's side - the "720p" URL then briefly serves the full-res master until + # the ladder catches up, which trips our size cap. That's not a permanent + # rejection, just needs more time than a stalled connection does. + delay = 60.0 if "exceeds size limit" in (err or "") else 3.0 logger.warning( - "yt-dlp attempt {}/{} failed transiently for {}: {} - retrying", - attempt, settings.yt_dlp_retry_attempts + 1, url, err, + "yt-dlp attempt {}/{} failed transiently for {}: {} - retrying in {}s", + attempt, settings.yt_dlp_retry_attempts + 1, url, err, delay, ) - await asyncio.sleep(3.0) + await asyncio.sleep(delay) return last_result async def _download_video_ytdlp_attempt( @@ -219,7 +224,7 @@ class MediaProcessor: ) output_path.unlink(missing_ok=True) await unregister_active_path(output_path) - return None, "video exceeds size limit", True + return None, "video exceeds size limit", False return output_path, None, False diff --git a/src/text_formatter.py b/src/text_formatter.py index 8e05e45..3cc2665 100644 --- a/src/text_formatter.py +++ b/src/text_formatter.py @@ -154,18 +154,18 @@ def build_media_unavailable_note( media_type = str(getattr(item, "media_type", "медиа") or "медиа") if not url: continue - label = "Смотреть видео" if media_type == "video" else media_type - if parse_mode == "html": - lines.append(f'- {html.escape(label)}') + if media_type == "video": + target = vk_url or url + label = "Смотреть видео в VK" else: - lines.append(f"- {label}: {url}") + target = url + label = media_type + if parse_mode == "html": + lines.append(f'- {html.escape(label)}') + else: + lines.append(f"- {label}: {target}") if not lines: return "" - if vk_url: - if parse_mode == "html": - lines.append(f'- Открыть пост в VK') - else: - lines.append(f"- пост в VK: {vk_url}") header = "Не поместилось в пост:" if parse_mode == "html": header = f"{html.escape(header)}"