Commit 260ba01
Changed files (4)
src
subtitles
src/preview/utils.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
import asyncio
import re
-from datetime import datetime
+from datetime import UTC, datetime
from pathlib import Path
from zoneinfo import ZoneInfo
@@ -11,7 +11,7 @@ from glom import glom
from loguru import logger
from pyrogram.parser.markdown import BLOCKQUOTE_EXPANDABLE_DELIM
-from config import READING_SPEED, TZ, cache
+from config import PROXY, READING_SPEED, TOKEN, TZ, cache
from cookies import bilibili_cookie_dict
from networking import hx_req
from others.emoji import emojify
@@ -130,6 +130,37 @@ async def get_bilibili_comments(url_or_vid: int | str) -> list[str]:
return comments
+@cache.memoize(ttl=120)
+async def fetch_youtube_video_info(video_id: str) -> dict:
+ """Fetch YouTube video info."""
+ if not video_id:
+ return {}
+ try:
+ logger.info(f"Fetch Video info for {video_id=}, proxy={PROXY.SUBTITLE}")
+ api = "https://www.googleapis.com/youtube/v3/videos"
+ params = {"key": TOKEN.YOUTUBE_API_KEY, "part": "snippet", "id": video_id, "hl": "zh-CN"}
+ resp = await hx_req(api, proxy=PROXY.SUBTITLE, params=params, check_keys=["items"], max_retry=0)
+ if resp.get("hx_error"):
+ logger.warning(f"YouTube Videos API failed: {resp['hx_error']}")
+ return {}
+ title = glom(resp, "items.0.snippet.title")
+ desc = glom(resp, "items.0.snippet.description")
+ author = glom(resp, "items.0.snippet.channelTitle")
+ channel = glom(resp, "items.0.snippet.channelId")
+ pubdate = glom(resp, "items.0.snippet.publishedAt")
+ except Exception as e:
+ logger.error(f"Failed to get video info: {e}")
+ return {}
+ return {
+ "title": title,
+ "description": desc,
+ "author": author,
+ "channel": f"https://www.youtube.com/channel/{channel}",
+ "date": datetime.strptime(pubdate, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=UTC).astimezone(ZoneInfo(TZ)),
+ "emoji": "๐ด",
+ }
+
+
def has_markdown_img(text: str) -> bool:
"""Check if the text contains markdown img format.
src/preview/ytdlp.py
@@ -43,9 +43,9 @@ from messages.sender import send2tg
from messages.utils import blockquote, count_without_entities, get_reply_to, smart_split, warp_comments
from multimedia import convert_to_h264, generate_cover
from networking import hx_req
-from preview.utils import get_bilibili_comments, make_bvid_clickable
+from preview.utils import fetch_youtube_video_info, get_bilibili_comments, make_bvid_clickable
from subtitles.base import fetch_subtitle
-from utils import publish_telegraph, readable_size, readable_time, remove_none_values, soup_to_text, to_int, true, ts_to_dt, unicode_to_ascii
+from utils import nowdt, publish_telegraph, readable_size, readable_time, remove_none_values, soup_to_text, to_int, true, ts_to_dt, unicode_to_ascii
class ProxyError(Exception):
@@ -174,6 +174,10 @@ async def preview_ytdlp(
create_time = f"{dt:%Y-%m-%d %H:%M:%S}"
elif info.get("upload_date"):
create_time = info["update_date"]
+ elif "youtube" in info["extractor"]:
+ vinfo = await fetch_youtube_video_info(kwargs.get("vid", ""))
+ dt = vinfo.get("date", nowdt())
+ create_time = f"{dt:%Y-%m-%d %H:%M:%S}"
if not true(kwargs.get("no_date")):
texts += f"\n๐{create_time}"
src/subtitles/base.py
@@ -1,15 +1,13 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-from datetime import UTC, datetime, timedelta
-from zoneinfo import ZoneInfo
+from datetime import timedelta
-from glom import glom
from loguru import logger
from pyrogram.client import Client
from pyrogram.types import Message
from youtube_transcript_api import YouTubeTranscriptApi # type: ignore
-from config import API, PREFIX, PROXY, READING_SPEED, TOKEN, TZ, cache
+from config import API, PREFIX, PROXY, READING_SPEED, TOKEN, cache
from messages.parser import parse_msg
from messages.utils import startswith_prefix
from networking import hx_req, match_social_media_link
@@ -158,31 +156,3 @@ def to_webvtt(subtitles: list[dict]) -> dict:
except Exception as e:
logger.error(f"Failed to convert subtitles to WebVTT: {e}")
return {"error": str(e)}
-
-
-async def fetch_youtube_video_info(video_id: str) -> dict:
- """Fetch YouTube video info."""
- try:
- logger.info(f"Fetch Video info for {video_id=}, proxy={PROXY.SUBTITLE}")
- api = "https://www.googleapis.com/youtube/v3/videos"
- params = {"key": TOKEN.YOUTUBE_API_KEY, "part": "snippet", "id": video_id, "hl": "zh-CN"}
- resp = await hx_req(api, proxy=PROXY.SUBTITLE, params=params, check_keys=["items"], max_retry=0)
- if resp.get("hx_error"):
- logger.warning(f"YouTube Videos API failed: {resp['hx_error']}")
- return {}
- title = glom(resp, "items.0.snippet.title")
- desc = glom(resp, "items.0.snippet.description")
- author = glom(resp, "items.0.snippet.channelTitle")
- channel = glom(resp, "items.0.snippet.channelId")
- pubdate = glom(resp, "items.0.snippet.publishedAt")
- except Exception as e:
- logger.error(f"Failed to get video info: {e}")
- return {}
- return {
- "title": title,
- "description": desc,
- "author": author,
- "channel": f"https://www.youtube.com/channel/{channel}",
- "date": datetime.strptime(pubdate, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=UTC).astimezone(ZoneInfo(TZ)),
- "emoji": "๐ด",
- }
src/subtitles/subtitle.py
@@ -14,9 +14,9 @@ from messages.progress import modify_progress
from messages.sender import send2tg
from messages.utils import equal_prefix
from networking import match_social_media_link
-from preview.utils import get_bilibili_video_info
+from preview.utils import fetch_youtube_video_info, get_bilibili_video_info
from preview.ytdlp import preview_ytdlp
-from subtitles.base import fetch_subtitle, fetch_youtube_video_info, match_url
+from subtitles.base import fetch_subtitle, match_url
from utils import publish_telegraph, to_int
HELP = f"""๐**ๆๅๅญๅน**