Skip to content
This repository was archived by the owner on Jan 28, 2026. It is now read-only.

Commit b82e204

Browse files
authored
feat: upload cover (#52)
* feat: upload cover * docs: update docs
1 parent 4d147a9 commit b82e204

25 files changed

+815
-475
lines changed

README-en.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ graph TD
101101
- Displays logs and upload progress
102102
- Supports **automatic speed test and selection of the best route** (default)
103103
- Supports specifying upload lines (`qn`, `bldsa`, `ws`, `bda2`, `tx`)
104+
- Supports uploading cover image
104105
- `bilitool append` appends videos to existing videos (multi-part)
105106
- `bilitool download` downloads videos
106107
- Supports downloading with `bvid` and `avid` identifiers

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ graph TD
101101
- 显示日志与上传进度
102102
- 支持**自动测速并且选择最佳线路**(默认)
103103
- 支持指定上传线路(`qn`, `bldsa`, `ws`, `bda2`, `tx`)
104+
- 支持上传视频封面图片
104105
- `bilitool append` 追加视频到已有的视频(**分p投稿**)
105106
- `bilitool download` 下载视频
106107
- 支持 `bvid``avid` 两种编号下载

bilitool/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,11 @@
55
from .utils.get_ip_info import IPInfo
66
from .utils.check_format import CheckFormat
77

8-
__all__ = ['LoginController', 'UploadController', 'DownloadController', 'FeedController', 'IPInfo', 'CheckFormat']
8+
__all__ = [
9+
"LoginController",
10+
"UploadController",
11+
"DownloadController",
12+
"FeedController",
13+
"IPInfo",
14+
"CheckFormat",
15+
]

bilitool/authenticate/wbi_sign.py

Lines changed: 78 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,57 +9,115 @@
99

1010
# https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/wbi.md
1111

12+
1213
class WbiSign(object):
1314
def __init__(self):
1415
self.config = Model().get_config()
1516

1617
mixinKeyEncTab = [
17-
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
18-
33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
19-
61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
20-
36, 20, 34, 44, 52
18+
46,
19+
47,
20+
18,
21+
2,
22+
53,
23+
8,
24+
23,
25+
32,
26+
15,
27+
50,
28+
10,
29+
31,
30+
58,
31+
3,
32+
45,
33+
35,
34+
27,
35+
43,
36+
5,
37+
49,
38+
33,
39+
9,
40+
42,
41+
19,
42+
29,
43+
28,
44+
14,
45+
39,
46+
12,
47+
38,
48+
41,
49+
13,
50+
37,
51+
48,
52+
7,
53+
16,
54+
24,
55+
55,
56+
40,
57+
61,
58+
26,
59+
17,
60+
0,
61+
1,
62+
60,
63+
51,
64+
30,
65+
4,
66+
22,
67+
25,
68+
54,
69+
21,
70+
56,
71+
59,
72+
6,
73+
63,
74+
57,
75+
62,
76+
11,
77+
36,
78+
20,
79+
34,
80+
44,
81+
52,
2182
]
2283

2384
def get_wbi_keys(self) -> tuple[str, str]:
2485
"""Get the refresh token"""
2586
headers = Model().get_headers_with_cookies_and_refer()
26-
resp = requests.get('https://api.bilibili.com/x/web-interface/nav', headers=headers)
87+
resp = requests.get(
88+
"https://api.bilibili.com/x/web-interface/nav", headers=headers
89+
)
2790
resp.raise_for_status()
2891
json_content = resp.json()
29-
img_url: str = json_content['data']['wbi_img']['img_url']
30-
sub_url: str = json_content['data']['wbi_img']['sub_url']
31-
img_key = img_url.rsplit('/', 1)[1].split('.')[0]
32-
sub_key = sub_url.rsplit('/', 1)[1].split('.')[0]
92+
img_url: str = json_content["data"]["wbi_img"]["img_url"]
93+
sub_url: str = json_content["data"]["wbi_img"]["sub_url"]
94+
img_key = img_url.rsplit("/", 1)[1].split(".")[0]
95+
sub_key = sub_url.rsplit("/", 1)[1].split(".")[0]
3396
return img_key, sub_key
3497

3598
def get_mixin_key(self, orig: str):
3699
"""shuffle the string"""
37-
return reduce(lambda s, i: s + orig[i], self.mixinKeyEncTab, '')[:32]
100+
return reduce(lambda s, i: s + orig[i], self.mixinKeyEncTab, "")[:32]
38101

39102
def enc_wbi(self, params: dict, img_key: str, sub_key: str):
40103
"""wbi sign"""
41104
mixin_key = self.get_mixin_key(img_key + sub_key)
42105
curr_time = round(time.time())
43-
params['wts'] = curr_time
106+
params["wts"] = curr_time
44107
params = dict(sorted(params.items()))
45108
# filter the value of "!'()*"
46109
params = {
47-
k: ''.join(filter(lambda char: char not in "!'()*", str(v)))
48-
for k, v
49-
in params.items()
110+
k: "".join(filter(lambda char: char not in "!'()*", str(v)))
111+
for k, v in params.items()
50112
}
51113
query = urllib.parse.urlencode(params)
52114
wbi_sign = md5((query + mixin_key).encode()).hexdigest()
53115
# add `w_rid` parameter in the url
54-
params['w_rid'] = wbi_sign
116+
params["w_rid"] = wbi_sign
55117
return params
56118

57119
def get_wbi_signed_params(self, params):
58120
img_key, sub_key = self.get_wbi_keys()
59121

60-
signed_params = self.enc_wbi(
61-
params=params,
62-
img_key=img_key,
63-
sub_key=sub_key
64-
)
122+
signed_params = self.enc_wbi(params=params, img_key=img_key, sub_key=sub_key)
65123
return signed_params

0 commit comments

Comments
 (0)