Skip to content

Commit

Permalink
fix: update Bilibili API (close #88)
Browse files Browse the repository at this point in the history
  • Loading branch information
y-young committed Dec 25, 2023
1 parent d3d3ed3 commit d1ee418
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 92 deletions.
28 changes: 7 additions & 21 deletions docs/site/bilibili.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Storage path for downloaded images.

### BILIBILI_FILE_NAME

:material-lightbulb-on: Optional, defaults to `{dynamic_id_str}_{index} - {user[name]}({user[uid]})`
:material-lightbulb-on: Optional, defaults to `{id_str}_{index} - {user[name]}({user[mid]})`

File name for downloaded images.

Expand All @@ -24,31 +24,17 @@ _Only common used ones are listed._

```json
{
"item": {
"pictures": [
{
"img_height": 900,
"img_size": 840.989990234375,
"img_width": 1600
}
],
"pictures_count": 1,
"reply": 5,
"title": "",
"upload_time": "Upload time"
},
"user": {
"name": "User name",
"uid": "User ID"
"mid": "User ID"
},
"dynamic_id_str": "ID",
"view": 497,
"repost": 5,
"comment": 5,
"like": 68,
"id_str": "ID",
"timestamp": "Timestamp",
"filename": "Original file name, without extension",
"pic": "Current image object in `item.pictures`",
"pic": {
"height": 1440,
"width": 1080
},
"index": "Image index"
}
```
28 changes: 7 additions & 21 deletions docs/site/bilibili.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

### BILIBILI_FILE_NAME

:material-lightbulb-on: 可选,默认为 `{dynamic_id_str}_{index} - {user[name]}({user[uid]})`
:material-lightbulb-on: 可选,默认为 `{id_str}_{index} - {user[name]}({user[mid]})`

文件名称。

Expand All @@ -24,31 +24,17 @@ _此处只列出常用项。_

```json
{
"item": {
"pictures": [
{
"img_height": 900,
"img_size": 840.989990234375,
"img_width": 1600
}
],
"pictures_count": 1,
"reply": 5,
"title": "",
"upload_time": "上传时间"
},
"user": {
"name": "用户名称",
"uid": "用户ID"
"mid": "用户ID"
},
"dynamic_id_str": "ID",
"view": 497,
"repost": 5,
"comment": 5,
"like": 68,
"id_str": "ID",
"timestamp": "时间戳",
"filename": "原始文件名称,不含扩展名",
"pic": "当前图片在`item.pictures`中的对象",
"pic": {
"height": 1440,
"width": 1080
},
"index": "当前图片索引"
}
```
3 changes: 1 addition & 2 deletions nazurin/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@
UA = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/90.0.4430.85 "
"Safari/537.36"
"Chrome/120.0.0.0 Safari/537.36"
)

# Local directory to store database and temporary files
Expand Down
97 changes: 50 additions & 47 deletions nazurin/sites/bilibili/api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import json
import os
from datetime import datetime
from typing import List, Tuple
Expand All @@ -13,60 +12,48 @@

class Bilibili:
@network_retry
async def get_dynamic(self, dynamic_id: int):
async def get_dynamic(self, dynamic_id: str):
"""Get dynamic data from API."""
api = (
"https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr"
"/get_dynamic_detail?dynamic_id=" + str(dynamic_id)
f"https://api.bilibili.com/x/polymer/web-dynamic/v1/detail?id={dynamic_id}"
)
async with Request() as request:
async with request.get(api) as response:
response.raise_for_status()
data = await response.json()
# For some IDs, the API returns code 0 but empty content
if data["code"] == 500207 or (
data["code"] == 0 and "card" not in data["data"]
):
code = data.get("code")
if code == 4101147 or "data" not in data:
raise NazurinError("Dynamic not found")
if data["code"] != 0:
raise NazurinError("Failed to get dynamic: " + data["message"])
card = data["data"]["card"]
desc = card["desc"]
card = json.loads(card["card"])
card.update(
{
"type": desc["type"],
"dynamic_id_str": desc["dynamic_id_str"],
"view": desc["view"],
"repost": desc["repost"],
"comment": desc["comment"],
"like": desc["like"],
"timestamp": desc["timestamp"],
}
)
if "vip" in card["user"]:
del card["user"]["vip"]
return card
if code != 0:
raise NazurinError(
f"Failed to get dynamic: code = {code}, message = {data['message']}"

Check warning on line 30 in nazurin/sites/bilibili/api.py

View workflow job for this annotation

GitHub Actions / build (3.8)

Line too long (92/88)
)
item = data["data"]["item"]
return self.cleanup_item(item)

async def fetch(self, dynamic_id: int) -> Illust:
async def fetch(self, dynamic_id: str) -> Illust:
"""Fetch images and detail."""
card = await self.get_dynamic(dynamic_id)
imgs = self.get_images(card)
caption = self.build_caption(card)
caption["url"] = f"https://t.bilibili.com/{dynamic_id}"
return Illust(imgs, caption, card)
item = await self.get_dynamic(dynamic_id)
imgs = self.get_images(item)
caption = self.build_caption(item)
caption["url"] = f"https://www.bilibili.com/opus/{dynamic_id}"
return Illust(imgs, caption, item)

@staticmethod
def get_images(card) -> List[Image]:
def get_images(item: dict) -> List[Image]:
"""Get all images in a dynamic card."""
if "item" not in card or "pictures" not in card["item"]:
major_items = item["modules"]["module_dynamic"]["major"]
if not major_items:
raise NazurinError("No image found")
draw_items = major_items["draw"]["items"]
if not len(draw_items):

Check warning on line 50 in nazurin/sites/bilibili/api.py

View workflow job for this annotation

GitHub Actions / build (3.8)

Do not use `len(SEQUENCE)` without comparison to determine if a sequence is empty
raise NazurinError("No image found")
pics = card["item"]["pictures"]
imgs = []
for index, pic in enumerate(pics):
url = pic["img_src"]
destination, filename = Bilibili.get_storage_dest(card, pic, index)
size = pic["img_size"] * 1024 # size returned by API is in KB
for index, pic in enumerate(draw_items):
url = pic["src"]
destination, filename = Bilibili.get_storage_dest(item, pic, index)
size = pic["size"] * 1024 # size returned by API is in KB
# Sometimes it returns a wrong size that is not in whole bytes,
# in this case we just ignore it.
if size % 1 != 0:
Expand All @@ -78,30 +65,32 @@ def get_images(card) -> List[Image]:
destination,
url + "@518w.jpg",
size,
pic["img_width"],
pic["img_height"],
pic["width"],
pic["height"],
)
)
return imgs

@staticmethod
def get_storage_dest(card: dict, pic: dict, index: int = 0) -> Tuple[str, str]:
def get_storage_dest(item: dict, pic: dict, index: int = 0) -> Tuple[str, str]:
"""
Format destination and filename.
"""

url = pic["img_src"]
timestamp = datetime.fromtimestamp(card["timestamp"])
url = pic["src"]
timestamp = datetime.fromtimestamp(item["modules"]["module_author"]["pub_ts"])
basename = os.path.basename(url)
filename, extension = os.path.splitext(basename)
user = item["modules"]["module_author"]
context = {
**card,
"user": user,
# Original filename, without extension
"filename": filename,
# Image index
"index": index,
"timestamp": timestamp,
"extension": extension,
"id_str": item["id_str"],
"pic": pic,
}
return (
Expand All @@ -110,7 +99,21 @@ def get_storage_dest(card: dict, pic: dict, index: int = 0) -> Tuple[str, str]:
)

@staticmethod
def build_caption(card) -> Caption:
def build_caption(item: dict) -> Caption:
modules = item["modules"]
return Caption(
{"author": card["user"]["name"], "content": card["item"]["description"]}
{
"author": "#" + modules["module_author"]["name"],
"content": modules["module_dynamic"]["desc"]["text"],
}
)

@staticmethod
def cleanup_item(item: dict) -> dict:
try:
del item["basic"]
del item["modules"]["module_author"]["avatar"]
del item["modules"]["module_more"]
except KeyError:
pass
return item
2 changes: 1 addition & 1 deletion nazurin/sites/bilibili/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
with env.prefixed("FILE_"):
DESTINATION: str = env.str("PATH", default="Bilibili")
FILENAME: str = env.str(
"NAME", default="{dynamic_id_str}_{index} - {user[name]}({user[uid]})"
"NAME", default="{id_str}_{index} - {user[name]}({user[mid]})"
)
2 changes: 2 additions & 0 deletions nazurin/sites/bilibili/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
r"t\.bilibili\.com/(\d+)",
# https://t.bilibili.com/h5/dynamic/detail/123456789012345678
r"t\.bilibili\.com/h5/dynamic/detail/(\d+)",
# https://www.bilibili.com/opus/123456789012345678
r"bilibili\.com/opus/(\d+)",
]


Expand Down

0 comments on commit d1ee418

Please sign in to comment.