mirror of
https://github.com/Dasemu/x-space-downloader.git
synced 2026-10-13 21:49:45 +00:00
feat: add downloader module with yt-dlp integration
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
46
src/downloader.py
Normal file
46
src/downloader.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import os
|
||||||
|
import yt_dlp
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
def download_space(
|
||||||
|
space_url: str,
|
||||||
|
output_dir: str,
|
||||||
|
cookies_file: Optional[str] = None
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Downloads X Space recording using yt-dlp.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
space_url: URL of the X Space recording
|
||||||
|
output_dir: Directory to save the MP3 file
|
||||||
|
cookies_file: Optional path to cookies file for authentication
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Path to the downloaded MP3 file
|
||||||
|
"""
|
||||||
|
# Extract space ID from URL for filename
|
||||||
|
space_id = space_url.split('/')[-1]
|
||||||
|
|
||||||
|
# Configure yt-dlp options
|
||||||
|
ydl_opts = {
|
||||||
|
'format': 'bestaudio/best',
|
||||||
|
'outtmpl': os.path.join(output_dir, f'space_{space_id}.%(ext)s'),
|
||||||
|
'postprocessors': [{
|
||||||
|
'key': 'FFmpegExtractAudio',
|
||||||
|
'preferredcodec': 'mp3',
|
||||||
|
}],
|
||||||
|
'quiet': False,
|
||||||
|
'no_warnings': False,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add cookies if provided
|
||||||
|
if cookies_file:
|
||||||
|
ydl_opts['cookiefile'] = cookies_file
|
||||||
|
|
||||||
|
# Download with yt-dlp
|
||||||
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||||
|
ydl.extract_info(space_url, download=True)
|
||||||
|
|
||||||
|
# Return the expected output path
|
||||||
|
return os.path.join(output_dir, f'space_{space_id}.mp3')
|
||||||
27
tests/test_downloader.py
Normal file
27
tests/test_downloader.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import pytest
|
||||||
|
from unittest.mock import Mock, patch
|
||||||
|
from src.downloader import download_space
|
||||||
|
|
||||||
|
|
||||||
|
def test_download_space_basic(tmp_path):
|
||||||
|
"""Test basic download functionality."""
|
||||||
|
space_url = "https://x.com/i/spaces/1ZkKzZWnVRRKv"
|
||||||
|
|
||||||
|
with patch('src.downloader.yt_dlp.YoutubeDL') as mock_ytdl_class:
|
||||||
|
# Mock the YoutubeDL instance
|
||||||
|
mock_ytdl = Mock()
|
||||||
|
mock_ytdl_class.return_value.__enter__.return_value = mock_ytdl
|
||||||
|
mock_ytdl.extract_info.return_value = {'id': '1ZkKzZWnVRRKv'}
|
||||||
|
|
||||||
|
# Call download_space
|
||||||
|
result = download_space(
|
||||||
|
space_url=space_url,
|
||||||
|
output_dir=str(tmp_path),
|
||||||
|
cookies_file=None
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify YoutubeDL was called
|
||||||
|
mock_ytdl.extract_info.assert_called_once_with(space_url, download=True)
|
||||||
|
|
||||||
|
# Verify result contains expected filename
|
||||||
|
assert "space_1ZkKzZWnVRRKv" in result
|
||||||
Reference in New Issue
Block a user