mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 02:48:38 -04:00
Using gnomekeyring for yt-dlp brave cookie parsing.
This commit is contained in:
parent
a49f67e117
commit
929468821b
4 changed files with 42 additions and 22 deletions
|
|
@ -124,6 +124,7 @@ def get_youtube_duration(video_url: str) -> Optional[int]:
|
|||
"""Get video duration using YouTube's internal API. Returns None if URL is not YouTube or API fails."""
|
||||
video_id = get_youtube_video_id(video_url)
|
||||
if not video_id:
|
||||
logger.debug(f'Could not extract YouTube video ID from {video_url}')
|
||||
return None
|
||||
|
||||
payload = {
|
||||
|
|
@ -145,10 +146,15 @@ def get_youtube_duration(video_url: str) -> Optional[int]:
|
|||
response.raise_for_status()
|
||||
data = response.json()
|
||||
length_seconds = data.get("videoDetails", {}).get("lengthSeconds")
|
||||
if length_seconds:
|
||||
if length_seconds is not None:
|
||||
return int(length_seconds)
|
||||
else:
|
||||
# Log why we couldn't get duration
|
||||
status = data.get("playabilityStatus", {}).get("status", "UNKNOWN")
|
||||
reason = data.get("playabilityStatus", {}).get("reason", "")
|
||||
logger.warning(f'YouTube API returned no duration for {video_url}: status={status} reason={reason}')
|
||||
except Exception as e:
|
||||
logger.debug(f'YouTube API failed for {video_url}: {e}')
|
||||
logger.debug(f'YouTube API request failed for {video_url}: {e}')
|
||||
|
||||
return None
|
||||
|
||||
|
|
@ -282,7 +288,8 @@ async def fetch_video_duration(url: str) -> int:
|
|||
return duration
|
||||
|
||||
# Try YouTube API first (faster than yt-dlp)
|
||||
if duration := get_youtube_duration(url):
|
||||
duration = get_youtube_duration(url)
|
||||
if duration is not None:
|
||||
logger.info(f'Fetched video duration of {duration} from {url} using YouTube API')
|
||||
return duration
|
||||
|
||||
|
|
|
|||
|
|
@ -1098,32 +1098,41 @@ def get_browser_profiles(home: pathlib.Path = WROLPI_HOME) -> dict:
|
|||
|
||||
|
||||
def browser_profile_to_yt_dlp_arg(profile: pathlib.Path) -> str:
|
||||
"""Takes a Path and returns a string that can be used as a yt-dlp `--cookies-from-browser` argument."""
|
||||
"""Takes a Path and returns a string that can be used as a yt-dlp `--cookies-from-browser` argument.
|
||||
|
||||
Format: BROWSER+KEYRING:PROFILE
|
||||
|
||||
We explicitly specify GNOMEKEYRING because yt-dlp's auto-detection relies on desktop environment
|
||||
variables which are not available when running as a systemd service.
|
||||
"""
|
||||
profile_str = str(profile)
|
||||
|
||||
for browser_key, config in BROWSER_CONFIGS.items():
|
||||
if config['config_path'] in profile_str:
|
||||
return f"{config['yt_dlp_name']}:{profile.name}"
|
||||
return f"{config['yt_dlp_name']}+GNOMEKEYRING:{profile.name}"
|
||||
|
||||
# Fallback to original behavior for unknown browsers
|
||||
*_, browser, profile_name = profile_str.split('/')
|
||||
return f'{browser}:{profile_name}'
|
||||
return f'{browser}+GNOMEKEYRING:{profile_name}'
|
||||
|
||||
|
||||
def browser_profile_to_yt_dlp_tuple(profile: pathlib.Path) -> tuple:
|
||||
"""Takes a Path and returns a tuple that can be used as yt-dlp `cookiesfrombrowser` option in Python API.
|
||||
|
||||
The yt-dlp Python API expects cookiesfrombrowser as a tuple: (browser, profile, keyring, container)
|
||||
|
||||
We explicitly specify GNOMEKEYRING because yt-dlp's auto-detection relies on desktop environment
|
||||
variables which are not available when running as a systemd service.
|
||||
"""
|
||||
profile_str = str(profile)
|
||||
|
||||
for browser_key, config in BROWSER_CONFIGS.items():
|
||||
if config['config_path'] in profile_str:
|
||||
return (config['yt_dlp_name'], profile.name, None, None)
|
||||
return (config['yt_dlp_name'], profile.name, 'GNOMEKEYRING', None)
|
||||
|
||||
# Fallback for unknown browsers
|
||||
*_, browser, profile_name = profile_str.split('/')
|
||||
return (browser, profile_name, None, None)
|
||||
return (browser, profile_name, 'GNOMEKEYRING', None)
|
||||
|
||||
|
||||
def format_video_filename(
|
||||
|
|
|
|||
|
|
@ -370,34 +370,37 @@ async def test_videos_downloader_config_api(async_client, test_directory, test_v
|
|||
|
||||
|
||||
@pytest.mark.parametrize('file_name,expected', [
|
||||
('/home/wrolpi/.config/chromium/Default', 'chromium:Default'),
|
||||
('/home/wrolpi/.config/chromium/Profile 1', 'chromium:Profile 1'),
|
||||
('/home/wrolpi/.mozilla/firefox/29el0wk0.default-release', 'firefox:29el0wk0.default-release'),
|
||||
('/home/wrolpi/.config/BraveSoftware/Brave-Browser/Default', 'brave:Default'),
|
||||
('/home/wrolpi/.config/BraveSoftware/Brave-Browser/Profile 1', 'brave:Profile 1'),
|
||||
('/home/wrolpi/.config/google-chrome/Default', 'chrome:Default'),
|
||||
('/home/wrolpi/.config/google-chrome/Profile 1', 'chrome:Profile 1'),
|
||||
('/home/wrolpi/.config/chromium/Default', 'chromium+GNOMEKEYRING:Default'),
|
||||
('/home/wrolpi/.config/chromium/Profile 1', 'chromium+GNOMEKEYRING:Profile 1'),
|
||||
('/home/wrolpi/.mozilla/firefox/29el0wk0.default-release', 'firefox+GNOMEKEYRING:29el0wk0.default-release'),
|
||||
('/home/wrolpi/.config/BraveSoftware/Brave-Browser/Default', 'brave+GNOMEKEYRING:Default'),
|
||||
('/home/wrolpi/.config/BraveSoftware/Brave-Browser/Profile 1', 'brave+GNOMEKEYRING:Profile 1'),
|
||||
('/home/wrolpi/.config/google-chrome/Default', 'chrome+GNOMEKEYRING:Default'),
|
||||
('/home/wrolpi/.config/google-chrome/Profile 1', 'chrome+GNOMEKEYRING:Profile 1'),
|
||||
])
|
||||
def test_browser_profile_to_yt_dlp_arg(file_name, expected):
|
||||
"""
|
||||
Test the conversion of a browser profile to yt-dlp arguments.
|
||||
Format: BROWSER+KEYRING:PROFILE
|
||||
Explicitly uses GNOMEKEYRING because yt-dlp auto-detection doesn't work in systemd services.
|
||||
"""
|
||||
file_name = pathlib.Path(file_name)
|
||||
assert lib.browser_profile_to_yt_dlp_arg(file_name) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('file_name,expected', [
|
||||
('/home/wrolpi/.config/chromium/Default', ('chromium', 'Default', None, None)),
|
||||
('/home/wrolpi/.config/chromium/Profile 1', ('chromium', 'Profile 1', None, None)),
|
||||
('/home/wrolpi/.mozilla/firefox/29el0wk0.default-release', ('firefox', '29el0wk0.default-release', None, None)),
|
||||
('/home/wrolpi/.config/BraveSoftware/Brave-Browser/Default', ('brave', 'Default', None, None)),
|
||||
('/home/wrolpi/.config/BraveSoftware/Brave-Browser/Profile 1', ('brave', 'Profile 1', None, None)),
|
||||
('/home/wrolpi/.config/google-chrome/Default', ('chrome', 'Default', None, None)),
|
||||
('/home/wrolpi/.config/google-chrome/Profile 1', ('chrome', 'Profile 1', None, None)),
|
||||
('/home/wrolpi/.config/chromium/Default', ('chromium', 'Default', 'GNOMEKEYRING', None)),
|
||||
('/home/wrolpi/.config/chromium/Profile 1', ('chromium', 'Profile 1', 'GNOMEKEYRING', None)),
|
||||
('/home/wrolpi/.mozilla/firefox/29el0wk0.default-release', ('firefox', '29el0wk0.default-release', 'GNOMEKEYRING', None)),
|
||||
('/home/wrolpi/.config/BraveSoftware/Brave-Browser/Default', ('brave', 'Default', 'GNOMEKEYRING', None)),
|
||||
('/home/wrolpi/.config/BraveSoftware/Brave-Browser/Profile 1', ('brave', 'Profile 1', 'GNOMEKEYRING', None)),
|
||||
('/home/wrolpi/.config/google-chrome/Default', ('chrome', 'Default', 'GNOMEKEYRING', None)),
|
||||
('/home/wrolpi/.config/google-chrome/Profile 1', ('chrome', 'Profile 1', 'GNOMEKEYRING', None)),
|
||||
])
|
||||
def test_browser_profile_to_yt_dlp_tuple(file_name, expected):
|
||||
"""
|
||||
Test the conversion of a browser profile to yt-dlp cookiesfrombrowser tuple.
|
||||
Explicitly uses GNOMEKEYRING because yt-dlp auto-detection doesn't work in systemd services.
|
||||
"""
|
||||
file_name = pathlib.Path(file_name)
|
||||
assert lib.browser_profile_to_yt_dlp_tuple(file_name) == expected
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue