diff --git a/skills/kb-link-parser/link-parser.py b/skills/kb-link-parser/link-parser.py index 84981d5..131357b 100644 --- a/skills/kb-link-parser/link-parser.py +++ b/skills/kb-link-parser/link-parser.py @@ -29,10 +29,12 @@ class LinkParser: # Bilibili patterns BILIBILI_VIDEO_PATTERN = re.compile(r'https?://(?:www\.)?bilibili\.com/video/(BV[a-zA-Z0-9]+)') BILIBILI_VIDEO_SHORT_PATTERN = re.compile(r'https?://b23\.tv/([a-zA-Z0-9]+)') - BILIBILI_ARTICLE_PATTERN = re.compile(r'https?://(?:www\.)?bilibili\.com/article/([a-zA-Z0-9]+)') + BILIBILI_ARTICLE_PATTERN = re.compile(r'https?://(?:www\.)?bilibili\.com/(?:article|read)/([a-zA-Z0-9]+)') BILIBILI_SPACE_PATTERN = re.compile(r'https?://(?:space\.)?bilibili\.com/(\d+)') - BILIBILI_FAVEPATTERN = re.compile(r'https?://(?:www\.)?bilibili\.com/opus/(\d+)') - BILIBILI_SERIES_PATTERN = re.compile(r'https?://(?:www\.)?bilibili\.com/series/([a-zA-Z0-9]+)') + BILIBILI_FAVLIST_PATTERN = re.compile(r'https?://(?:space\.)?bilibili\.com/\d+/favlist\?fid=(\d+)') + BILIBILI_OPUS_PATTERN = re.compile(r'https?://(?:www\.)?bilibili\.com/opus/(\d+)') + BILIBILI_SERIES_PATTERN = re.compile(r'https?://(?:space\.)?bilibili\.com/\d+/lists/(\d+)\?type=series') + BILIBILI_READLIST_PATTERN = re.compile(r'https?://(?:www\.)?bilibili\.com/read/readlist/(rl[a-zA-Z0-9]+)') # YouTube patterns YOUTUBE_VIDEO_PATTERN = re.compile(r'(?:https?://)?(?:www\.)?(?:youtube\.com/watch\?v=|youtu\.be/)([a-zA-Z0-9_-]{11})') @@ -62,11 +64,8 @@ class LinkParser: """ # Check if it's a known short link pattern if self.shortlink_resolver.is_bilibili_short_link(url): - # For b23.tv, we need Playwright to resolve - # Return the short URL as-is with a note return url - # Return original URL for other cases return url def extract_bilibili_id(self, url: str) -> Optional[Dict[str, str]]: @@ -79,6 +78,42 @@ class LinkParser: Returns: Dict with platform, type, and id fields, or None if not matched """ + # Try series/playlist (must check before space pattern) + match = self.BILIBILI_SERIES_PATTERN.match(url) + if match: + return { + "platform": "bilibili", + "type": "playlist", + "id": match.group(1) + } + + # Try readlist (专栏合集) + match = self.BILIBILI_READLIST_PATTERN.match(url) + if match: + return { + "platform": "bilibili", + "type": "readlist", + "id": match.group(1) + } + + # Try favlist (收藏夹) + match = self.BILIBILI_FAVLIST_PATTERN.match(url) + if match: + return { + "platform": "bilibili", + "type": "favlist", + "id": match.group(1) + } + + # Try opus (动态) + match = self.BILIBILI_OPUS_PATTERN.match(url) + if match: + return { + "platform": "bilibili", + "type": "opus", + "id": match.group(1) + } + # Try video match = self.BILIBILI_VIDEO_PATTERN.match(url) if match: @@ -88,7 +123,7 @@ class LinkParser: "id": match.group(1) } - # Try article + # Try article/read match = self.BILIBILI_ARTICLE_PATTERN.match(url) if match: return { @@ -97,7 +132,7 @@ class LinkParser: "id": match.group(1) } - # Try space (UP主) + # Try space (UP主) - must check after specific patterns match = self.BILIBILI_SPACE_PATTERN.match(url) if match: return { @@ -106,24 +141,6 @@ class LinkParser: "id": match.group(1) } - # Try collection - match = self.BILIBILI_FAVEPATTERN.match(url) - if match: - return { - "platform": "bilibili", - "type": "collection", - "id": match.group(1) - } - - # Try series - match = self.BILIBILI_SERIES_PATTERN.match(url) - if match: - return { - "platform": "bilibili", - "type": "series", - "id": match.group(1) - } - return None def extract_youtube_id(self, url: str) -> Optional[Dict[str, str]]: