Video downloads are retried in an hour, if they are live.
Some checks are pending
CodeQL / Analyze (push) Waiting to run
Controller Tests / controller-tests (push) Waiting to run
Jest Tests / jest-tests (push) Waiting to run

This commit is contained in:
Roland 2026-03-06 15:22:27 -07:00
parent b73685c6f4
commit d2d09da296
No known key found for this signature in database
GPG key ID: 1BA620CE6C9A4680
3 changed files with 41 additions and 1 deletions

View file

@ -639,14 +639,18 @@ class VideoDownloader(Downloader, ABC):
if not video_path.is_file():
error = f'{stdout}\n\n\n{stderr}\n\n' \
f'Video file could not be found! {video_path}'
retry_seconds = None
if '!is_live' in stdout:
error = f'{stdout}\n\nVideo was live and did not finish downloading.'
retry_seconds = 3600
if ' live event ' in stdout:
error = f'{stdout}\n\nVideo will be live and did not finish downloading.'
retry_seconds = 3600
return DownloadResult(
success=False,
error=error,
location=location,
retry_seconds=retry_seconds,
)
if not ffmpeg_video_complete(video_path):

View file

@ -821,3 +821,35 @@ async def test_video_download_uses_effective_settings(test_session, test_directo
assert '--sleep-requests' in cmd, 'sleep_requests override should appear in command'
sleep_idx = cmd.index('--sleep-requests')
assert cmd[sleep_idx + 1] == '5.0', f'Expected sleep_requests=5.0, got {cmd[sleep_idx + 1]}'
@pytest.mark.asyncio
async def test_live_video_retry_seconds(test_session, test_directory, mock_video_extract_info,
video_download_manager, mock_video_process_runner,
simple_channel):
"""A live video download should return retry_seconds=3600 so it retries in 1 hour."""
from wrolpi.cmd import CommandResult
simple_channel.source_id = example_video_json['channel_id']
simple_channel.directory = test_directory / 'videos/channel name'
simple_channel.directory.mkdir(parents=True)
# Simulate yt-dlp output when a video is live.
mock_video_process_runner.return_value = CommandResult(
return_code=0, cancelled=False,
stdout=b'does not pass filter (!is_live), skipping ..', stderr=b'', elapsed=0,
)
url = 'https://www.youtube.com/watch?v=live_video'
mock_video_extract_info.return_value = example_video_json
with mock.patch('modules.videos.downloader.VideoDownloader.prepare_filename') as mock_prepare_filename:
# Return a path that won't exist (video wasn't downloaded because it's live).
mock_prepare_filename.return_value = (simple_channel.directory / 'live video.mp4', {'id': 'foo'})
download = Download(url=url, downloader='video', attempts=0)
result = await video_downloader.do_download(download)
assert result.success is False
assert result.retry_seconds == 3600
assert 'live' in result.error.lower()

View file

@ -87,6 +87,7 @@ class DownloadResult:
error: str = None
info_json: dict = field(default_factory=dict)
location: str = None
retry_seconds: int = None
success: bool = False
settings: dict = field(default_factory=dict)
@ -1286,7 +1287,10 @@ async def signal_download_download(download_id: int, download_url: str):
download.location = result.location or download.location or None
# Clear any old errors if the download succeeded.
download.error = result.error if result.error else None
download.next_download = download_manager.calculate_next_download(session, download)
if isinstance(result.retry_seconds, int):
download.next_download = now() + timedelta(seconds=result.retry_seconds)
else:
download.next_download = download_manager.calculate_next_download(session, download)
urls = download.filter_excluded(result.downloads) if result.downloads else None
if urls: