nonebot-plugin-bililive 2.0.5__tar.gz → 2.0.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/PKG-INFO +1 -1
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/dynamic/web.py +11 -8
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/pusher/dynamic_pusher.py +69 -42
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/utils/__init__.py +5 -1
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/utils/browser.py +27 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/version.py +1 -1
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/pyproject.toml +1 -1
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/tests/test_maintenance.py +26 -1
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/LICENSE +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/README.md +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/__main__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/cli/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/cli/bot.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/cli/utils.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/compat.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/config.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/database/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/database/db.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/database/models.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/dynamic/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/dynamic/card.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/dynamic/desc.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/dynamic/display.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/dynamic/user_profile.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/at/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/at/at_off.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/at/at_on.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/auto_agree.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/auto_delete.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/dynamic/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/dynamic/dynamic_off.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/dynamic/dynamic_on.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/help.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/live/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/live/live_now.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/live/live_off.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/live/live_on.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/permission/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/permission/permission_off.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/permission/permission_on.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/pusher/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/pusher/live_pusher.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/sub/__init__.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/sub/add_sub.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/sub/delete_sub.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/sub/sub_list.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/utils/captcha_solver.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/utils/fonts_provider.py +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/utils/mobile.js +0 -0
- {nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/nonebot_plugin_bililive/__init__.py +0 -0
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/dynamic/web.py
RENAMED
|
@@ -47,6 +47,16 @@ def parse_web_dynamic_items(payload: dict) -> list[WebDynamicItem]:
|
|
|
47
47
|
return parsed_items
|
|
48
48
|
|
|
49
49
|
|
|
50
|
+
def parse_web_dynamic_payload(payload: dict) -> list[WebDynamicItem]:
|
|
51
|
+
if payload.get("code") != 0:
|
|
52
|
+
raise WebDynamicError(
|
|
53
|
+
payload.get("code"),
|
|
54
|
+
payload.get("message") or "unknown error",
|
|
55
|
+
payload.get("data"),
|
|
56
|
+
)
|
|
57
|
+
return parse_web_dynamic_items(payload)
|
|
58
|
+
|
|
59
|
+
|
|
50
60
|
async def get_user_dynamics_web(
|
|
51
61
|
uid: int,
|
|
52
62
|
cookies: dict[str, str],
|
|
@@ -69,11 +79,4 @@ async def get_user_dynamics_web(
|
|
|
69
79
|
follow_redirects=True,
|
|
70
80
|
) as client:
|
|
71
81
|
response = await client.get(WEB_DYNAMIC_URL, params={"host_mid": uid})
|
|
72
|
-
|
|
73
|
-
if payload.get("code") != 0:
|
|
74
|
-
raise WebDynamicError(
|
|
75
|
-
payload.get("code"),
|
|
76
|
-
payload.get("message") or "unknown error",
|
|
77
|
-
payload.get("data"),
|
|
78
|
-
)
|
|
79
|
-
return parse_web_dynamic_items(payload)
|
|
82
|
+
return parse_web_dynamic_payload(response.json())
|
|
@@ -19,15 +19,22 @@ from nonebot.log import logger
|
|
|
19
19
|
from ...config import plugin_config
|
|
20
20
|
from ...database import DB as db
|
|
21
21
|
from ...database import dynamic_offset as offset
|
|
22
|
-
from ...libs.dynamic.web import
|
|
22
|
+
from ...libs.dynamic.web import (
|
|
23
|
+
WebDynamicError,
|
|
24
|
+
get_user_dynamics_web,
|
|
25
|
+
parse_web_dynamic_payload,
|
|
26
|
+
)
|
|
23
27
|
from ...utils import (
|
|
24
28
|
get_bilibili_cookies,
|
|
25
29
|
get_dynamic_screenshot,
|
|
30
|
+
get_user_dynamics_payload_in_browser,
|
|
26
31
|
safe_send,
|
|
27
32
|
scheduler,
|
|
28
33
|
)
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
GRPC_RISK_CONTROL_RETRY_SECONDS = 3600
|
|
36
|
+
WEB_REQUEST_BANNED_RETRY_SECONDS = 300
|
|
37
|
+
WEB_REQUEST_ERROR_RETRY_SECONDS = 600
|
|
31
38
|
dynamic_risk_control_until = {}
|
|
32
39
|
dynamic_web_fallback_until = {}
|
|
33
40
|
WEB_SKIP_DYNAMIC_TYPES = {
|
|
@@ -44,6 +51,7 @@ WEB_DYNAMIC_TYPE_MESSAGES = {
|
|
|
44
51
|
"DYNAMIC_TYPE_ARTICLE": "发布了新专栏",
|
|
45
52
|
"DYNAMIC_TYPE_MUSIC": "发布了新音频",
|
|
46
53
|
}
|
|
54
|
+
DYNAMIC_FETCH_CONCURRENCY = 4
|
|
47
55
|
|
|
48
56
|
|
|
49
57
|
async def throttle_dynamic_loop():
|
|
@@ -95,21 +103,32 @@ def should_skip_dynamic(dynamic_type, use_web_fallback: bool) -> bool:
|
|
|
95
103
|
|
|
96
104
|
|
|
97
105
|
async def get_user_dynamics_with_web_fallback(uid: int) -> tuple[list, bool]:
|
|
106
|
+
async def fetch_web_dynamics() -> list:
|
|
107
|
+
try:
|
|
108
|
+
payload = await get_user_dynamics_payload_in_browser(uid)
|
|
109
|
+
return parse_web_dynamic_payload(payload)
|
|
110
|
+
except WebDynamicError as browser_error:
|
|
111
|
+
logger.debug(
|
|
112
|
+
f"浏览器上下文动态接口获取失败,尝试直连 Web API:{uid} "
|
|
113
|
+
f"{browser_error.code} {browser_error.msg}"
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
cookies = await get_bilibili_cookies()
|
|
117
|
+
if not cookies:
|
|
118
|
+
raise WebDynamicError(-1, "browser cookies unavailable")
|
|
119
|
+
return await get_user_dynamics_web(
|
|
120
|
+
uid,
|
|
121
|
+
cookies,
|
|
122
|
+
proxy=plugin_config.bililive_proxy,
|
|
123
|
+
user_agent=plugin_config.bililive_browser_ua or None,
|
|
124
|
+
timeout=plugin_config.bililive_dynamic_timeout,
|
|
125
|
+
)
|
|
126
|
+
|
|
98
127
|
fallback_until = dynamic_web_fallback_until.get(uid)
|
|
99
128
|
if fallback_until is not None:
|
|
100
129
|
if fallback_until > monotonic():
|
|
101
130
|
logger.debug(f"动态 gRPC 接口仍在风控,继续使用 Web 接口:{uid}")
|
|
102
|
-
|
|
103
|
-
if not cookies:
|
|
104
|
-
raise WebDynamicError(-1, "browser cookies unavailable")
|
|
105
|
-
dynamics = await get_user_dynamics_web(
|
|
106
|
-
uid,
|
|
107
|
-
cookies,
|
|
108
|
-
proxy=plugin_config.bililive_proxy,
|
|
109
|
-
user_agent=plugin_config.bililive_browser_ua or None,
|
|
110
|
-
timeout=plugin_config.bililive_dynamic_timeout,
|
|
111
|
-
)
|
|
112
|
-
return dynamics, True
|
|
131
|
+
return await fetch_web_dynamics(), True
|
|
113
132
|
del dynamic_web_fallback_until[uid]
|
|
114
133
|
|
|
115
134
|
try:
|
|
@@ -129,36 +148,14 @@ async def get_user_dynamics_with_web_fallback(uid: int) -> tuple[list, bool]:
|
|
|
129
148
|
f"动态 gRPC 接口触发风控,切换 Web 接口:{uid} "
|
|
130
149
|
f"{e.code} {e.msg}"
|
|
131
150
|
)
|
|
132
|
-
dynamic_web_fallback_until[uid] = monotonic() +
|
|
133
|
-
|
|
134
|
-
if not cookies:
|
|
135
|
-
raise WebDynamicError(-1, "browser cookies unavailable")
|
|
136
|
-
dynamics = await get_user_dynamics_web(
|
|
137
|
-
uid,
|
|
138
|
-
cookies,
|
|
139
|
-
proxy=plugin_config.bililive_proxy,
|
|
140
|
-
user_agent=plugin_config.bililive_browser_ua or None,
|
|
141
|
-
timeout=plugin_config.bililive_dynamic_timeout,
|
|
142
|
-
)
|
|
143
|
-
return dynamics, True
|
|
144
|
-
|
|
151
|
+
dynamic_web_fallback_until[uid] = monotonic() + GRPC_RISK_CONTROL_RETRY_SECONDS
|
|
152
|
+
return await fetch_web_dynamics(), True
|
|
145
153
|
|
|
146
|
-
async def dy_sched():
|
|
147
|
-
"""动态推送"""
|
|
148
|
-
if not await db.wait_until_ready():
|
|
149
|
-
logger.debug("数据库尚未初始化完成,跳过本轮动态推送")
|
|
150
|
-
await throttle_dynamic_loop()
|
|
151
|
-
return
|
|
152
154
|
|
|
153
|
-
|
|
154
|
-
if not uid:
|
|
155
|
-
# 没有订阅先暂停一秒再跳过,不然会导致 CPU 占用过高
|
|
156
|
-
await throttle_dynamic_loop()
|
|
157
|
-
return
|
|
155
|
+
async def process_dynamic_uid(uid: int):
|
|
158
156
|
user = await db.get_user(uid=uid)
|
|
159
157
|
if user is None:
|
|
160
158
|
logger.warning(f"动态推送跳过异常订阅 UID:{uid}")
|
|
161
|
-
await throttle_dynamic_loop()
|
|
162
159
|
return
|
|
163
160
|
name = user.name
|
|
164
161
|
|
|
@@ -186,16 +183,19 @@ async def dy_sched():
|
|
|
186
183
|
return
|
|
187
184
|
except GrpcError as e:
|
|
188
185
|
logger.error(f"爬取动态失败:{e.code} {e.msg}")
|
|
189
|
-
await throttle_dynamic_loop()
|
|
190
186
|
return
|
|
191
187
|
except WebDynamicError as e:
|
|
192
|
-
|
|
193
|
-
|
|
188
|
+
retry_seconds = (
|
|
189
|
+
WEB_REQUEST_BANNED_RETRY_SECONDS
|
|
190
|
+
if e.code == -412
|
|
191
|
+
else WEB_REQUEST_ERROR_RETRY_SECONDS
|
|
192
|
+
)
|
|
193
|
+
dynamic_risk_control_until[uid] = monotonic() + retry_seconds
|
|
194
|
+
retry_minutes = max(retry_seconds // 60, 1)
|
|
194
195
|
logger.warning(
|
|
195
196
|
f"动态 Web 接口获取失败,{name}({uid})将在 "
|
|
196
197
|
f"{retry_minutes} 分钟后重试:{e.code} {e.msg}"
|
|
197
198
|
)
|
|
198
|
-
await throttle_dynamic_loop()
|
|
199
199
|
return
|
|
200
200
|
|
|
201
201
|
dynamic_risk_control_until.pop(uid, None)
|
|
@@ -256,6 +256,30 @@ async def dy_sched():
|
|
|
256
256
|
await db.update_user(uid, name)
|
|
257
257
|
|
|
258
258
|
|
|
259
|
+
async def dy_sched():
|
|
260
|
+
"""动态推送"""
|
|
261
|
+
if not await db.wait_until_ready():
|
|
262
|
+
logger.debug("数据库尚未初始化完成,跳过本轮动态推送")
|
|
263
|
+
await throttle_dynamic_loop()
|
|
264
|
+
return
|
|
265
|
+
|
|
266
|
+
uids = await db.get_uid_list("dynamic")
|
|
267
|
+
if not uids:
|
|
268
|
+
# 没有订阅先暂停一秒再跳过,不然会导致 CPU 占用过高
|
|
269
|
+
await throttle_dynamic_loop()
|
|
270
|
+
return
|
|
271
|
+
|
|
272
|
+
logger.debug(f"爬取动态列表,总共 {len(uids)} 人")
|
|
273
|
+
semaphore = asyncio.Semaphore(DYNAMIC_FETCH_CONCURRENCY)
|
|
274
|
+
|
|
275
|
+
async def run_for_uid(uid: int):
|
|
276
|
+
async with semaphore:
|
|
277
|
+
await process_dynamic_uid(uid)
|
|
278
|
+
|
|
279
|
+
await asyncio.gather(*(run_for_uid(uid) for uid in uids))
|
|
280
|
+
await throttle_dynamic_loop()
|
|
281
|
+
|
|
282
|
+
|
|
259
283
|
def dynamic_lisener(event):
|
|
260
284
|
if hasattr(event, "job_id") and event.job_id != "dynamic_sched":
|
|
261
285
|
return
|
|
@@ -277,4 +301,7 @@ else:
|
|
|
277
301
|
"interval",
|
|
278
302
|
seconds=plugin_config.bililive_dynamic_interval,
|
|
279
303
|
id="dynamic_sched",
|
|
304
|
+
coalesce=True,
|
|
305
|
+
max_instances=1,
|
|
306
|
+
misfire_grace_time=5,
|
|
280
307
|
)
|
|
@@ -304,4 +304,8 @@ PROXIES = {"all://": plugin_config.bililive_proxy}
|
|
|
304
304
|
require("nonebot_plugin_apscheduler")
|
|
305
305
|
from nonebot_plugin_apscheduler import scheduler # noqa
|
|
306
306
|
|
|
307
|
-
from .browser import
|
|
307
|
+
from .browser import ( # noqa
|
|
308
|
+
get_bilibili_cookies,
|
|
309
|
+
get_dynamic_screenshot,
|
|
310
|
+
get_user_dynamics_payload_in_browser,
|
|
311
|
+
)
|
|
@@ -16,6 +16,7 @@ from .fonts_provider import fill_font
|
|
|
16
16
|
|
|
17
17
|
_browser: BrowserContext | None = None
|
|
18
18
|
mobile_js = Path(__file__).parent.joinpath("mobile.js")
|
|
19
|
+
WEB_DYNAMIC_URL = "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space"
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
async def init_browser(proxy=plugin_config.bililive_proxy, **kwargs) -> BrowserContext:
|
|
@@ -72,6 +73,32 @@ async def get_bilibili_cookies() -> dict[str, str]:
|
|
|
72
73
|
return {cookie["name"]: cookie["value"] for cookie in cookies}
|
|
73
74
|
|
|
74
75
|
|
|
76
|
+
async def get_user_dynamics_payload_in_browser(uid: int) -> dict:
|
|
77
|
+
browser = await get_browser()
|
|
78
|
+
page = await browser.new_page()
|
|
79
|
+
try:
|
|
80
|
+
await page.goto(
|
|
81
|
+
"https://www.bilibili.com/",
|
|
82
|
+
wait_until="domcontentloaded",
|
|
83
|
+
timeout=plugin_config.bililive_dynamic_timeout * 1000,
|
|
84
|
+
)
|
|
85
|
+
return await page.evaluate(
|
|
86
|
+
"""async ({ url, uid }) => {
|
|
87
|
+
const response = await fetch(`${url}?host_mid=${uid}`, {
|
|
88
|
+
credentials: 'include',
|
|
89
|
+
headers: {
|
|
90
|
+
accept: 'application/json, text/plain, */*',
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
return await response.json();
|
|
94
|
+
}""",
|
|
95
|
+
{"url": WEB_DYNAMIC_URL, "uid": str(uid)},
|
|
96
|
+
)
|
|
97
|
+
finally:
|
|
98
|
+
with contextlib.suppress(Exception):
|
|
99
|
+
await page.close()
|
|
100
|
+
|
|
101
|
+
|
|
75
102
|
async def get_dynamic_screenshot(
|
|
76
103
|
dynamic_id,
|
|
77
104
|
style=plugin_config.bililive_screenshot_style,
|
|
@@ -20,7 +20,20 @@ class DummyDriver:
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
fake_apscheduler = ModuleType("nonebot_plugin_apscheduler")
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class DummyScheduler:
|
|
26
|
+
def add_listener(self, *args, **kwargs):
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
def add_job(self, *args, **kwargs):
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
def get_job(self, *args, **kwargs):
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
fake_apscheduler.scheduler = DummyScheduler()
|
|
24
37
|
|
|
25
38
|
|
|
26
39
|
with patch("nonebot.get_driver", return_value=DummyDriver()), patch(
|
|
@@ -131,6 +144,18 @@ class WebDynamicTests(unittest.TestCase):
|
|
|
131
144
|
|
|
132
145
|
self.assertEqual(web_dynamic.parse_web_dynamic_items(payload), [])
|
|
133
146
|
|
|
147
|
+
def test_parse_web_dynamic_payload_raises_for_error_code(self):
|
|
148
|
+
payload = {
|
|
149
|
+
"code": -412,
|
|
150
|
+
"message": "request was banned",
|
|
151
|
+
"data": None,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
with self.assertRaises(web_dynamic.WebDynamicError) as context:
|
|
155
|
+
web_dynamic.parse_web_dynamic_payload(payload)
|
|
156
|
+
|
|
157
|
+
self.assertEqual(context.exception.code, -412)
|
|
158
|
+
|
|
134
159
|
|
|
135
160
|
class DBPermissionTests(unittest.IsolatedAsyncioTestCase):
|
|
136
161
|
async def test_db_init_enables_global_fallback(self):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/database/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/dynamic/__init__.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/dynamic/card.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/dynamic/desc.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/libs/dynamic/display.py
RENAMED
|
File without changes
|
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/__init__.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/at/__init__.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/at/at_off.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/at/at_on.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/auto_agree.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/auto_delete.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/dynamic/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/live/__init__.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/live/live_now.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/live/live_off.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/live/live_on.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/pusher/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/sub/__init__.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/sub/add_sub.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/sub/delete_sub.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/plugins/sub/sub_list.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/utils/captcha_solver.py
RENAMED
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/bililive/utils/fonts_provider.py
RENAMED
|
File without changes
|
|
File without changes
|
{nonebot_plugin_bililive-2.0.5 → nonebot_plugin_bililive-2.0.6}/nonebot_plugin_bililive/__init__.py
RENAMED
|
File without changes
|