nonebot-plugin-bittorrents 1.1.0__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_bittorrents-1.1.0/LICENSE +19 -0
- nonebot_plugin_bittorrents-1.1.0/PKG-INFO +63 -0
- nonebot_plugin_bittorrents-1.1.0/README.md +44 -0
- nonebot_plugin_bittorrents-1.1.0/nonebot_plugin_BitTorrents/__init__.py +13 -0
- nonebot_plugin_bittorrents-1.1.0/nonebot_plugin_BitTorrents/main.py +289 -0
- nonebot_plugin_bittorrents-1.1.0/nonebot_plugin_bittorrents.egg-info/PKG-INFO +63 -0
- nonebot_plugin_bittorrents-1.1.0/nonebot_plugin_bittorrents.egg-info/SOURCES.txt +10 -0
- nonebot_plugin_bittorrents-1.1.0/nonebot_plugin_bittorrents.egg-info/dependency_links.txt +1 -0
- nonebot_plugin_bittorrents-1.1.0/nonebot_plugin_bittorrents.egg-info/requires.txt +7 -0
- nonebot_plugin_bittorrents-1.1.0/nonebot_plugin_bittorrents.egg-info/top_level.txt +1 -0
- nonebot_plugin_bittorrents-1.1.0/pyproject.toml +32 -0
- nonebot_plugin_bittorrents-1.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
Copyright (c) 2020 NoneBot Team
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
5
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
6
|
+
the Software without restriction, including without limitation the rights to
|
|
7
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
8
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
9
|
+
subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
16
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
17
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
18
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
19
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nonebot-plugin-bittorrents
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: 适配NoneBot的磁力搜索插件,通过机器人帮你寻找电影、软件或者学习资料
|
|
5
|
+
Author: NightDust981989
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: homepage, https://github.com/NightDust981989/nonebot-plugin-BitTorrents
|
|
8
|
+
Project-URL: repository, https://github.com/NightDust981989/nonebot-plugin-BitTorrents
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: httpx
|
|
12
|
+
Requires-Dist: beautifulsoup4
|
|
13
|
+
Requires-Dist: lxml
|
|
14
|
+
Requires-Dist: pydantic
|
|
15
|
+
Requires-Dist: pydantic-settings
|
|
16
|
+
Requires-Dist: nonebot2
|
|
17
|
+
Requires-Dist: nonebot-adapter-onebot
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# NoneBot 磁力搜索插件
|
|
21
|
+
适配磁力狗的磁力链接搜索插件,支持更新站点地址、返回结果数等配置,纯静态HTTP请求实现。
|
|
22
|
+
|
|
23
|
+
## 核心特性
|
|
24
|
+
1. 突破磁力狗重定向反爬:关闭自动重定向,提取原始搜索结果
|
|
25
|
+
2. 配置完全自定义:支持修改站点地址、接口路径、超时时间等
|
|
26
|
+
3. 自动解密:复刻站点window.atob+unescape加密逻辑
|
|
27
|
+
4. 轻量无依赖:仅需基础HTTP/解析库,无需Playwright/Selenium
|
|
28
|
+
|
|
29
|
+
## 环境要求
|
|
30
|
+
- NoneBot 插件运行环境
|
|
31
|
+
- 网络可访问目标磁力狗站点
|
|
32
|
+
|
|
33
|
+
## 部署方法
|
|
34
|
+
直接到插件商店安装即可
|
|
35
|
+
|
|
36
|
+
## 配置文件修改
|
|
37
|
+
在 .env 文件即可更改
|
|
38
|
+
|
|
39
|
+
## 配置项说明
|
|
40
|
+
| 配置项 | 说明 | 默认值 |
|
|
41
|
+
|-----------------|----------------------------------------------------------------------|---------------------------------|
|
|
42
|
+
| base_url | 磁力狗站点基础地址,支持更换备用域名(如站点失效时)| https://clg2.clgapp1.xyz |
|
|
43
|
+
| search_path | 搜索接口路径,正常无需更改 | /cllj.php |
|
|
44
|
+
| max_results | 单次搜索返回的最大结果数,建议 3-5 条(过多会增加解密耗时)| 3 |
|
|
45
|
+
| request_timeout | HTTP 请求超时时间(秒),详情页解密需耗时,建议 15-20 秒 | 15 |
|
|
46
|
+
|
|
47
|
+
## 使用方法
|
|
48
|
+
### 发送指令:
|
|
49
|
+
bt (排序方式) [搜索关键词]
|
|
50
|
+
### 示例:
|
|
51
|
+
bt 热门 安达与岛村
|
|
52
|
+
|
|
53
|
+
## 说明
|
|
54
|
+
### 排序方式
|
|
55
|
+
- 相关度:按相关度从高到低排序(默认)
|
|
56
|
+
- 热门/热门程度:按热门度从高到低排序
|
|
57
|
+
- 时间/最新:按时间从新到旧排序
|
|
58
|
+
- 大小/文件大小:按文件大小从大到小排序
|
|
59
|
+
|
|
60
|
+
当原站点失效时,请访问 https://ciligoufabuye3.xyz 或发邮件至 clgdzzh@gmail.com 更新地址
|
|
61
|
+
|
|
62
|
+
## 许可证
|
|
63
|
+
本插件遵循和NoneBot相同的许可证
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# NoneBot 磁力搜索插件
|
|
2
|
+
适配磁力狗的磁力链接搜索插件,支持更新站点地址、返回结果数等配置,纯静态HTTP请求实现。
|
|
3
|
+
|
|
4
|
+
## 核心特性
|
|
5
|
+
1. 突破磁力狗重定向反爬:关闭自动重定向,提取原始搜索结果
|
|
6
|
+
2. 配置完全自定义:支持修改站点地址、接口路径、超时时间等
|
|
7
|
+
3. 自动解密:复刻站点window.atob+unescape加密逻辑
|
|
8
|
+
4. 轻量无依赖:仅需基础HTTP/解析库,无需Playwright/Selenium
|
|
9
|
+
|
|
10
|
+
## 环境要求
|
|
11
|
+
- NoneBot 插件运行环境
|
|
12
|
+
- 网络可访问目标磁力狗站点
|
|
13
|
+
|
|
14
|
+
## 部署方法
|
|
15
|
+
直接到插件商店安装即可
|
|
16
|
+
|
|
17
|
+
## 配置文件修改
|
|
18
|
+
在 .env 文件即可更改
|
|
19
|
+
|
|
20
|
+
## 配置项说明
|
|
21
|
+
| 配置项 | 说明 | 默认值 |
|
|
22
|
+
|-----------------|----------------------------------------------------------------------|---------------------------------|
|
|
23
|
+
| base_url | 磁力狗站点基础地址,支持更换备用域名(如站点失效时)| https://clg2.clgapp1.xyz |
|
|
24
|
+
| search_path | 搜索接口路径,正常无需更改 | /cllj.php |
|
|
25
|
+
| max_results | 单次搜索返回的最大结果数,建议 3-5 条(过多会增加解密耗时)| 3 |
|
|
26
|
+
| request_timeout | HTTP 请求超时时间(秒),详情页解密需耗时,建议 15-20 秒 | 15 |
|
|
27
|
+
|
|
28
|
+
## 使用方法
|
|
29
|
+
### 发送指令:
|
|
30
|
+
bt (排序方式) [搜索关键词]
|
|
31
|
+
### 示例:
|
|
32
|
+
bt 热门 安达与岛村
|
|
33
|
+
|
|
34
|
+
## 说明
|
|
35
|
+
### 排序方式
|
|
36
|
+
- 相关度:按相关度从高到低排序(默认)
|
|
37
|
+
- 热门/热门程度:按热门度从高到低排序
|
|
38
|
+
- 时间/最新:按时间从新到旧排序
|
|
39
|
+
- 大小/文件大小:按文件大小从大到小排序
|
|
40
|
+
|
|
41
|
+
当原站点失效时,请访问 https://ciligoufabuye3.xyz 或发邮件至 clgdzzh@gmail.com 更新地址
|
|
42
|
+
|
|
43
|
+
## 许可证
|
|
44
|
+
本插件遵循和NoneBot相同的许可证
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from nonebot.plugin import PluginMetadata
|
|
2
|
+
from .main import Config
|
|
3
|
+
|
|
4
|
+
__plugin_meta__ = PluginMetadata(
|
|
5
|
+
name="BitTorrent磁力搜索",
|
|
6
|
+
description="适配NoneBot的磁力搜索插件,通过机器人帮你寻找电影、软件或者学习资料",
|
|
7
|
+
usage="bt (排序方式) [关键词]",
|
|
8
|
+
type="application",
|
|
9
|
+
homepage="https://github.com/NightDust981989/nonebot-plugin-BitTorrents",
|
|
10
|
+
config=Config,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from . import main
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import base64
|
|
3
|
+
import urllib.parse
|
|
4
|
+
from typing import List, Dict
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
from bs4 import BeautifulSoup
|
|
9
|
+
from nonebot import on_command
|
|
10
|
+
from nonebot.adapters import Message
|
|
11
|
+
from nonebot.params import CommandArg
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
from pydantic import BaseSettings
|
|
15
|
+
except ImportError:
|
|
16
|
+
from pydantic_settings import BaseSettings
|
|
17
|
+
|
|
18
|
+
# ========== 1. 配置映射类(从配置文件读取参数) ==========
|
|
19
|
+
@dataclass
|
|
20
|
+
class MagnetConfig:
|
|
21
|
+
"""磁力搜索配置类"""
|
|
22
|
+
base_url: str = "https://clg2.clgapp1.xyz" # 站点基础地址
|
|
23
|
+
search_path: str = "/cllj.php" # 搜索接口路径
|
|
24
|
+
max_results: int = 3 # 最大返回结果数
|
|
25
|
+
request_timeout: int = 15 # 请求超时时间(秒)
|
|
26
|
+
captcha_cookies: Dict[str, str] = None # 验证Cookie(固定值)
|
|
27
|
+
|
|
28
|
+
def __post_init__(self):
|
|
29
|
+
# 初始化固定验证Cookie
|
|
30
|
+
self.captcha_cookies = {
|
|
31
|
+
"sssfwz2": "qwsdsddsdsdse",
|
|
32
|
+
"aywcUid": "lwgkvwDiYQ_20211009155217"
|
|
33
|
+
}
|
|
34
|
+
# 处理base_url结尾的/(统一格式:不带结尾/)
|
|
35
|
+
if self.base_url.endswith("/"):
|
|
36
|
+
self.base_url = self.base_url.rstrip("/")
|
|
37
|
+
# 处理search_path开头的/(统一格式:带开头/)
|
|
38
|
+
if not self.search_path.startswith("/"):
|
|
39
|
+
self.search_path = f"/{self.search_path}"
|
|
40
|
+
|
|
41
|
+
# ========== 2. 核心工具类 ==========
|
|
42
|
+
class MagnetUtils:
|
|
43
|
+
@staticmethod
|
|
44
|
+
def decrypt_base64(encrypted_str: str) -> str:
|
|
45
|
+
"""Base64解密"""
|
|
46
|
+
try:
|
|
47
|
+
encrypted_str = encrypted_str.ljust(len(encrypted_str) + (4 - len(encrypted_str) % 4) % 4, '=')
|
|
48
|
+
decoded = base64.b64decode(encrypted_str).decode('utf-8', errors='ignore')
|
|
49
|
+
return urllib.parse.unquote(decoded)
|
|
50
|
+
except Exception as e:
|
|
51
|
+
print(f"Base64解密失败:{str(e)}")
|
|
52
|
+
return ""
|
|
53
|
+
|
|
54
|
+
@staticmethod
|
|
55
|
+
def get_full_url(base_url: str, relative_url: str) -> str:
|
|
56
|
+
"""拼接完整URL"""
|
|
57
|
+
if relative_url.startswith("http"):
|
|
58
|
+
return relative_url
|
|
59
|
+
if relative_url.startswith("./"):
|
|
60
|
+
return f"{base_url}/{relative_url[2:]}"
|
|
61
|
+
if relative_url.startswith("/"):
|
|
62
|
+
return f"{base_url}{relative_url}"
|
|
63
|
+
return f"{base_url}/{relative_url}"
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def get_sort_param(sort_keyword: str) -> str:
|
|
67
|
+
"""
|
|
68
|
+
排序关键词
|
|
69
|
+
"""
|
|
70
|
+
sort_mapping = {
|
|
71
|
+
"相关度": "",
|
|
72
|
+
"大小": "length",
|
|
73
|
+
"文件大小": "length",
|
|
74
|
+
"热门": "hot",
|
|
75
|
+
"热门程度": "hot",
|
|
76
|
+
"时间": "time",
|
|
77
|
+
"最新": "time",
|
|
78
|
+
}
|
|
79
|
+
# 提高鲁棒性
|
|
80
|
+
sort_keyword = sort_keyword.strip().lower()
|
|
81
|
+
for key, value in sort_mapping.items():
|
|
82
|
+
if key.lower() == sort_keyword:
|
|
83
|
+
return value
|
|
84
|
+
# 匹配不到返回空
|
|
85
|
+
return ""
|
|
86
|
+
|
|
87
|
+
# ========== 3. 核心搜索服务 ==========
|
|
88
|
+
class MagnetSearchService:
|
|
89
|
+
def __init__(self, config: MagnetConfig):
|
|
90
|
+
self.config = config
|
|
91
|
+
self.client: httpx.AsyncClient = None
|
|
92
|
+
|
|
93
|
+
async def _init_client(self):
|
|
94
|
+
"""初始化客户端:使用配置文件的超时时间"""
|
|
95
|
+
headers = {
|
|
96
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
|
97
|
+
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
98
|
+
"Accept-Language": "zh-CN,zh;q=0.9",
|
|
99
|
+
"Origin": self.config.base_url,
|
|
100
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
101
|
+
"Referer": self.config.base_url
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
self.client = httpx.AsyncClient(
|
|
105
|
+
headers=headers,
|
|
106
|
+
cookies=self.config.captcha_cookies,
|
|
107
|
+
timeout=self.config.request_timeout, # 从配置读取超时时间
|
|
108
|
+
follow_redirects=False, # 关闭自动重定向
|
|
109
|
+
verify=False
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
async def search(self, keyword: str, sort_param: str = "") -> List[str]:
|
|
113
|
+
"""搜索逻辑:使用配置文件的站点/接口/结果数"""
|
|
114
|
+
await self._init_client()
|
|
115
|
+
results = []
|
|
116
|
+
|
|
117
|
+
try:
|
|
118
|
+
# ========== 构造搜索URL ==========
|
|
119
|
+
search_url = f"{self.config.base_url}{self.config.search_path}?name={urllib.parse.quote(keyword)}"
|
|
120
|
+
# 拼接排序参数
|
|
121
|
+
if sort_param:
|
|
122
|
+
search_url += f"&sort={sort_param}"
|
|
123
|
+
print(f"GET请求:{search_url}")
|
|
124
|
+
|
|
125
|
+
# 发起请求
|
|
126
|
+
response = await self.client.get(search_url)
|
|
127
|
+
print(f"响应状态码:{response.status_code}")
|
|
128
|
+
|
|
129
|
+
# 提取原始响应
|
|
130
|
+
raw_html = response.text
|
|
131
|
+
|
|
132
|
+
# ========== 解密原始响应 ==========
|
|
133
|
+
encrypt_match = re.search(r"window\.atob\('([^']+)'", raw_html)
|
|
134
|
+
if not encrypt_match:
|
|
135
|
+
print(f"未找到window.atob加密串")
|
|
136
|
+
return []
|
|
137
|
+
|
|
138
|
+
decrypted_html = MagnetUtils.decrypt_base64(encrypt_match.group(1))
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
# ========== 提取xq.php链接(使用配置) ==========
|
|
142
|
+
soup = BeautifulSoup(decrypted_html, "lxml")
|
|
143
|
+
result_container = soup.find("ul", id="Search_list_wrapper")
|
|
144
|
+
if not result_container:
|
|
145
|
+
print(f"解密后仍无搜索结果容器")
|
|
146
|
+
return []
|
|
147
|
+
|
|
148
|
+
detail_links = []
|
|
149
|
+
processed_urls = set()
|
|
150
|
+
# 遍历结果:最多取配置的max_results条
|
|
151
|
+
for idx, li in enumerate(result_container.find_all("li")):
|
|
152
|
+
if idx >= self.config.max_results: # 从配置读取最大结果数
|
|
153
|
+
break
|
|
154
|
+
if li.find("ul", class_="pagination"):
|
|
155
|
+
continue
|
|
156
|
+
|
|
157
|
+
link_tag = li.find("a", href=re.compile(r"xq\.php\?key="))
|
|
158
|
+
if not link_tag:
|
|
159
|
+
continue
|
|
160
|
+
|
|
161
|
+
full_url = MagnetUtils.get_full_url(self.config.base_url, link_tag.get("href"))
|
|
162
|
+
if full_url in processed_urls:
|
|
163
|
+
continue
|
|
164
|
+
processed_urls.add(full_url)
|
|
165
|
+
|
|
166
|
+
# 提取基础信息
|
|
167
|
+
title = link_tag.text.strip() or f"搜索结果{idx+1}"
|
|
168
|
+
size = re.search(r"文件大小:([0-9.]+ [GMK]B)", li.text)
|
|
169
|
+
size = size.group(1).strip() if size else "未知大小"
|
|
170
|
+
create_time = re.search(r"创建时间:(\d{4}-\d{2}-\d{2})", li.text)
|
|
171
|
+
create_time = create_time.group(1).strip() if create_time else "未知时间"
|
|
172
|
+
|
|
173
|
+
detail_links.append({
|
|
174
|
+
"url": full_url,
|
|
175
|
+
"title": title,
|
|
176
|
+
"size": size,
|
|
177
|
+
"create_time": create_time
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
if not detail_links:
|
|
181
|
+
return []
|
|
182
|
+
|
|
183
|
+
# ========== 解析详情页 ==========
|
|
184
|
+
for link in detail_links:
|
|
185
|
+
try:
|
|
186
|
+
detail_resp = await self.client.get(link["url"], follow_redirects=False)
|
|
187
|
+
detail_raw = detail_resp.text
|
|
188
|
+
|
|
189
|
+
# 解密详情页
|
|
190
|
+
detail_encrypt = re.search(r"window\.atob\('([^']+)'", detail_raw)
|
|
191
|
+
detail_html = detail_raw
|
|
192
|
+
if detail_encrypt:
|
|
193
|
+
detail_html = MagnetUtils.decrypt_base64(detail_encrypt.group(1))
|
|
194
|
+
|
|
195
|
+
# 提取磁力链接 - 保持原始逻辑,使用全局soup对象
|
|
196
|
+
magnet_link = None
|
|
197
|
+
magnet_a = soup.find("a", href=re.compile(r"magnet:\?xt=urn:btih:"))
|
|
198
|
+
if magnet_a:
|
|
199
|
+
magnet_link = magnet_a.get("href").strip()
|
|
200
|
+
if not magnet_link:
|
|
201
|
+
magnet_match = re.search(r"magnet:\?xt=urn:btih:[a-fA-F0-9]{40,}[^\"']*", detail_html)
|
|
202
|
+
if magnet_match:
|
|
203
|
+
magnet_link = magnet_match.group().strip()
|
|
204
|
+
|
|
205
|
+
# 构造结果
|
|
206
|
+
results.append(
|
|
207
|
+
f"标题:{link['title']}\n"
|
|
208
|
+
f"磁力链接:{magnet_link or '未提取到'}\n"
|
|
209
|
+
f"文件大小:{link['size']}\n"
|
|
210
|
+
f"收录时间:{link['create_time']}"
|
|
211
|
+
)
|
|
212
|
+
except Exception as e:
|
|
213
|
+
results.append(f"标题:{link['title']}\n解析失败:{str(e)[:30]}\n文件大小:{link['size']}")
|
|
214
|
+
|
|
215
|
+
except Exception as e:
|
|
216
|
+
print(f"搜索异常:{str(e)}")
|
|
217
|
+
results = [f"搜索失败:{str(e)[:50]}"]
|
|
218
|
+
finally:
|
|
219
|
+
if self.client:
|
|
220
|
+
await self.client.aclose()
|
|
221
|
+
|
|
222
|
+
return results
|
|
223
|
+
|
|
224
|
+
# ========== 4. 初始化配置和服务 ==========
|
|
225
|
+
# 从 nonebot 配置中获取参数,如果不存在则使用默认值
|
|
226
|
+
from nonebot import get_driver
|
|
227
|
+
|
|
228
|
+
class Config(BaseSettings):
|
|
229
|
+
magnet_base_url: str = "https://clg2.clgapp1.xyz"
|
|
230
|
+
magnet_search_path: str = "/cllj.php"
|
|
231
|
+
magnet_max_results: int = 3
|
|
232
|
+
magnet_request_timeout: int = 15
|
|
233
|
+
|
|
234
|
+
class Config:
|
|
235
|
+
extra = "allow"
|
|
236
|
+
|
|
237
|
+
driver = get_driver()
|
|
238
|
+
global_config = driver.config
|
|
239
|
+
plugin_config = Config(**global_config.dict())
|
|
240
|
+
|
|
241
|
+
# 初始化配置类
|
|
242
|
+
magnet_config = MagnetConfig(
|
|
243
|
+
base_url=plugin_config.magnet_base_url,
|
|
244
|
+
search_path=plugin_config.magnet_search_path,
|
|
245
|
+
max_results=plugin_config.magnet_max_results,
|
|
246
|
+
request_timeout=plugin_config.magnet_request_timeout
|
|
247
|
+
)
|
|
248
|
+
search_service = MagnetSearchService(magnet_config)
|
|
249
|
+
|
|
250
|
+
print(f"磁力搜索插件初始化完成,使用站点:{magnet_config.base_url}{magnet_config.search_path}")
|
|
251
|
+
|
|
252
|
+
# ========== 5. 注册命令处理器 ==========
|
|
253
|
+
bt_cmd = on_command("bt", aliases=set(), priority=10, block=True)
|
|
254
|
+
|
|
255
|
+
@bt_cmd.handle()
|
|
256
|
+
async def handle_bt_command(args: Message = CommandArg()):
|
|
257
|
+
message = str(args).strip()
|
|
258
|
+
args_list = message.split()
|
|
259
|
+
|
|
260
|
+
# 检查参数是否足够
|
|
261
|
+
if not message or len(args_list) < 1:
|
|
262
|
+
await bt_cmd.finish("用法:bt (排序方式) [关键词]\n示例:bt 热门 安达与岛村")
|
|
263
|
+
|
|
264
|
+
# 解析排序参数和关键词
|
|
265
|
+
sort_keyword = ""
|
|
266
|
+
keyword = ""
|
|
267
|
+
if len(args_list) == 1:
|
|
268
|
+
# 默认相关度
|
|
269
|
+
keyword = args_list[0]
|
|
270
|
+
else:
|
|
271
|
+
# 有排序参数
|
|
272
|
+
sort_keyword = args_list[0]
|
|
273
|
+
keyword = " ".join(args_list[1:])
|
|
274
|
+
|
|
275
|
+
# 转换排序关键词为sort
|
|
276
|
+
sort_param = MagnetUtils.get_sort_param(sort_keyword)
|
|
277
|
+
# 执行搜索
|
|
278
|
+
results = await search_service.search(keyword, sort_param)
|
|
279
|
+
|
|
280
|
+
if not results:
|
|
281
|
+
# 无结果
|
|
282
|
+
await bt_cmd.finish("未找到相关磁力链接")
|
|
283
|
+
else:
|
|
284
|
+
# 有结果时拼接完整内容
|
|
285
|
+
result_text = f"共找到 {len(results)} 条有效结果:\n"
|
|
286
|
+
for idx, res in enumerate(results, 1):
|
|
287
|
+
result_text += f"\n===== 结果 {idx} =====\n{res}"
|
|
288
|
+
|
|
289
|
+
await bt_cmd.finish(result_text)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nonebot-plugin-bittorrents
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: 适配NoneBot的磁力搜索插件,通过机器人帮你寻找电影、软件或者学习资料
|
|
5
|
+
Author: NightDust981989
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: homepage, https://github.com/NightDust981989/nonebot-plugin-BitTorrents
|
|
8
|
+
Project-URL: repository, https://github.com/NightDust981989/nonebot-plugin-BitTorrents
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: httpx
|
|
12
|
+
Requires-Dist: beautifulsoup4
|
|
13
|
+
Requires-Dist: lxml
|
|
14
|
+
Requires-Dist: pydantic
|
|
15
|
+
Requires-Dist: pydantic-settings
|
|
16
|
+
Requires-Dist: nonebot2
|
|
17
|
+
Requires-Dist: nonebot-adapter-onebot
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# NoneBot 磁力搜索插件
|
|
21
|
+
适配磁力狗的磁力链接搜索插件,支持更新站点地址、返回结果数等配置,纯静态HTTP请求实现。
|
|
22
|
+
|
|
23
|
+
## 核心特性
|
|
24
|
+
1. 突破磁力狗重定向反爬:关闭自动重定向,提取原始搜索结果
|
|
25
|
+
2. 配置完全自定义:支持修改站点地址、接口路径、超时时间等
|
|
26
|
+
3. 自动解密:复刻站点window.atob+unescape加密逻辑
|
|
27
|
+
4. 轻量无依赖:仅需基础HTTP/解析库,无需Playwright/Selenium
|
|
28
|
+
|
|
29
|
+
## 环境要求
|
|
30
|
+
- NoneBot 插件运行环境
|
|
31
|
+
- 网络可访问目标磁力狗站点
|
|
32
|
+
|
|
33
|
+
## 部署方法
|
|
34
|
+
直接到插件商店安装即可
|
|
35
|
+
|
|
36
|
+
## 配置文件修改
|
|
37
|
+
在 .env 文件即可更改
|
|
38
|
+
|
|
39
|
+
## 配置项说明
|
|
40
|
+
| 配置项 | 说明 | 默认值 |
|
|
41
|
+
|-----------------|----------------------------------------------------------------------|---------------------------------|
|
|
42
|
+
| base_url | 磁力狗站点基础地址,支持更换备用域名(如站点失效时)| https://clg2.clgapp1.xyz |
|
|
43
|
+
| search_path | 搜索接口路径,正常无需更改 | /cllj.php |
|
|
44
|
+
| max_results | 单次搜索返回的最大结果数,建议 3-5 条(过多会增加解密耗时)| 3 |
|
|
45
|
+
| request_timeout | HTTP 请求超时时间(秒),详情页解密需耗时,建议 15-20 秒 | 15 |
|
|
46
|
+
|
|
47
|
+
## 使用方法
|
|
48
|
+
### 发送指令:
|
|
49
|
+
bt (排序方式) [搜索关键词]
|
|
50
|
+
### 示例:
|
|
51
|
+
bt 热门 安达与岛村
|
|
52
|
+
|
|
53
|
+
## 说明
|
|
54
|
+
### 排序方式
|
|
55
|
+
- 相关度:按相关度从高到低排序(默认)
|
|
56
|
+
- 热门/热门程度:按热门度从高到低排序
|
|
57
|
+
- 时间/最新:按时间从新到旧排序
|
|
58
|
+
- 大小/文件大小:按文件大小从大到小排序
|
|
59
|
+
|
|
60
|
+
当原站点失效时,请访问 https://ciligoufabuye3.xyz 或发邮件至 clgdzzh@gmail.com 更新地址
|
|
61
|
+
|
|
62
|
+
## 许可证
|
|
63
|
+
本插件遵循和NoneBot相同的许可证
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
nonebot_plugin_BitTorrents/__init__.py
|
|
5
|
+
nonebot_plugin_BitTorrents/main.py
|
|
6
|
+
nonebot_plugin_bittorrents.egg-info/PKG-INFO
|
|
7
|
+
nonebot_plugin_bittorrents.egg-info/SOURCES.txt
|
|
8
|
+
nonebot_plugin_bittorrents.egg-info/dependency_links.txt
|
|
9
|
+
nonebot_plugin_bittorrents.egg-info/requires.txt
|
|
10
|
+
nonebot_plugin_bittorrents.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nonebot_plugin_BitTorrents
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "nonebot-plugin-bittorrents"
|
|
3
|
+
version = "1.1.0"
|
|
4
|
+
description = "适配NoneBot的磁力搜索插件,通过机器人帮你寻找电影、软件或者学习资料"
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "NightDust981989"}
|
|
7
|
+
]
|
|
8
|
+
license = "MIT"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"httpx",
|
|
12
|
+
"beautifulsoup4",
|
|
13
|
+
"lxml",
|
|
14
|
+
"pydantic",
|
|
15
|
+
"pydantic-settings",
|
|
16
|
+
"nonebot2",
|
|
17
|
+
"nonebot-adapter-onebot"
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.urls]
|
|
21
|
+
homepage = "https://github.com/NightDust981989/nonebot-plugin-BitTorrents"
|
|
22
|
+
repository = "https://github.com/NightDust981989/nonebot-plugin-BitTorrents"
|
|
23
|
+
|
|
24
|
+
[build-system]
|
|
25
|
+
requires = ["setuptools>=61.0","wheel"]
|
|
26
|
+
build-backend = "setuptools.build_meta"
|
|
27
|
+
|
|
28
|
+
[tool.setuptools.packages.find]
|
|
29
|
+
include = ["nonebot_plugin_BitTorrents*"]
|
|
30
|
+
|
|
31
|
+
[tool.nonebot]
|
|
32
|
+
plugins = ["nonebot_plugin_BitTorrents"]
|