videoNote / backend /app /services /browser_cookie.py
zhoujiaangyao
deploy videomemo backend to HF Space
6cfe55f
Raw
History Blame Contribute Delete
4.21 kB
import subprocess
import sys
import webbrowser
from typing import Optional
from app.services.cookie_manager import CookieConfigManager
PLATFORM_COOKIE_DOMAINS = {
"bilibili": ("bilibili.com",),
"youtube": ("youtube.com", "youtu.be"),
"douyin": ("douyin.com", "iesdouyin.com"),
"kuaishou": ("kuaishou.com",),
"xiaohongshu": ("xiaohongshu.com", "xhslink.com"),
}
PLATFORM_LOGIN_URLS = {
"bilibili": "https://www.bilibili.com/",
"youtube": "https://www.youtube.com/",
"douyin": "https://www.douyin.com/",
"kuaishou": "https://www.kuaishou.com/",
"xiaohongshu": "https://www.xiaohongshu.com/",
}
PLATFORM_LABELS = {
"bilibili": "B站",
"youtube": "YouTube",
"douyin": "抖音",
"kuaishou": "快手",
"xiaohongshu": "小红书",
}
class BrowserCookieError(Exception):
pass
def _extract_cookies_from_browser(browser: str):
try:
from yt_dlp.cookies import extract_cookies_from_browser
except Exception as exc:
raise BrowserCookieError("当前后端环境缺少 yt-dlp,无法从浏览器读取 Cookie") from exc
return extract_cookies_from_browser(browser)
def _cookie_domains_for_platform(platform: str) -> tuple[str, ...]:
return PLATFORM_COOKIE_DOMAINS.get(platform, (platform,))
def _matches_platform_domain(cookie_domain: str, platform: str) -> bool:
domain = (cookie_domain or "").lstrip(".").lower()
return any(
domain == target or domain.endswith(f".{target}")
for target in _cookie_domains_for_platform(platform)
)
def _format_cookie_pairs(cookies, platform: str) -> list[str]:
pairs = []
seen = set()
for cookie in cookies:
name = getattr(cookie, "name", "")
value = getattr(cookie, "value", "")
domain = getattr(cookie, "domain", "")
if not name or not value or not _matches_platform_domain(domain, platform):
continue
key = (name, value)
if key in seen:
continue
seen.add(key)
pairs.append(f"{name}={value}")
return pairs
def _open_url_in_browser(url: str, browser: str) -> bool:
browser = (browser or "").strip().lower()
if sys.platform == "darwin" and browser:
mac_apps = {
"chrome": "Google Chrome",
"edge": "Microsoft Edge",
"firefox": "Firefox",
"safari": "Safari",
"brave": "Brave Browser",
"chromium": "Chromium",
"opera": "Opera",
"vivaldi": "Vivaldi",
}
app_name = mac_apps.get(browser)
if app_name:
try:
subprocess.Popen(["open", "-a", app_name, url])
return True
except Exception:
pass
return webbrowser.open_new_tab(url)
def sync_browser_cookie(
platform: str,
browser: str,
manager: Optional[CookieConfigManager] = None,
) -> dict:
platform = (platform or "").strip()
browser = (browser or "").strip()
if not platform:
raise BrowserCookieError("平台不能为空")
if not browser:
raise BrowserCookieError("请选择浏览器")
try:
cookies = _extract_cookies_from_browser(browser)
except Exception as exc:
if isinstance(exc, BrowserCookieError):
raise
raise BrowserCookieError(f"从浏览器读取 Cookie 失败:{exc}") from exc
pairs = _format_cookie_pairs(cookies, platform)
if not pairs:
login_url = PLATFORM_LOGIN_URLS.get(platform)
opened = bool(login_url and _open_url_in_browser(login_url, browser))
label = PLATFORM_LABELS.get(platform, platform)
opened_hint = f"已打开{label}页面,登录后再点击一键获取。" if opened else ""
raise BrowserCookieError(
f"未找到 {platform} 对应的浏览器 Cookie,请先在该浏览器登录对应平台。{opened_hint}"
)
cookie_str = "; ".join(pairs)
cookie_manager = manager or CookieConfigManager()
cookie_manager.set(platform, cookie_str, browser=browser)
return {
"platform": platform,
"browser": browser,
"cookie": cookie_str,
"count": len(pairs),
}