pymecli 0.4.2__tar.gz → 0.4.3__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.
- {pymecli-0.4.2 → pymecli-0.4.3}/PKG-INFO +3 -1
- {pymecli-0.4.2 → pymecli-0.4.3}/README.md +2 -0
- pymecli-0.4.3/api/v1/clash.py +62 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/core/clash.py +215 -10
- {pymecli-0.4.2 → pymecli-0.4.3}/data/template.yaml +16 -21
- {pymecli-0.4.2 → pymecli-0.4.3}/pyproject.toml +1 -1
- pymecli-0.4.2/api/v1/clash.py +0 -34
- {pymecli-0.4.2 → pymecli-0.4.3}/.gitignore +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/api/__init__.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/api/v1/__init__.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/api/v1/redis.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/cli/__init__.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/cli/baidu.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/cli/bitget.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/cli/example.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/cli/fast.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/cli/gate.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/cli/redis_csv.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/cli/util.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/core/__init__.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/core/config.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/core/redis_client.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/crypto/__init__.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/crypto/bitget.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/crypto/gate.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/data/__init__.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/data/dou_dict.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/data/dou_list.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/data/main.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/models/__init__.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/models/douzero_model.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/models/ocr_model.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/models/response.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/utils/__init__.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/utils/elapsed.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/utils/helper.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/utils/logger.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/utils/mysql.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/utils/path.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/utils/pd.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/utils/pyredis.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/utils/sleep.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/utils/text.py +0 -0
- {pymecli-0.4.2 → pymecli-0.4.3}/utils/toml.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pymecli
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: My CLI
|
|
5
5
|
Project-URL: Homepage, https://pypi.org/project/pymecli
|
|
6
6
|
Project-URL: Repository, https://github.com/meme2046/pymecli
|
|
@@ -43,4 +43,6 @@ uv run example goodbye Xiaoming -f
|
|
|
43
43
|
|
|
44
44
|
```shell
|
|
45
45
|
uv run fast --port 8877
|
|
46
|
+
uv build
|
|
47
|
+
uv publish --token (TOKEN)
|
|
46
48
|
```
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import yaml
|
|
2
|
+
from fastapi import APIRouter, Query, Response
|
|
3
|
+
|
|
4
|
+
from core.clash import ClashYamlGenerator, get_generator_dependency
|
|
5
|
+
|
|
6
|
+
router = APIRouter()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@router.get(
|
|
10
|
+
"/subwhite",
|
|
11
|
+
summary="转换订阅(可以转换多个订阅)",
|
|
12
|
+
description="根据提供的URL、User-Agent和名称获取并处理订阅信息,返回YAML格式的Clash配置",
|
|
13
|
+
response_description="返回YAML格式的Clash配置文件",
|
|
14
|
+
)
|
|
15
|
+
async def subWhite(
|
|
16
|
+
urls: str = Query(..., description="订阅URL,逗号分隔"),
|
|
17
|
+
agents: str = Query(
|
|
18
|
+
"clash-verge/v2.4.3",
|
|
19
|
+
description="User-Agent,逗号分隔(根据客户段选择)",
|
|
20
|
+
),
|
|
21
|
+
names: str = Query(
|
|
22
|
+
"订阅1", description="订阅名称,逗号分隔(可选,在客户端中的显示名)"
|
|
23
|
+
),
|
|
24
|
+
generator: ClashYamlGenerator = get_generator_dependency(),
|
|
25
|
+
):
|
|
26
|
+
# 将JSON字符串解析为Python对象
|
|
27
|
+
sub_list = generator.query2sub(urls, agents, names)
|
|
28
|
+
yaml_content, userinfo = generator.genW(sub_list)
|
|
29
|
+
yaml_string = yaml.dump(yaml_content, allow_unicode=True, default_flow_style=False)
|
|
30
|
+
return Response(
|
|
31
|
+
headers={"Subscription-Userinfo": userinfo},
|
|
32
|
+
content=yaml_string,
|
|
33
|
+
media_type="text/yaml",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@router.get(
|
|
38
|
+
"/subblack",
|
|
39
|
+
summary="转换订阅(可以转换多个订阅)",
|
|
40
|
+
description="根据提供的URL、User-Agent和名称获取并处理订阅信息,返回YAML格式的Clash配置",
|
|
41
|
+
response_description="返回YAML格式的Clash配置文件",
|
|
42
|
+
)
|
|
43
|
+
async def subBlack(
|
|
44
|
+
urls: str = Query(..., description="订阅URL,逗号分隔"),
|
|
45
|
+
agents: str = Query(
|
|
46
|
+
"clash-verge/v2.4.3",
|
|
47
|
+
description="User-Agent,逗号分隔(根据客户段选择)",
|
|
48
|
+
),
|
|
49
|
+
names: str = Query(
|
|
50
|
+
"订阅1", description="订阅名称,逗号分隔(可选,在客户端中的显示名)"
|
|
51
|
+
),
|
|
52
|
+
generator: ClashYamlGenerator = get_generator_dependency(),
|
|
53
|
+
):
|
|
54
|
+
# 将JSON字符串解析为Python对象
|
|
55
|
+
sub_list = generator.query2sub(urls, agents, names)
|
|
56
|
+
yaml_content, userinfo = generator.genB(sub_list)
|
|
57
|
+
yaml_string = yaml.dump(yaml_content, allow_unicode=True, default_flow_style=False)
|
|
58
|
+
return Response(
|
|
59
|
+
headers={"Subscription-Userinfo": userinfo},
|
|
60
|
+
content=yaml_string,
|
|
61
|
+
media_type="text/yaml",
|
|
62
|
+
)
|
|
@@ -21,7 +21,8 @@ class ClashYamlGenerator:
|
|
|
21
21
|
self.my_rule_base_url = config.my_rule_base_url
|
|
22
22
|
self.request_proxy = config.request_proxy
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
# 白名单模式 Rules 配置方式
|
|
25
|
+
def genW(self, sub_list: list[dict]):
|
|
25
26
|
proxies = None
|
|
26
27
|
if self.request_proxy:
|
|
27
28
|
proxies = {
|
|
@@ -57,7 +58,7 @@ class ClashYamlGenerator:
|
|
|
57
58
|
{
|
|
58
59
|
"name": "轮询",
|
|
59
60
|
"type": "load-balance",
|
|
60
|
-
"url": "https://
|
|
61
|
+
"url": "https://api.bitget.com/api/v2/public/time",
|
|
61
62
|
"interval": 300,
|
|
62
63
|
"lazy": True,
|
|
63
64
|
"strategy": "round-robin",
|
|
@@ -102,10 +103,13 @@ class ClashYamlGenerator:
|
|
|
102
103
|
},
|
|
103
104
|
)
|
|
104
105
|
|
|
106
|
+
template["rules"].append("IP-CIDR,192.168.0.0/16,DIRECT,no-resolve")
|
|
107
|
+
template["rules"].append("IP-CIDR,10.0.0.0/8,DIRECT,no-resolve")
|
|
108
|
+
template["rules"].append("IP-CIDR,172.16.0.0/12,DIRECT,no-resolve")
|
|
109
|
+
template["rules"].append("IP-CIDR,127.0.0.0/8,DIRECT,no-resolve")
|
|
110
|
+
|
|
105
111
|
template["rules"].append("DOMAIN,clash.razord.top,DIRECT")
|
|
106
112
|
template["rules"].append("DOMAIN,yacd.haishan.me,DIRECT")
|
|
107
|
-
template["rules"].append("DOMAIN-SUFFIX,kleientertainment.com,全局选择")
|
|
108
|
-
template["rules"].append("DOMAIN-SUFFIX,klei.com,全局选择")
|
|
109
113
|
# 获取rules
|
|
110
114
|
rule_list = [
|
|
111
115
|
[f"{self.my_rule_base_url}/direct.yaml", "DIRECT"],
|
|
@@ -115,8 +119,8 @@ class ClashYamlGenerator:
|
|
|
115
119
|
"轮询",
|
|
116
120
|
],
|
|
117
121
|
[
|
|
118
|
-
f"{self.my_rule_base_url}/
|
|
119
|
-
"
|
|
122
|
+
f"{self.my_rule_base_url}/reject.yaml",
|
|
123
|
+
"REJECT",
|
|
120
124
|
],
|
|
121
125
|
]
|
|
122
126
|
|
|
@@ -214,6 +218,14 @@ class ClashYamlGenerator:
|
|
|
214
218
|
"path": "./ruleset/telegramcidr.yaml",
|
|
215
219
|
"interval": 86400,
|
|
216
220
|
},
|
|
221
|
+
# "reject": {
|
|
222
|
+
# "type": "http",
|
|
223
|
+
# "format": "yaml",
|
|
224
|
+
# "behavior": "domain",
|
|
225
|
+
# "url": f"{self.rule_base_url}/reject.txt",
|
|
226
|
+
# "path": "./ruleset/reject.yaml",
|
|
227
|
+
# "interval": 86400,
|
|
228
|
+
# },
|
|
217
229
|
},
|
|
218
230
|
)
|
|
219
231
|
|
|
@@ -221,22 +233,215 @@ class ClashYamlGenerator:
|
|
|
221
233
|
[
|
|
222
234
|
"RULE-SET,applications,DIRECT",
|
|
223
235
|
"RULE-SET,private,DIRECT",
|
|
236
|
+
# "RULE-SET,reject,REJECT",
|
|
224
237
|
"RULE-SET,icloud,DIRECT",
|
|
225
238
|
"RULE-SET,apple,DIRECT",
|
|
226
239
|
"RULE-SET,google,全局选择",
|
|
227
240
|
"RULE-SET,proxy,全局选择",
|
|
228
241
|
"RULE-SET,direct,DIRECT",
|
|
229
|
-
"RULE-SET,lancidr,DIRECT
|
|
230
|
-
"RULE-SET,cncidr,DIRECT
|
|
242
|
+
"RULE-SET,lancidr,DIRECT",
|
|
243
|
+
"RULE-SET,cncidr,DIRECT",
|
|
231
244
|
"RULE-SET,telegramcidr,全局选择",
|
|
232
|
-
"GEOIP,LAN,DIRECT
|
|
233
|
-
"GEOIP,CN,DIRECT
|
|
245
|
+
"GEOIP,LAN,DIRECT",
|
|
246
|
+
"GEOIP,CN,DIRECT",
|
|
234
247
|
"MATCH,全局选择",
|
|
235
248
|
]
|
|
236
249
|
)
|
|
237
250
|
|
|
238
251
|
return template, userinfo
|
|
239
252
|
|
|
253
|
+
# 黑名单模式 Rules 配置方式
|
|
254
|
+
def genB(self, sub_list: list[dict]):
|
|
255
|
+
proxies = None
|
|
256
|
+
if self.request_proxy:
|
|
257
|
+
proxies = {
|
|
258
|
+
"http": self.request_proxy,
|
|
259
|
+
"https": self.request_proxy,
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
with open(str(module_dir / "data/template.yaml"), "r", encoding="utf-8") as f:
|
|
263
|
+
template = yaml.safe_load(f)
|
|
264
|
+
|
|
265
|
+
template["proxy-groups"].extend(
|
|
266
|
+
[
|
|
267
|
+
{
|
|
268
|
+
"name": "全局选择",
|
|
269
|
+
"type": "select",
|
|
270
|
+
"proxies": ["自动选择", "手动选择", "轮询"]
|
|
271
|
+
+ [item["name"] for item in sub_list],
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"name": "自动选择",
|
|
275
|
+
"type": "url-test",
|
|
276
|
+
"url": "https://www.gstatic.com/generate_204",
|
|
277
|
+
"interval": 300,
|
|
278
|
+
"tolerance": 11,
|
|
279
|
+
"lazy": True,
|
|
280
|
+
"use": [f"provider.{item['name']}" for item in sub_list],
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"name": "手动选择",
|
|
284
|
+
"type": "select",
|
|
285
|
+
"use": [f"provider.{item['name']}" for item in sub_list],
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"name": "轮询",
|
|
289
|
+
"type": "load-balance",
|
|
290
|
+
"url": "https://api.bitget.com/api/v2/public/time",
|
|
291
|
+
"interval": 300,
|
|
292
|
+
"lazy": True,
|
|
293
|
+
"strategy": "round-robin",
|
|
294
|
+
"use": [f"provider.{item['name']}" for item in sub_list],
|
|
295
|
+
},
|
|
296
|
+
]
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
userinfo = ""
|
|
300
|
+
for item in sub_list:
|
|
301
|
+
headers = {"User-Agent": item["user_agent"]} if item["user_agent"] else {}
|
|
302
|
+
|
|
303
|
+
if not item["url"]:
|
|
304
|
+
raise ValueError("Invalid subscription URL.")
|
|
305
|
+
response = requests.get(item["url"], headers=headers, proxies=proxies)
|
|
306
|
+
response.raise_for_status()
|
|
307
|
+
if not userinfo:
|
|
308
|
+
userinfo = response.headers["Subscription-Userinfo"]
|
|
309
|
+
remote_config = yaml.safe_load(response.text)
|
|
310
|
+
|
|
311
|
+
# 检查 remote_config 是否为 None
|
|
312
|
+
if remote_config is None:
|
|
313
|
+
raise ValueError("Invalid subscription content: empty or invalid YAML.")
|
|
314
|
+
|
|
315
|
+
ps = remote_config.get("proxies", [])
|
|
316
|
+
if not ps:
|
|
317
|
+
raise ValueError("No proxies found in subscription.")
|
|
318
|
+
|
|
319
|
+
template["proxy-providers"][f"provider.{item['name']}"] = {
|
|
320
|
+
"type": "inline",
|
|
321
|
+
"payload": ps,
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
template["proxy-groups"].append(
|
|
325
|
+
{
|
|
326
|
+
"name": item["name"],
|
|
327
|
+
"type": "url-test",
|
|
328
|
+
"url": "https://www.gstatic.com/generate_204",
|
|
329
|
+
"interval": 300,
|
|
330
|
+
"tolerance": 11,
|
|
331
|
+
"lazy": True,
|
|
332
|
+
"use": [f"provider.{item['name']}"],
|
|
333
|
+
},
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
template["rules"].append("IP-CIDR,192.168.0.0/16,DIRECT,no-resolve")
|
|
337
|
+
template["rules"].append("IP-CIDR,10.0.0.0/8,DIRECT,no-resolve")
|
|
338
|
+
template["rules"].append("IP-CIDR,172.16.0.0/12,DIRECT,no-resolve")
|
|
339
|
+
template["rules"].append("IP-CIDR,127.0.0.0/8,DIRECT,no-resolve")
|
|
340
|
+
# ⬇️饥荒服务器相关端口
|
|
341
|
+
template["rules"].append("DST-PORT,10999,DIRECT")
|
|
342
|
+
template["rules"].append("DST-PORT,10998,DIRECT")
|
|
343
|
+
template["rules"].append("DST-PORT,27016,DIRECT")
|
|
344
|
+
template["rules"].append("DST-PORT,27017,DIRECT")
|
|
345
|
+
template["rules"].append("DST-PORT,8766,DIRECT")
|
|
346
|
+
template["rules"].append("DST-PORT,8767,DIRECT")
|
|
347
|
+
|
|
348
|
+
template["rules"].append("DOMAIN,clash.razord.top,DIRECT")
|
|
349
|
+
template["rules"].append("DOMAIN,yacd.haishan.me,DIRECT")
|
|
350
|
+
# template["rules"].append("DOMAIN,accounts.klei.com,全局选择")
|
|
351
|
+
|
|
352
|
+
# 获取rules
|
|
353
|
+
rule_list = [
|
|
354
|
+
[f"{self.my_rule_base_url}/direct.yaml", "DIRECT"],
|
|
355
|
+
[f"{self.my_rule_base_url}/proxy.yaml", "全局选择"],
|
|
356
|
+
[
|
|
357
|
+
f"{self.my_rule_base_url}/round.yaml",
|
|
358
|
+
"轮询",
|
|
359
|
+
],
|
|
360
|
+
[
|
|
361
|
+
f"{self.my_rule_base_url}/reject.yaml",
|
|
362
|
+
"REJECT",
|
|
363
|
+
],
|
|
364
|
+
]
|
|
365
|
+
|
|
366
|
+
for item in rule_list:
|
|
367
|
+
response = requests.get(item[0], proxies=proxies)
|
|
368
|
+
response.raise_for_status()
|
|
369
|
+
remote = yaml.safe_load(response.text)
|
|
370
|
+
template["rule-providers"][os.path.basename(item[0])] = {
|
|
371
|
+
"type": "inline",
|
|
372
|
+
"behavior": "classical",
|
|
373
|
+
"payload": remote["payload"],
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
template["rules"].append(f"RULE-SET,{os.path.basename(item[0])},{item[1]}")
|
|
377
|
+
|
|
378
|
+
template["rule-providers"].update(
|
|
379
|
+
{
|
|
380
|
+
"applications": {
|
|
381
|
+
"type": "http",
|
|
382
|
+
"format": "yaml",
|
|
383
|
+
"behavior": "classical",
|
|
384
|
+
"url": f"{self.rule_base_url}/applications.txt",
|
|
385
|
+
"path": "./ruleset/applications.yaml",
|
|
386
|
+
"interval": 86400,
|
|
387
|
+
},
|
|
388
|
+
"private": {
|
|
389
|
+
"type": "http",
|
|
390
|
+
"format": "yaml",
|
|
391
|
+
"behavior": "domain",
|
|
392
|
+
"url": f"{self.rule_base_url}/private.txt",
|
|
393
|
+
"path": "./ruleset/private.yaml",
|
|
394
|
+
"interval": 86400,
|
|
395
|
+
},
|
|
396
|
+
"tld-not-cn": {
|
|
397
|
+
"type": "http",
|
|
398
|
+
"format": "yaml",
|
|
399
|
+
"behavior": "domain",
|
|
400
|
+
"url": f"{self.rule_base_url}/tld-not-cn.txt",
|
|
401
|
+
"path": "./ruleset/tld-not-cn.yaml",
|
|
402
|
+
"interval": 86400,
|
|
403
|
+
},
|
|
404
|
+
"telegramcidr": {
|
|
405
|
+
"type": "http",
|
|
406
|
+
"format": "yaml",
|
|
407
|
+
"behavior": "ipcidr",
|
|
408
|
+
"url": f"{self.rule_base_url}/telegramcidr.txt",
|
|
409
|
+
"path": "./ruleset/telegramcidr.yaml",
|
|
410
|
+
"interval": 86400,
|
|
411
|
+
},
|
|
412
|
+
"gfw": {
|
|
413
|
+
"type": "http",
|
|
414
|
+
"format": "yaml",
|
|
415
|
+
"behavior": "domain",
|
|
416
|
+
"url": f"{self.rule_base_url}/gfw.txt",
|
|
417
|
+
"path": "./ruleset/gfw.yaml",
|
|
418
|
+
"interval": 86400,
|
|
419
|
+
},
|
|
420
|
+
# "reject": {
|
|
421
|
+
# "type": "http",
|
|
422
|
+
# "format": "yaml",
|
|
423
|
+
# "behavior": "domain",
|
|
424
|
+
# "url": f"{self.rule_base_url}/reject.txt",
|
|
425
|
+
# "path": "./ruleset/reject.yaml",
|
|
426
|
+
# "interval": 86400,
|
|
427
|
+
# },
|
|
428
|
+
},
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
template["rules"].extend(
|
|
432
|
+
[
|
|
433
|
+
"RULE-SET,applications,DIRECT",
|
|
434
|
+
"RULE-SET,private,DIRECT",
|
|
435
|
+
# "RULE-SET,reject,REJECT",
|
|
436
|
+
"RULE-SET,tld-not-cn,全局选择",
|
|
437
|
+
"RULE-SET,gfw,全局选择",
|
|
438
|
+
"RULE-SET,telegramcidr,全局选择",
|
|
439
|
+
"MATCH,DIRECT",
|
|
440
|
+
]
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
return template, userinfo
|
|
444
|
+
|
|
240
445
|
def query2sub(self, urls: str, agents: str, names: str):
|
|
241
446
|
url_list = urls.split(",") if urls and urls.strip() else []
|
|
242
447
|
agents_list = agents.split(",") if agents else []
|
|
@@ -12,15 +12,15 @@ tun:
|
|
|
12
12
|
mtu: 1500
|
|
13
13
|
dns:
|
|
14
14
|
enable: true
|
|
15
|
-
listen: ":
|
|
15
|
+
listen: ":53"
|
|
16
16
|
enhanced-mode: "fake-ip"
|
|
17
17
|
fake-ip-range: "198.18.0.1/16"
|
|
18
18
|
fake-ip-filter-mode: "blacklist"
|
|
19
19
|
prefer-h3: false
|
|
20
|
-
respect-rules: false
|
|
21
|
-
use-hosts:
|
|
22
|
-
use-system-hosts:
|
|
23
|
-
ipv6:
|
|
20
|
+
respect-rules: false
|
|
21
|
+
use-hosts: false
|
|
22
|
+
use-system-hosts: false
|
|
23
|
+
ipv6: true
|
|
24
24
|
fake-ip-filter:
|
|
25
25
|
- "*.lan"
|
|
26
26
|
- "*.local"
|
|
@@ -32,22 +32,17 @@ dns:
|
|
|
32
32
|
- "localhost.ptlogin2.qq.com"
|
|
33
33
|
- "*.msftncsi.com"
|
|
34
34
|
- "www.msftconnecttest.com"
|
|
35
|
-
|
|
36
|
-
- "
|
|
37
|
-
- "
|
|
38
|
-
- "
|
|
39
|
-
- "
|
|
40
|
-
- "
|
|
41
|
-
default-nameserver: # 默认 DNS 服务器
|
|
42
|
-
- "223.5.5.5" # 阿里云 DNS(国内)
|
|
43
|
-
- "8.8.8.8" # Google DNS(国外)
|
|
44
|
-
- "2400:3200::1" # 阿里云 IPv6 DNS
|
|
45
|
-
- "2001:4860:4860::8888" # Google IPv6 DNS
|
|
35
|
+
default-nameserver:
|
|
36
|
+
- "system"
|
|
37
|
+
- "223.6.6.6"
|
|
38
|
+
- "8.8.8.8"
|
|
39
|
+
- "2400:3200::1"
|
|
40
|
+
- "2001:4860:4860::8888"
|
|
46
41
|
nameserver:
|
|
47
|
-
- "8.8.8.8"
|
|
48
|
-
- "https://doh.pub/dns-query"
|
|
49
|
-
- "https://dns.alidns.com/dns-query"
|
|
50
|
-
|
|
42
|
+
- "8.8.8.8"
|
|
43
|
+
- "https://doh.pub/dns-query"
|
|
44
|
+
- "https://dns.alidns.com/dns-query"
|
|
45
|
+
direct-nameserver-follow-policy: false
|
|
51
46
|
fallback-filter:
|
|
52
47
|
geoip: true
|
|
53
48
|
geoip-code: "CN"
|
|
@@ -58,11 +53,11 @@ dns:
|
|
|
58
53
|
- "+.google.com"
|
|
59
54
|
- "+.facebook.com"
|
|
60
55
|
- "+.youtube.com"
|
|
56
|
+
fallback: []
|
|
61
57
|
proxy-server-nameserver:
|
|
62
58
|
- "https://doh.pub/dns-query"
|
|
63
59
|
- "https://dns.alidns.com/dns-query"
|
|
64
60
|
- "tls://223.5.5.5"
|
|
65
|
-
direct-nameserver-follow-policy: false # 直连域名的 DNS 不遵循代理规则
|
|
66
61
|
direct-nameserver: []
|
|
67
62
|
external-controller-cors:
|
|
68
63
|
allow-private-network: true
|
pymecli-0.4.2/api/v1/clash.py
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import yaml
|
|
2
|
-
from fastapi import APIRouter, Query, Response
|
|
3
|
-
|
|
4
|
-
from core.clash import ClashYamlGenerator, get_generator_dependency
|
|
5
|
-
|
|
6
|
-
router = APIRouter()
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@router.get(
|
|
10
|
-
"/sub",
|
|
11
|
-
summary="转换订阅(可以转换多个订阅)",
|
|
12
|
-
description="根据提供的URL、User-Agent和名称获取并处理订阅信息,返回YAML格式的Clash配置",
|
|
13
|
-
response_description="返回YAML格式的Clash配置文件",
|
|
14
|
-
)
|
|
15
|
-
async def sub(
|
|
16
|
-
urls: str = Query(..., description="订阅URL,逗号分隔"),
|
|
17
|
-
agents: str = Query(
|
|
18
|
-
"clash-verge/v2.4.3",
|
|
19
|
-
description="User-Agent,逗号分隔(根据客户段选择)",
|
|
20
|
-
),
|
|
21
|
-
names: str = Query(
|
|
22
|
-
"订阅1", description="订阅名称,逗号分隔(可选,在客户端中的显示名)"
|
|
23
|
-
),
|
|
24
|
-
generator: ClashYamlGenerator = get_generator_dependency(),
|
|
25
|
-
):
|
|
26
|
-
# 将JSON字符串解析为Python对象
|
|
27
|
-
sub_list = generator.query2sub(urls, agents, names)
|
|
28
|
-
yaml_content, userinfo = generator.gen(sub_list)
|
|
29
|
-
yaml_string = yaml.dump(yaml_content, allow_unicode=True, default_flow_style=False)
|
|
30
|
-
return Response(
|
|
31
|
-
headers={"Subscription-Userinfo": userinfo},
|
|
32
|
-
content=yaml_string,
|
|
33
|
-
media_type="text/yaml",
|
|
34
|
-
)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|