From 7b485abfbbc51c0816ecc6c061e42105bde78315 Mon Sep 17 00:00:00 2001 From: "Gan, Jimmy" Date: Wed, 24 Jun 2026 00:50:36 +0800 Subject: [PATCH] feat: DeepSeek API + transcript fixes; add OAuth captions scope --- backend/auth.py | 8 +++++++- backend/summarizer.py | 31 ++++++++++++++----------------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/backend/auth.py b/backend/auth.py index 3e33332..50d40cd 100644 --- a/backend/auth.py +++ b/backend/auth.py @@ -6,7 +6,10 @@ from google_auth_oauthlib.flow import InstalledAppFlow log = logging.getLogger(__name__) -SCOPES = ["https://www.googleapis.com/auth/youtube.readonly"] +SCOPES = [ + "https://www.googleapis.com/auth/youtube.readonly", + "https://www.googleapis.com/auth/youtube.force-ssl" +] CONFIG_DIR = os.environ.get("CONFIG_DIR", "/app/config") _local_dir = os.path.dirname(os.path.abspath(__file__)) _local_config = os.path.join(os.path.dirname(_local_dir), "config") @@ -34,6 +37,9 @@ def get_credentials(): "Download from Google Cloud Console." ) flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET, SCOPES) + # Print URL for manual opening + auth_url, _ = flow.authorization_url(prompt='consent', access_type='offline') + print(f"\nOpen this URL in your browser:\n{auth_url}\n") creds = flow.run_local_server(port=0) os.makedirs(os.path.dirname(TOKEN_FILE), exist_ok=True) diff --git a/backend/summarizer.py b/backend/summarizer.py index 75ef8fb..babc530 100644 --- a/backend/summarizer.py +++ b/backend/summarizer.py @@ -28,38 +28,35 @@ Keep the entire summary under 150 words. Be extremely direct so I can decide in Transcript: {transcript}""" +COOKIES_PATH = None +for p in [os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config/cookies.txt"), + "/app/config/cookies.txt"]: + if os.path.exists(p): + COOKIES_PATH = p + break + def download_transcript(video_id: str) -> str: try: session = requests.Session() session.headers.update({ - "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", "Accept-Language": "en-US,en;q=0.9" }) - # Load cookies to bypass YouTube IP block - for p in [os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config/cookies.txt"), - "/app/config/cookies.txt"]: - if os.path.exists(p): - from http.cookiejar import MozillaCookieJar - cj = MozillaCookieJar(p) - cj.load(ignore_discard=True, ignore_expires=True) - session.cookies.update({c.name: c.value for c in cj}) - break + if COOKIES_PATH: + from http.cookiejar import MozillaCookieJar + cj = MozillaCookieJar(COOKIES_PATH) + cj.load(ignore_discard=True, ignore_expires=True) + session.cookies.update({c.name: c.value for c in cj}) transcript_list = YouTubeTranscriptApi(http_client=session).list(video_id) - - # Try to find manual transcripts in preferred languages try: transcript = transcript_list.find_manually_created_transcript(['en', 'zh-Hans', 'zh-Hant', 'zh', 'ja']) except Exception: - # Fallback to generated (auto-captions) in preferred languages try: transcript = transcript_list.find_generated_transcript(['en', 'zh-Hans', 'zh-Hant', 'zh', 'ja']) except Exception: - # Fallback to any transcript transcript = next(iter(transcript_list)) - parts = transcript.fetch() - text = " ".join([part["text"] for part in parts]) - return text + return " ".join([part["text"] for part in parts]) except Exception as e: log.warning(f"Failed to fetch transcript for {video_id}: {e}") return None