Files
api-HydrusNetwork/scripts/linux-mpv-handler.py
T

89 lines
2.6 KiB
Python

#!/usr/bin/env python3
import base64
import os
import re
import subprocess
import sys
from pathlib import Path
from urllib.parse import parse_qs, urlparse
def decode_urlsafe_base64(value: str) -> str:
padding = '=' * (-len(value) % 4)
return base64.urlsafe_b64decode(f'{value}{padding}').decode('utf-8')
def read_config_value(config_path: Path, key: str) -> str:
if not config_path.is_file():
return ''
pattern = re.compile(rf'^\s*#?\s*{re.escape(key)}\s*=\s*"([^"]*)"\s*$')
for line in config_path.read_text(encoding='utf-8').splitlines():
match = pattern.match(line)
if match:
return match.group(1).strip()
return ''
def resolve_mpv_command(config_path: Path) -> list[str]:
configured_mpv = read_config_value(config_path, 'mpv')
if configured_mpv:
return [configured_mpv]
return ['mpv']
def build_mpv_command(target_url: str, title: str, config_path: Path) -> list[str]:
command = resolve_mpv_command(config_path)
if title:
command.append(f'--force-media-title={title}')
command.append(target_url)
return command
def parse_protocol_url(raw_url: str) -> tuple[str, str]:
parsed = urlparse(raw_url)
if parsed.scheme not in {'mpv-handler', 'mpv-handler-debug'}:
raise ValueError(f'Unsupported scheme: {parsed.scheme}')
path_segments = [segment for segment in parsed.path.split('/') if segment]
if not path_segments or path_segments[0] != 'play':
raise ValueError('Unsupported mpv-handler plugin')
if len(path_segments) < 2:
raise ValueError('Missing encoded media URL')
target_url = decode_urlsafe_base64(path_segments[1])
query = parse_qs(parsed.query)
title = ''
if query.get('v_title'):
title = decode_urlsafe_base64(query['v_title'][0])
return target_url, title
def main() -> int:
if len(sys.argv) < 2:
print('Expected protocol URL argument', file=sys.stderr)
return 1
try:
target_url, title = parse_protocol_url(sys.argv[1])
except Exception as error:
print(f'Failed to parse mpv-handler URL: {error}', file=sys.stderr)
return 1
config_home = os.environ.get('XDG_CONFIG_HOME', '').strip()
config_dir = Path(config_home) / 'mpv-handler' if config_home else Path.home() / '.config' / 'mpv-handler'
config_path = config_dir / 'config.toml'
command = build_mpv_command(target_url, title, config_path)
try:
subprocess.Popen(command)
except Exception as error:
print(f'Failed to launch mpv: {error}', file=sys.stderr)
return 1
return 0
if __name__ == '__main__':
raise SystemExit(main())