nonebot-plugin-jmdownloader 1.0.3__py3-none-any.whl → 1.1.0__py3-none-any.whl

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.
Files changed (33) hide show
  1. nonebot_plugin_jmdownloader/__init__.py +23 -600
  2. nonebot_plugin_jmdownloader/bot/__init__.py +18 -0
  3. nonebot_plugin_jmdownloader/bot/dependencies.py +176 -0
  4. nonebot_plugin_jmdownloader/bot/handlers/__init__.py +26 -0
  5. nonebot_plugin_jmdownloader/bot/handlers/ban_id_tag.py +62 -0
  6. nonebot_plugin_jmdownloader/bot/handlers/blacklist.py +113 -0
  7. nonebot_plugin_jmdownloader/bot/handlers/download.py +210 -0
  8. nonebot_plugin_jmdownloader/bot/handlers/group_control.py +172 -0
  9. nonebot_plugin_jmdownloader/bot/handlers/query.py +76 -0
  10. nonebot_plugin_jmdownloader/bot/handlers/scheduled.py +38 -0
  11. nonebot_plugin_jmdownloader/bot/handlers/search.py +224 -0
  12. nonebot_plugin_jmdownloader/bot/nonebot_utils.py +22 -0
  13. nonebot_plugin_jmdownloader/config.py +30 -58
  14. nonebot_plugin_jmdownloader/core/__init__.py +11 -0
  15. nonebot_plugin_jmdownloader/core/data_models.py +179 -0
  16. nonebot_plugin_jmdownloader/core/enums.py +10 -0
  17. nonebot_plugin_jmdownloader/core/search_session.py +74 -0
  18. nonebot_plugin_jmdownloader/infra/__init__.py +15 -0
  19. nonebot_plugin_jmdownloader/infra/data_manager.py +104 -0
  20. nonebot_plugin_jmdownloader/infra/image_utils.py +38 -0
  21. nonebot_plugin_jmdownloader/infra/jm_service.py +368 -0
  22. nonebot_plugin_jmdownloader/infra/pdf_utils.py +82 -0
  23. nonebot_plugin_jmdownloader/infra/search_session.py +43 -0
  24. nonebot_plugin_jmdownloader/migration.py +232 -0
  25. nonebot_plugin_jmdownloader-1.1.0.dist-info/METADATA +221 -0
  26. nonebot_plugin_jmdownloader-1.1.0.dist-info/RECORD +27 -0
  27. {nonebot_plugin_jmdownloader-1.0.3.dist-info → nonebot_plugin_jmdownloader-1.1.0.dist-info}/WHEEL +1 -2
  28. nonebot_plugin_jmdownloader/data_source.py +0 -247
  29. nonebot_plugin_jmdownloader/utils.py +0 -217
  30. nonebot_plugin_jmdownloader-1.0.3.dist-info/METADATA +0 -219
  31. nonebot_plugin_jmdownloader-1.0.3.dist-info/RECORD +0 -9
  32. nonebot_plugin_jmdownloader-1.0.3.dist-info/licenses/LICENSE +0 -21
  33. nonebot_plugin_jmdownloader-1.0.3.dist-info/top_level.txt +0 -1
@@ -1,615 +1,38 @@
1
- import asyncio
2
- import hashlib
3
- import os
4
- import random
5
- from re import A
6
- import shutil
7
- import time
1
+ """NoneBot JMComic 插件
8
2
 
9
- from httpx import get
10
- from jmcomic import (JmcomicException, JmDownloader,
11
- MissingAlbumPhotoException, create_option_by_str)
12
- from nonebot import logger, on_command, require, get_bot
13
- from nonebot.adapters.onebot.v11 import (GROUP_ADMIN, GROUP_OWNER,
14
- ActionFailed, Bot, GroupMessageEvent,
15
- Message, MessageEvent, MessageSegment,
16
- PrivateMessageEvent, NetworkError)
17
- from nonebot.params import ArgPlainText, CommandArg
18
- from nonebot.permission import SUPERUSER
19
- from nonebot.plugin import PluginMetadata
20
-
21
- from .config import (Config, cache_dir, config_data, plugin_cache_dir,
22
- plugin_config)
23
- from .data_source import data_manager, search_manager, SearchState
24
- from .utils import (blur_image_async, check_group_and_user, check_permission,
25
- download_avatar, download_photo_async,
26
- get_photo_info_async, modify_pdf_md5, search_album_async,
27
- send_forward_message)
3
+ JMComic 搜索、下载插件,支持全局屏蔽 jm 号和 tag,仅支持 OnebotV11 协议。
4
+ """
28
5
 
29
- require("nonebot_plugin_apscheduler")
6
+ from nonebot.plugin import PluginMetadata
30
7
 
31
- from nonebot_plugin_apscheduler import scheduler
8
+ from .config import PluginConfig
32
9
 
33
10
  __plugin_meta__ = PluginMetadata(
34
11
  name="JMComic插件",
35
12
  description="JMComic搜索、下载插件,支持全局屏蔽jm号和tag,仅支持OnebotV11协议。",
36
13
  usage="jm下载 [jm号]:下载指定jm号的本子\n"
37
- "jm查询 [jm号]:查询指定jm号的本子\n"
38
- "jm搜索 [关键词]:搜索包含关键词的本子\n"
39
- "jm设置文件夹 [文件夹名]:设置本群的本子储存文件夹\n",
40
- type="application", # library
14
+ "jm查询 [jm号]:查询指定jm号的本子\n"
15
+ "jm搜索 [关键词]:搜索包含关键词的本子\n"
16
+ "jm设置文件夹 [文件夹名]:设置本群的本子储存文件夹\n",
17
+ type="application",
41
18
  homepage="https://github.com/Misty02600/nonebot-plugin-jmdownloader",
42
- config=Config,
19
+ config=PluginConfig,
43
20
  supported_adapters={"~onebot.v11"},
44
21
  extra={"author": "Misty02600 <xiao02600@gmail.com>"},
45
22
  )
46
23
 
47
- option = create_option_by_str(config_data, mode="yml")
48
-
49
- try:
50
- client = option.build_jm_client()
51
- downloader = JmDownloader(option)
52
- except JmcomicException as e:
53
- logger.error(f"初始化失败: { e }")
54
-
55
- results_per_page = plugin_config.jmcomic_results_per_page
56
-
57
-
58
- # region jm功能指令
59
- jm_download = on_command("jm下载", aliases={"JM下载"}, block=True, rule=check_group_and_user)
60
- @jm_download.handle()
61
- async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
62
- photo_id = arg.extract_plain_text().strip()
63
- user_id = event.user_id
64
-
65
- if not photo_id.isdigit():
66
- await jm_download.finish("请输入要下载的jm号")
67
-
68
- if str(user_id) not in bot.config.superusers:
69
- user_limit = data_manager.get_user_limit(user_id)
70
- if user_limit <= 0:
71
- await jm_download.finish(MessageSegment.at(user_id) + f"你的下载次数已经用完了!")
72
-
73
- try:
74
- photo = await get_photo_info_async(client, photo_id)
75
- except MissingAlbumPhotoException:
76
- await jm_download.finish("未查找到本子")
77
-
78
- if photo is None:
79
- await jm_download.finish("查询时发生错误")
80
-
81
- if data_manager.is_jm_id_restricted(photo.id) or data_manager.has_restricted_tag(photo.tags):
82
- if isinstance(event, GroupMessageEvent):
83
- try:
84
- await bot.set_group_ban(group_id=event.group_id, user_id=user_id, duration=86400)
85
- except ActionFailed:
86
- pass
87
- data_manager.add_blacklist(event.group_id, user_id)
88
- await jm_download.finish(MessageSegment.at(user_id) + "该本子(或其tag)被禁止下载!你已被加入本群jm黑名单")
89
- else:
90
- await jm_download.finish("该本子(或其tag)被禁止下载!")
91
-
92
- try:
93
- if str(user_id) not in bot.config.superusers:
94
- data_manager.decrease_user_limit(user_id, 1)
95
- user_limit_new = data_manager.get_user_limit(user_id)
96
- message = Message()
97
- message += f"jm{photo.id} | {photo.title}\n"
98
- message += f"🎨 作者: {photo.author}\n"
99
- message += "🔖 标签: " + " ".join(f"#{tag}" for tag in photo.tags) + "\n"
100
- message += f"开始下载...\n你本周还有{user_limit_new}次下载次数!"
101
- await jm_download.send(message)
102
- else:
103
- message = Message()
104
- message += f"jm{photo.id} | {photo.title}\n"
105
- message += f"🎨 作者: {photo.author}\n"
106
- message += "🔖 标签: " + " ".join(f"#{tag}" for tag in photo.tags) + "\n"
107
- message += "开始下载..."
108
- await jm_download.send(message)
109
- except ActionFailed:
110
- await jm_download.send("本子信息可能被屏蔽,已开始下载")
111
- except NetworkError as e:
112
- logger.warning(f"{e},可能是协议端发送文件时间太长导致的报错")
113
-
114
- pdf_path = f"{cache_dir}/{photo.id}.pdf"
115
-
116
- # 如果不存在,则下载
117
- if not os.path.exists(pdf_path):
118
- if not await download_photo_async(downloader, photo):
119
- await jm_download.finish("下载失败")
120
-
121
- try:
122
- # 根据配置决定是否需要修改MD5
123
- if plugin_config.jmcomic_modify_real_md5:
124
- random_suffix = hashlib.md5(str(time.time() + random.random()).encode()).hexdigest()[:8]
125
- renamed_pdf_path = f"{cache_dir}/{photo.id}_{random_suffix}.pdf"
126
-
127
- modified = await asyncio.to_thread(modify_pdf_md5, pdf_path, renamed_pdf_path)
128
- if modified:
129
- pdf_path = renamed_pdf_path
130
- except Exception as e:
131
- logger.error(f"处理PDF文件时出错: {e}")
132
- await jm_download.finish("处理文件失败")
133
-
134
- try:
135
- if isinstance(event, GroupMessageEvent):
136
- folder_id = data_manager.get_group_folder_id(event.group_id)
137
-
138
- if folder_id:
139
- await bot.call_api(
140
- "upload_group_file",
141
- group_id=event.group_id,
142
- file=pdf_path,
143
- name=f"{photo.id}.pdf",
144
- folder_id=folder_id
145
- )
146
- else:
147
- await bot.call_api(
148
- "upload_group_file",
149
- group_id=event.group_id,
150
- file=pdf_path,
151
- name=f"{photo.id}.pdf"
152
- )
153
-
154
- elif isinstance(event, PrivateMessageEvent):
155
- await bot.call_api(
156
- "upload_private_file",
157
- user_id=event.user_id,
158
- file=pdf_path,
159
- name=f"{photo.id}.pdf"
160
- )
161
-
162
- except ActionFailed:
163
- await jm_download.send("发送文件失败")
164
-
165
-
166
-
167
- jm_query = on_command("jm查询", aliases={"JM查询"}, block=True, rule=check_group_and_user)
168
- @jm_query.handle()
169
- async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
170
- photo_id = arg.extract_plain_text().strip()
171
- if not photo_id.isdigit():
172
- await jm_query.finish("请输入要查询的jm号")
173
- try:
174
- photo = await get_photo_info_async(client, photo_id)
175
- except MissingAlbumPhotoException:
176
- await jm_query.finish("未查找到本子")
177
- if photo is None:
178
- await jm_query.finish("查询时发生错误")
179
-
180
- message = Message()
181
- message += f"查询到jm{photo.id}: {photo.title}\n"
182
- message += f"🎨 作者: {photo.author}\n"
183
- tags_text = " ".join(f"#{tag}" for tag in photo.tags)
184
- message += f"🔖 标签: {tags_text}\n"
185
-
186
- avatar = await download_avatar(photo.id)
187
- if avatar:
188
- avatar = await blur_image_async(avatar)
189
- message += MessageSegment.image(avatar)
190
-
191
- message_node = MessageSegment("node", {"name": "jm查询结果", "uin": bot.self_id, "content": message})
192
- messages = [message_node]
193
-
194
- try:
195
- await send_forward_message(bot, event, messages)
196
- except ActionFailed:
197
- await jm_query.finish("查询结果发送失败", reply_message=True)
198
-
199
-
200
- jm_search = on_command("jm搜索", aliases={"JM搜索"}, block=True, rule=check_group_and_user)
201
- @jm_search.handle()
202
- async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
203
- search_query = arg.extract_plain_text().strip()
204
- if not search_query:
205
- await jm_search.finish("请输入要搜索的内容")
206
-
207
- searching_msg_id = (await jm_search.send("正在搜索中..."))['message_id']
208
-
209
- page = await search_album_async(client, search_query)
210
- if page is None:
211
- await bot.delete_msg(message_id=searching_msg_id)
212
- await jm_search.finish("搜索失败", reply_message=True)
213
-
214
- search_results = list(page.iter_id())
215
- if not search_results:
216
- await bot.delete_msg(message_id=searching_msg_id)
217
- await jm_search.finish("未搜索到本子", reply_message=True)
218
-
219
- current_results = search_results[:results_per_page]
220
- photos = await asyncio.gather(*(get_photo_info_async(client, photo_id) for photo_id in current_results))
221
- avatars = await asyncio.gather(*(download_avatar(photo_id) for photo_id in current_results))
222
-
223
- messages = []
224
- blocked_message = plugin_config.jmcomic_blocked_message
225
-
226
- for photo, avatar in zip(photos, avatars):
227
- if photo is None:
228
- continue
229
-
230
- if data_manager.has_restricted_tag(photo.tags):
231
- message_node = MessageSegment("node", {
232
- "name": "jm搜索结果",
233
- "uin": bot.self_id,
234
- "content": blocked_message
235
- })
236
- else:
237
- node_content = Message()
238
- node_content += f"jm{photo.id} | {photo.title}\n"
239
- node_content += f"🎨 作者: {photo.author}\n"
240
- node_content += "🔖 标签: " + " ".join(f"#{tag}" for tag in photo.tags)
241
-
242
- if avatar:
243
- avatar = await blur_image_async(avatar)
244
- node_content += MessageSegment.image(avatar)
245
-
246
- message_node = MessageSegment("node", {
247
- "name": "jm搜索结果",
248
- "uin": bot.self_id,
249
- "content": node_content
250
- })
251
- messages.append(message_node)
252
-
253
- try:
254
- await send_forward_message(bot, event, messages)
255
- except ActionFailed:
256
- await jm_search.finish("搜索结果发送失败", reply_message=True)
257
-
258
- if len(search_results) > results_per_page:
259
- search_manager.set_state(str(event.user_id), SearchState(
260
- query=search_query,
261
- start_idx=results_per_page,
262
- total_results=search_results,
263
- api_page=1
264
- ))
265
- await jm_search.send("搜索有更多结果,使用'jm下一页'指令查看更多")
266
- else:
267
- await jm_search.send("已发送所有搜索结果")
268
-
269
- await bot.delete_msg(message_id=searching_msg_id)
270
-
271
-
272
-
273
-
274
- jm_next_page = on_command("jm 下一页", aliases={"JM 下一页", "jm下一页", "JM下一页"}, block=True, rule=check_group_and_user)
275
- @jm_next_page.handle()
276
- async def handle_jm_next_page(bot: Bot, event: MessageEvent):
277
- state = search_manager.get_state(str(event.user_id))
278
- if not state:
279
- await jm_next_page.finish("没有进行中的搜索,请先使用'jm搜索'命令")
280
-
281
- searching_msg_id = (await jm_search.send("正在搜索更多内容..."))['message_id']
282
-
283
- end_idx = state.start_idx + results_per_page
284
- # 本次是否已经返回所有结果
285
- is_return_all = False
286
-
287
- # 需要尝试调用api搜索下一页?
288
- if end_idx >= len(state.total_results):
289
- # 如果当前页数是80的倍数,说明可能还有下一页,80是JM搜索每页数量
290
- if len(state.total_results) % 80 == 0:
291
- state.api_page += 1
292
- next_page = await search_album_async(client, state.query, page=state.api_page)
293
-
294
- if next_page is None:
295
- logger.warning(f"获取下一页失败: {state.query} {state.api_page}")
296
- is_return_all = True
297
- else:
298
- next_results = list(next_page.iter_id())
299
- # 严格检查是否达到最后一页
300
- if not next_results or next_results[-1] == state.total_results[-1]:
301
- is_return_all = True
302
- else:
303
- state.total_results.extend(next_results)
304
- else:
305
- is_return_all = True
306
-
307
- current_results = state.total_results[state.start_idx:end_idx]
308
- photos = await asyncio.gather(*(get_photo_info_async(client, album_id) for album_id in current_results))
309
- avatars = await asyncio.gather(*(download_avatar(album_id) for album_id in current_results))
310
-
311
- messages = []
312
- blocked_message = plugin_config.jmcomic_blocked_message
313
-
314
- for photo, avatar in zip(photos, avatars):
315
- if photo is None:
316
- continue
317
-
318
- if data_manager.has_restricted_tag(photo.tags):
319
- message_node = MessageSegment("node", {
320
- "name": "jm搜索结果",
321
- "uin": bot.self_id,
322
- "content": blocked_message
323
- })
324
- else:
325
- node_content = Message()
326
- node_content += f"jm{photo.id} | {photo.title}\n"
327
- node_content += f"🎨 作者: {photo.author}\n"
328
- node_content += "🔖 标签: " + " ".join(f"#{tag}" for tag in photo.tags)
329
-
330
- if avatar:
331
- avatar = await blur_image_async(avatar)
332
- node_content += MessageSegment.image(avatar)
333
-
334
- message_node = MessageSegment("node", {
335
- "name": "jm搜索结果",
336
- "uin": bot.self_id,
337
- "content": node_content
338
- })
339
- messages.append(message_node)
340
-
341
- try:
342
- await send_forward_message(bot, event, messages)
343
- except ActionFailed:
344
- search_manager.remove_state(str(event.user_id))
345
- await bot.delete_msg(message_id=searching_msg_id)
346
- await jm_next_page.finish("下一页结果发送失败", reply_message=True)
347
-
348
- if is_return_all:
349
- search_manager.remove_state(str(event.user_id))
350
- await jm_next_page.send("已显示所有搜索结果")
351
- else:
352
- await jm_next_page.send("搜索有更多结果,使用'jm下一页'指令查看更多")
353
- state.start_idx = end_idx
354
-
355
- await bot.delete_msg(message_id=searching_msg_id)
356
-
357
-
358
- jm_set_folder = on_command("jm设置文件夹", aliases={"JM设置文件夹"}, permission=SUPERUSER | GROUP_ADMIN | GROUP_OWNER, block=True)
359
- @jm_set_folder.handle()
360
- async def _( bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
361
- folder_name = arg.extract_plain_text().strip()
362
- if not folder_name:
363
- await jm_set_folder.finish("请输入要设置的文件夹名称")
364
-
365
- group_id = event.group_id
24
+ # 检测并迁移旧数据
25
+ from .migration import run_migration
366
26
 
367
- found_folder_id = None
27
+ run_migration()
368
28
 
369
- try:
370
- root_data = await bot.call_api("get_group_root_files", group_id=group_id)
371
- for folder_item in root_data.get("folders", []):
372
- if folder_item.get("folder_name") == folder_name:
373
- found_folder_id = folder_item.get("folder_id")
374
- break
375
- except ActionFailed as e:
376
- logger.warning(f"获取群根目录文件夹信息失败:{e}")
377
-
378
- if found_folder_id:
379
- data_manager.set_group_folder_id(group_id, found_folder_id)
380
- await jm_set_folder.finish(f"已设置本子储存文件夹")
381
- else:
382
- try:
383
- create_result = await bot.call_api(
384
- "create_group_file_folder",
385
- group_id=group_id,
386
- folder_name=folder_name
387
- )
388
-
389
- ret_code = create_result["result"]["retCode"]
390
- if ret_code != 0:
391
- await jm_set_folder.finish("未找到该文件夹,创建文件夹失败")
392
-
393
- folder_id = create_result["groupItem"]["folderInfo"]["folderId"]
394
- data_manager.set_group_folder_id(group_id, folder_id)
395
- await jm_set_folder.finish(f"已设置本子储存文件夹")
396
-
397
- except ActionFailed as e:
398
- logger.warning("创建文件夹失败")
399
- await jm_set_folder.finish("未找到该文件夹,主动创建文件夹失败")
400
-
401
- # endregion
402
-
403
- # region jm成员黑名单指令
404
- jm_ban_user = on_command("jm拉黑", aliases={"JM拉黑"}, permission=SUPERUSER | GROUP_ADMIN | GROUP_OWNER, block=True)
405
- @jm_ban_user.handle()
406
- async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
407
- """将用户加入当前群的黑名单"""
408
- at_segment = arg[0]
409
- if at_segment.type != "at":
410
- await jm_unban_user.finish("请使用@指定要拉黑的用户")
411
-
412
- user_id = at_segment.data["qq"]
413
-
414
- user_id = int(user_id)
415
- group_id = event.group_id
416
- operator_id = event.user_id
417
-
418
- if user_id == operator_id:
419
- await jm_ban_user.finish("你拉黑你自己?")
420
-
421
- has_permission = await check_permission(bot, group_id, operator_id, user_id)
422
- if not has_permission:
423
- await jm_unban_user.finish("权限不足")
424
-
425
- data_manager.add_blacklist(group_id, user_id)
426
- await jm_ban_user.finish(MessageSegment.at(user_id) + f"已加入本群jm黑名单")
427
-
428
-
429
- jm_unban_user = on_command("jm解除拉黑", aliases={"JM解除拉黑"}, permission=SUPERUSER | GROUP_ADMIN | GROUP_OWNER, block=True)
430
- @jm_unban_user.handle()
431
- async def handle_jm_unban_user(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
432
- """将用户移出当前群的黑名单"""
433
- at_segment = arg[0]
434
- if at_segment.type != "at":
435
- await jm_unban_user.finish("请使用@指定要解除拉黑的用户")
436
-
437
- user_id = at_segment.data["qq"]
438
-
439
- user_id = int(user_id)
440
- group_id = event.group_id
441
- operator_id = event.user_id
442
-
443
- if user_id == operator_id:
444
- await jm_ban_user.finish("想都别想!")
445
-
446
- has_permission = await check_permission(bot, group_id, operator_id, user_id)
447
- if not has_permission:
448
- await jm_unban_user.finish("权限不足")
449
-
450
- data_manager.remove_blacklist(group_id, user_id)
451
- await jm_unban_user.finish(MessageSegment.at(user_id) + f"已从本群jm黑名单中移除")
452
-
453
-
454
- jm_blacklist = on_command( "jm黑名单", aliases={"JM黑名单"}, permission=SUPERUSER | GROUP_ADMIN | GROUP_OWNER, block=True)
455
- @jm_blacklist.handle()
456
- async def handle_jm_list_blacklist(bot: Bot, event: GroupMessageEvent):
457
- """列出当前群的黑名单列表"""
458
- group_id = event.group_id
459
- blacklist = data_manager.list_blacklist(group_id)
460
-
461
- if not blacklist:
462
- await jm_blacklist.finish("当前群的黑名单列表为空")
463
-
464
- msg = "当前群的黑名单列表:\n"
465
- for user_id in blacklist:
466
- msg += MessageSegment.at(user_id)
467
-
468
- await jm_blacklist.finish(msg)
469
-
470
- # endregion
471
-
472
- # region 群功能开关指令
473
- jm_enable_group = on_command("jm启用群", permission=SUPERUSER, block=True)
474
- @jm_enable_group.handle()
475
- async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
476
- """ 启用指定群号,可用空格隔开多个群 """
477
- raw_text = arg.extract_plain_text().strip()
478
-
479
- group_ids = raw_text.split()
480
- success_list = []
481
-
482
- for group_id_str in group_ids:
483
- if not group_id_str.isdigit():
484
- continue
485
-
486
- group_id = int(group_id_str)
487
- data_manager.set_group_enabled(group_id, True)
488
- success_list.append(group_id_str)
489
-
490
- msg = ""
491
- if success_list:
492
- msg += "以下群已启用插件功能:\n" + " ".join(success_list)
493
-
494
- await jm_enable_group.finish(msg.strip() or "没有做任何处理。")
495
-
496
-
497
- jm_disable_group = on_command("jm禁用群", permission=SUPERUSER, block=True)
498
- @jm_disable_group.handle()
499
- async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
500
- """ 禁用指定群号,可用空格隔开多个群 """
501
- raw_text = arg.extract_plain_text().strip()
502
-
503
- group_ids = raw_text.split()
504
- success_list = []
505
-
506
- for group_id_str in group_ids:
507
- if not group_id_str.isdigit():
508
- continue
509
-
510
- group_id = int(group_id_str)
511
- data_manager.set_group_enabled(group_id, False)
512
- success_list.append(group_id_str)
513
-
514
- msg = ""
515
- if success_list:
516
- msg += "以下群已禁用插件功能:\n" + " ".join(success_list)
517
-
518
- await jm_disable_group.finish(msg.strip() or "没有做任何处理。")
519
-
520
- jm_enable_here = on_command("开启jm", aliases={"开启JM"}, permission=SUPERUSER, block=True)
521
- @jm_enable_here.handle()
522
- async def handle_jm_enable_here(event: GroupMessageEvent):
523
- group_id = event.group_id
524
- data_manager.set_group_enabled(group_id, True)
525
- await jm_enable_here.finish("已启用本群jm功能!")
526
-
527
-
528
- jm_disable_here = on_command("关闭jm", aliases={"关闭JM"}, permission=SUPERUSER | GROUP_ADMIN | GROUP_OWNER, block=True)
529
- @jm_disable_here.got("confirm", prompt="禁用后只能请求神秘存在再次开启该功能!确认要关闭吗?发送'确认'关闭")
530
- async def _(event: GroupMessageEvent, confirm: str = ArgPlainText()):
531
- if confirm == "确认":
532
- group_id = event.group_id
533
- data_manager.set_group_enabled(group_id, False)
534
- await jm_disable_here.finish("已禁用本群jm功能!")
535
-
536
- # endregion
537
-
538
- # region 添加屏蔽tags和jm号
539
- jm_forbid_id = on_command("jm禁用id", aliases={"JM禁用id"}, permission=SUPERUSER, block=True)
540
- @jm_forbid_id.handle()
541
- async def handle_jm_forbid_id(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
542
- raw_text = arg.extract_plain_text().strip()
543
-
544
- jm_ids = raw_text.split()
545
- success_list = []
546
-
547
- for jm_id in jm_ids:
548
- if not jm_id.isdigit():
549
- continue
550
- data_manager.add_restricted_jm_id(jm_id)
551
- success_list.append(jm_id)
552
-
553
- msg = ""
554
- if success_list:
555
- msg += "以下jm号已加入禁止下载列表:\n" + " ".join(success_list)
556
-
557
- await jm_forbid_id.finish(msg.strip() or "没有做任何处理")
558
-
559
-
560
- jm_forbid_tag = on_command("jm禁用tag", aliases={"JM禁用tag"}, permission=SUPERUSER, block=True)
561
- @jm_forbid_tag.handle()
562
- async def handle_jm_forbid_tag(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
563
- raw_text = arg.extract_plain_text().strip()
564
-
565
- tags = raw_text.split()
566
- success_list = []
567
-
568
- for tag in tags:
569
- if not tag:
570
- continue
571
- data_manager.add_restricted_tag(tag)
572
- success_list.append(tag)
573
-
574
- msg = ""
575
- if success_list:
576
- msg += "以下tag已加入禁止下载列表:\n" + " ".join(success_list)
577
-
578
- await jm_forbid_tag.finish(msg.strip() or "没有做任何处理")
579
-
580
- # endregion
581
-
582
- @scheduler.scheduled_job("cron", day_of_week="mon", hour=0, minute=0, id="reset_user_limits")
583
- async def reset_user_limits():
584
- """ 每周一凌晨0点重置所有用户的下载次数 """
585
- try:
586
- user_limits = data_manager.data.get("user_limits", {})
587
-
588
- if not user_limits:
589
- logger.info("无用户下载数据可供重置。")
590
- return
591
-
592
- for user_id in user_limits.keys():
593
- data_manager.set_user_limit(int(user_id), plugin_config.jmcomic_user_limits)
594
-
595
- logger.info("所有用户的下载次数已成功刷新")
596
-
597
- except Exception as e:
598
- logger.error(f"刷新用户下载次数时出错:{e}")
599
-
600
-
601
- @scheduler.scheduled_job("cron", hour=3, minute=0)
602
- async def clear_cache_dir():
603
- """ 每天凌晨3点清理缓存文件夹 """
604
- try:
605
- if plugin_cache_dir.exists():
606
- shutil.rmtree(plugin_cache_dir)
607
- plugin_cache_dir.mkdir(parents=True, exist_ok=True)
608
- logger.info(f"已成功清理缓存目录:{cache_dir}")
609
- except Exception as e:
610
- logger.error(f"清理缓存目录失败:{e}")
611
-
612
- @scheduler.scheduled_job("interval", minutes=10)
613
- async def clean_expired_search_states():
614
- """ 定期清理过期的搜索状态 """
615
- search_manager.clean_expired()
29
+ # 导入命令模块以注册所有命令处理器
30
+ from .bot.handlers import ( # noqa: F401
31
+ ban_id_tag,
32
+ blacklist,
33
+ download,
34
+ group_control,
35
+ query,
36
+ scheduled,
37
+ search,
38
+ )
@@ -0,0 +1,18 @@
1
+ """Bot 层
2
+
3
+ NoneBot 相关的依赖注入。
4
+ """
5
+
6
+ from .dependencies import (
7
+ DataManagerDep,
8
+ JmServiceDep,
9
+ SessionsDep,
10
+ plugin_cache_dir,
11
+ )
12
+
13
+ __all__ = [
14
+ "DataManagerDep",
15
+ "JmServiceDep",
16
+ "SessionsDep",
17
+ "plugin_cache_dir",
18
+ ]