pymecli 0.4.4__tar.gz → 0.4.5__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.4 → pymecli-0.4.5}/PKG-INFO +1 -1
- pymecli-0.4.5/api/v1/clash.py +113 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/cli/fast.py +2 -2
- {pymecli-0.4.4 → pymecli-0.4.5}/core/clash.py +181 -9
- {pymecli-0.4.4 → pymecli-0.4.5}/data/template.yaml +70 -70
- {pymecli-0.4.4 → pymecli-0.4.5}/pyproject.toml +1 -1
- pymecli-0.4.4/api/v1/clash.py +0 -62
- {pymecli-0.4.4 → pymecli-0.4.5}/.gitignore +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/README.md +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/api/__init__.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/api/v1/__init__.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/api/v1/redis.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/cli/__init__.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/cli/baidu.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/cli/bitget.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/cli/dst.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/cli/example.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/cli/gate.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/cli/redis_csv.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/cli/util.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/core/__init__.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/core/config.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/core/redis_client.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/crypto/__init__.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/crypto/bitget.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/crypto/gate.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/data/__init__.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/data/dou_dict.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/data/dou_list.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/data/main.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/models/__init__.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/models/douzero_model.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/models/ocr_model.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/models/response.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/utils/__init__.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/utils/elapsed.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/utils/helper.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/utils/logger.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/utils/mysql.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/utils/path.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/utils/pd.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/utils/pyredis.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/utils/sleep.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/utils/text.py +0 -0
- {pymecli-0.4.4 → pymecli-0.4.5}/utils/toml.py +0 -0
|
@@ -0,0 +1,113 @@
|
|
|
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
|
+
class NoAnchorDumper(yaml.Dumper):
|
|
10
|
+
def ignore_aliases(self, data):
|
|
11
|
+
return True
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@router.get(
|
|
15
|
+
"/subpw",
|
|
16
|
+
summary="转换订阅(可以转换多个订阅),proxy-providers方式合并多个订阅,白名单模式",
|
|
17
|
+
description="根据提供的URL、User-Agent和名称获取并处理订阅信息,返回YAML格式的Clash配置",
|
|
18
|
+
response_description="返回YAML格式的Clash配置文件",
|
|
19
|
+
)
|
|
20
|
+
async def subProviderWhite(
|
|
21
|
+
urls: str = Query(..., description="订阅URL,逗号分隔"),
|
|
22
|
+
agents: str = Query(
|
|
23
|
+
"clash-verge/v2.4.3",
|
|
24
|
+
description="User-Agent,逗号分隔(根据客户段选择)",
|
|
25
|
+
),
|
|
26
|
+
names: str = Query(
|
|
27
|
+
"订阅1", description="订阅名称,逗号分隔(可选,在客户端中的显示名)"
|
|
28
|
+
),
|
|
29
|
+
generator: ClashYamlGenerator = get_generator_dependency(),
|
|
30
|
+
):
|
|
31
|
+
# 将JSON字符串解析为Python对象
|
|
32
|
+
sub_list = generator.query2sub(urls, agents, names)
|
|
33
|
+
yaml_content, userinfo = generator.genPW(sub_list)
|
|
34
|
+
yaml_string = yaml.dump(
|
|
35
|
+
yaml_content,
|
|
36
|
+
allow_unicode=True,
|
|
37
|
+
default_flow_style=False,
|
|
38
|
+
sort_keys=False,
|
|
39
|
+
# Dumper=NoAnchorDumper,
|
|
40
|
+
)
|
|
41
|
+
return Response(
|
|
42
|
+
headers={"Subscription-Userinfo": userinfo},
|
|
43
|
+
content=yaml_string,
|
|
44
|
+
media_type="text/yaml",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@router.get(
|
|
49
|
+
"/subpb",
|
|
50
|
+
summary="转换订阅(可以转换多个订阅),proxy-providers方式合并多个订阅, 黑名单模式",
|
|
51
|
+
description="根据提供的URL、User-Agent和名称获取并处理订阅信息,返回YAML格式的Clash配置",
|
|
52
|
+
response_description="返回YAML格式的Clash配置文件",
|
|
53
|
+
)
|
|
54
|
+
async def subProviderBlack(
|
|
55
|
+
urls: str = Query(..., description="订阅URL,逗号分隔"),
|
|
56
|
+
agents: str = Query(
|
|
57
|
+
"clash-verge/v2.4.3",
|
|
58
|
+
description="User-Agent,逗号分隔(根据客户段选择)",
|
|
59
|
+
),
|
|
60
|
+
names: str = Query(
|
|
61
|
+
"订阅1", description="订阅名称,逗号分隔(可选,在客户端中的显示名)"
|
|
62
|
+
),
|
|
63
|
+
generator: ClashYamlGenerator = get_generator_dependency(),
|
|
64
|
+
):
|
|
65
|
+
# 将JSON字符串解析为Python对象
|
|
66
|
+
sub_list = generator.query2sub(urls, agents, names)
|
|
67
|
+
yaml_content, userinfo = generator.genPB(sub_list)
|
|
68
|
+
yaml_string = yaml.dump(
|
|
69
|
+
yaml_content,
|
|
70
|
+
allow_unicode=True,
|
|
71
|
+
default_flow_style=False,
|
|
72
|
+
sort_keys=False,
|
|
73
|
+
# Dumper=NoAnchorDumper,
|
|
74
|
+
)
|
|
75
|
+
return Response(
|
|
76
|
+
headers={"Subscription-Userinfo": userinfo},
|
|
77
|
+
content=yaml_string,
|
|
78
|
+
media_type="text/yaml",
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@router.get(
|
|
83
|
+
"/subb",
|
|
84
|
+
summary="转换订阅(可以转换多个订阅),拼接proxies的方式合并多个订阅, 黑名单模式",
|
|
85
|
+
description="根据提供的URL、User-Agent和名称获取并处理订阅信息,返回YAML格式的Clash配置",
|
|
86
|
+
response_description="返回YAML格式的Clash配置文件",
|
|
87
|
+
)
|
|
88
|
+
async def subBlack(
|
|
89
|
+
urls: str = Query(..., description="订阅URL,逗号分隔"),
|
|
90
|
+
agents: str = Query(
|
|
91
|
+
"clash-verge/v2.4.3",
|
|
92
|
+
description="User-Agent,逗号分隔(根据客户段选择)",
|
|
93
|
+
),
|
|
94
|
+
names: str = Query(
|
|
95
|
+
"订阅1", description="订阅名称,逗号分隔(可选,在客户端中的显示名)"
|
|
96
|
+
),
|
|
97
|
+
generator: ClashYamlGenerator = get_generator_dependency(),
|
|
98
|
+
):
|
|
99
|
+
# 将JSON字符串解析为Python对象
|
|
100
|
+
sub_list = generator.query2sub(urls, agents, names)
|
|
101
|
+
yaml_content, userinfo = generator.genB(sub_list)
|
|
102
|
+
yaml_string = yaml.dump(
|
|
103
|
+
yaml_content,
|
|
104
|
+
allow_unicode=True,
|
|
105
|
+
default_flow_style=False,
|
|
106
|
+
sort_keys=False,
|
|
107
|
+
# Dumper=NoAnchorDumper,
|
|
108
|
+
)
|
|
109
|
+
return Response(
|
|
110
|
+
headers={"Subscription-Userinfo": userinfo},
|
|
111
|
+
content=yaml_string,
|
|
112
|
+
media_type="text/yaml",
|
|
113
|
+
)
|
|
@@ -136,13 +136,13 @@ def run_app(
|
|
|
136
136
|
help="ssl certfile",
|
|
137
137
|
),
|
|
138
138
|
rule: str = typer.Option(
|
|
139
|
-
"https://
|
|
139
|
+
"https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release",
|
|
140
140
|
"--rule",
|
|
141
141
|
"-r",
|
|
142
142
|
help="clash Rule base URL",
|
|
143
143
|
),
|
|
144
144
|
my_rule: str = typer.Option(
|
|
145
|
-
"https://
|
|
145
|
+
"https://fastly.jsdelivr.net/gh/meme2046/data@main/clash",
|
|
146
146
|
"--my-rule",
|
|
147
147
|
"-mr",
|
|
148
148
|
help="my clash rule base URL(自定义规则)",
|
|
@@ -22,7 +22,7 @@ class ClashYamlGenerator:
|
|
|
22
22
|
self.request_proxy = config.request_proxy
|
|
23
23
|
|
|
24
24
|
# 白名单模式 Rules 配置方式
|
|
25
|
-
def
|
|
25
|
+
def genPW(self, sub_list: list[dict]):
|
|
26
26
|
proxies = None
|
|
27
27
|
if self.request_proxy:
|
|
28
28
|
proxies = {
|
|
@@ -103,13 +103,6 @@ class ClashYamlGenerator:
|
|
|
103
103
|
},
|
|
104
104
|
)
|
|
105
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
|
-
|
|
111
|
-
template["rules"].append("DOMAIN,clash.razord.top,DIRECT")
|
|
112
|
-
template["rules"].append("DOMAIN,yacd.haishan.me,DIRECT")
|
|
113
106
|
# 获取rules
|
|
114
107
|
rule_list = [
|
|
115
108
|
[f"{self.my_rule_base_url}/direct.yaml", "DIRECT"],
|
|
@@ -251,7 +244,7 @@ class ClashYamlGenerator:
|
|
|
251
244
|
return template, userinfo
|
|
252
245
|
|
|
253
246
|
# 黑名单模式 Rules 配置方式
|
|
254
|
-
def
|
|
247
|
+
def genPB(self, sub_list: list[dict]):
|
|
255
248
|
proxies = None
|
|
256
249
|
if self.request_proxy:
|
|
257
250
|
proxies = {
|
|
@@ -442,6 +435,185 @@ class ClashYamlGenerator:
|
|
|
442
435
|
|
|
443
436
|
return template, userinfo
|
|
444
437
|
|
|
438
|
+
def genB(self, sub_list: list[dict]):
|
|
439
|
+
proxies = None
|
|
440
|
+
if self.request_proxy:
|
|
441
|
+
proxies = {
|
|
442
|
+
"http": self.request_proxy,
|
|
443
|
+
"https": self.request_proxy,
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
with open(str(module_dir / "data/template.yaml"), "r", encoding="utf-8") as f:
|
|
447
|
+
template = yaml.safe_load(f)
|
|
448
|
+
|
|
449
|
+
template["proxy-groups"].extend(
|
|
450
|
+
[
|
|
451
|
+
{
|
|
452
|
+
"name": "全局选择",
|
|
453
|
+
"type": "select",
|
|
454
|
+
"proxies": ["自动选择", "手动选择", "轮询"]
|
|
455
|
+
+ [item["name"] for item in sub_list],
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
"name": "自动选择",
|
|
459
|
+
"type": "url-test",
|
|
460
|
+
"include-all": True,
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
"name": "手动选择",
|
|
464
|
+
"type": "select",
|
|
465
|
+
"include-all": True,
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
"name": "轮询",
|
|
469
|
+
"type": "load-balance",
|
|
470
|
+
"url": "https://api.bitget.com/api/v2/public/time",
|
|
471
|
+
"strategy": "round-robin",
|
|
472
|
+
"include-all": True,
|
|
473
|
+
},
|
|
474
|
+
]
|
|
475
|
+
)
|
|
476
|
+
|
|
477
|
+
userinfo = ""
|
|
478
|
+
template["proxies"] = []
|
|
479
|
+
for item in sub_list:
|
|
480
|
+
headers = {"User-Agent": item["user_agent"]} if item["user_agent"] else {}
|
|
481
|
+
|
|
482
|
+
if not item["url"]:
|
|
483
|
+
raise ValueError("Invalid subscription URL.")
|
|
484
|
+
response = requests.get(item["url"], headers=headers, proxies=proxies)
|
|
485
|
+
response.raise_for_status()
|
|
486
|
+
if not userinfo:
|
|
487
|
+
userinfo = response.headers["Subscription-Userinfo"]
|
|
488
|
+
remote_config = yaml.safe_load(response.text)
|
|
489
|
+
|
|
490
|
+
# 检查 remote_config 是否为 None
|
|
491
|
+
if remote_config is None:
|
|
492
|
+
raise ValueError("Invalid subscription content: empty or invalid YAML.")
|
|
493
|
+
|
|
494
|
+
ps = remote_config.get("proxies", [])
|
|
495
|
+
if not ps:
|
|
496
|
+
raise ValueError("No proxies found in subscription.")
|
|
497
|
+
|
|
498
|
+
template["proxies"].extend(ps)
|
|
499
|
+
|
|
500
|
+
template["proxy-groups"].append(
|
|
501
|
+
{
|
|
502
|
+
"name": item["name"],
|
|
503
|
+
"type": "url-test",
|
|
504
|
+
"proxies": [item["name"] for item in ps],
|
|
505
|
+
},
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
template["rules"].append("IP-CIDR,192.168.0.0/16,DIRECT,no-resolve")
|
|
509
|
+
template["rules"].append("IP-CIDR,10.0.0.0/8,DIRECT,no-resolve")
|
|
510
|
+
template["rules"].append("IP-CIDR,172.16.0.0/12,DIRECT,no-resolve")
|
|
511
|
+
template["rules"].append("IP-CIDR,127.0.0.0/8,DIRECT,no-resolve")
|
|
512
|
+
# ⬇️饥荒服务器相关端口
|
|
513
|
+
template["rules"].append("DST-PORT,10999,DIRECT")
|
|
514
|
+
template["rules"].append("DST-PORT,10998,DIRECT")
|
|
515
|
+
template["rules"].append("DST-PORT,27016,DIRECT")
|
|
516
|
+
template["rules"].append("DST-PORT,27017,DIRECT")
|
|
517
|
+
template["rules"].append("DST-PORT,8766,DIRECT")
|
|
518
|
+
template["rules"].append("DST-PORT,8767,DIRECT")
|
|
519
|
+
|
|
520
|
+
template["rules"].append("DOMAIN,clash.razord.top,DIRECT")
|
|
521
|
+
template["rules"].append("DOMAIN,yacd.haishan.me,DIRECT")
|
|
522
|
+
# template["rules"].append("DOMAIN,accounts.klei.com,全局选择")
|
|
523
|
+
|
|
524
|
+
# 获取rules
|
|
525
|
+
rule_list = [
|
|
526
|
+
[f"{self.my_rule_base_url}/direct.yaml", "DIRECT"],
|
|
527
|
+
[f"{self.my_rule_base_url}/proxy.yaml", "全局选择"],
|
|
528
|
+
[
|
|
529
|
+
f"{self.my_rule_base_url}/round.yaml",
|
|
530
|
+
"轮询",
|
|
531
|
+
],
|
|
532
|
+
[
|
|
533
|
+
f"{self.my_rule_base_url}/reject.yaml",
|
|
534
|
+
"REJECT",
|
|
535
|
+
],
|
|
536
|
+
]
|
|
537
|
+
|
|
538
|
+
for item in rule_list:
|
|
539
|
+
response = requests.get(item[0], proxies=proxies)
|
|
540
|
+
response.raise_for_status()
|
|
541
|
+
remote = yaml.safe_load(response.text)
|
|
542
|
+
template["rule-providers"][os.path.basename(item[0])] = {
|
|
543
|
+
"type": "inline",
|
|
544
|
+
"behavior": "classical",
|
|
545
|
+
"payload": remote["payload"],
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
template["rules"].append(f"RULE-SET,{os.path.basename(item[0])},{item[1]}")
|
|
549
|
+
|
|
550
|
+
template["rule-providers"].update(
|
|
551
|
+
{
|
|
552
|
+
"applications": {
|
|
553
|
+
"type": "http",
|
|
554
|
+
"format": "yaml",
|
|
555
|
+
"behavior": "classical",
|
|
556
|
+
"url": f"{self.rule_base_url}/applications.txt",
|
|
557
|
+
"path": "./ruleset/applications.yaml",
|
|
558
|
+
"interval": 86400,
|
|
559
|
+
},
|
|
560
|
+
"private": {
|
|
561
|
+
"type": "http",
|
|
562
|
+
"format": "yaml",
|
|
563
|
+
"behavior": "domain",
|
|
564
|
+
"url": f"{self.rule_base_url}/private.txt",
|
|
565
|
+
"path": "./ruleset/private.yaml",
|
|
566
|
+
"interval": 86400,
|
|
567
|
+
},
|
|
568
|
+
"tld-not-cn": {
|
|
569
|
+
"type": "http",
|
|
570
|
+
"format": "yaml",
|
|
571
|
+
"behavior": "domain",
|
|
572
|
+
"url": f"{self.rule_base_url}/tld-not-cn.txt",
|
|
573
|
+
"path": "./ruleset/tld-not-cn.yaml",
|
|
574
|
+
"interval": 86400,
|
|
575
|
+
},
|
|
576
|
+
"telegramcidr": {
|
|
577
|
+
"type": "http",
|
|
578
|
+
"format": "yaml",
|
|
579
|
+
"behavior": "ipcidr",
|
|
580
|
+
"url": f"{self.rule_base_url}/telegramcidr.txt",
|
|
581
|
+
"path": "./ruleset/telegramcidr.yaml",
|
|
582
|
+
"interval": 86400,
|
|
583
|
+
},
|
|
584
|
+
"gfw": {
|
|
585
|
+
"type": "http",
|
|
586
|
+
"format": "yaml",
|
|
587
|
+
"behavior": "domain",
|
|
588
|
+
"url": f"{self.rule_base_url}/gfw.txt",
|
|
589
|
+
"path": "./ruleset/gfw.yaml",
|
|
590
|
+
"interval": 86400,
|
|
591
|
+
},
|
|
592
|
+
# "reject": {
|
|
593
|
+
# "type": "http",
|
|
594
|
+
# "format": "yaml",
|
|
595
|
+
# "behavior": "domain",
|
|
596
|
+
# "url": f"{self.rule_base_url}/reject.txt",
|
|
597
|
+
# "path": "./ruleset/reject.yaml",
|
|
598
|
+
# "interval": 86400,
|
|
599
|
+
# },
|
|
600
|
+
},
|
|
601
|
+
)
|
|
602
|
+
|
|
603
|
+
template["rules"].extend(
|
|
604
|
+
[
|
|
605
|
+
"RULE-SET,applications,DIRECT",
|
|
606
|
+
"RULE-SET,private,DIRECT",
|
|
607
|
+
# "RULE-SET,reject,REJECT",
|
|
608
|
+
"RULE-SET,tld-not-cn,全局选择",
|
|
609
|
+
"RULE-SET,gfw,全局选择",
|
|
610
|
+
"RULE-SET,telegramcidr,全局选择",
|
|
611
|
+
"MATCH,DIRECT",
|
|
612
|
+
]
|
|
613
|
+
)
|
|
614
|
+
|
|
615
|
+
return template, userinfo
|
|
616
|
+
|
|
445
617
|
def query2sub(self, urls: str, agents: str, names: str):
|
|
446
618
|
url_list = urls.split(",") if urls and urls.strip() else []
|
|
447
619
|
agents_list = agents.split(",") if agents else []
|
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
mixed-port: 7897
|
|
2
|
-
allow-lan: false
|
|
3
|
-
mode: rule
|
|
4
|
-
log-level: warning
|
|
5
|
-
external-controller: "127.0.0.1:9097"
|
|
6
|
-
client-fingerprint: chrome
|
|
7
|
-
unified-delay: true
|
|
8
|
-
ipv6: false
|
|
9
|
-
profile:
|
|
10
|
-
store-selected: true
|
|
11
|
-
tun:
|
|
12
|
-
mtu: 1500
|
|
13
|
-
dns:
|
|
14
|
-
enable: true
|
|
15
|
-
listen: ":53"
|
|
16
|
-
enhanced-mode: "fake-ip"
|
|
17
|
-
fake-ip-range: "198.18.0.1/16"
|
|
18
|
-
fake-ip-filter-mode: "blacklist"
|
|
19
|
-
prefer-h3: false
|
|
20
|
-
respect-rules: false
|
|
21
|
-
use-hosts: false
|
|
22
|
-
use-system-hosts: false
|
|
23
|
-
ipv6: true
|
|
24
|
-
fake-ip-filter:
|
|
25
|
-
- "*.lan"
|
|
26
|
-
- "*.local"
|
|
27
|
-
- "*.arpa"
|
|
28
|
-
- "time.*.com"
|
|
29
|
-
- "ntp.*.com"
|
|
30
|
-
- "time.*.com"
|
|
31
|
-
- "+.market.xiaomi.com"
|
|
32
|
-
- "localhost.ptlogin2.qq.com"
|
|
33
|
-
- "*.msftncsi.com"
|
|
34
|
-
- "www.msftconnecttest.com"
|
|
35
|
-
default-nameserver:
|
|
36
|
-
- "system"
|
|
37
|
-
- "223.6.6.6"
|
|
38
|
-
- "8.8.8.8"
|
|
39
|
-
- "2400:3200::1"
|
|
40
|
-
- "2001:4860:4860::8888"
|
|
41
|
-
nameserver:
|
|
42
|
-
- "8.8.8.8"
|
|
43
|
-
- "https://doh.pub/dns-query"
|
|
44
|
-
- "https://dns.alidns.com/dns-query"
|
|
45
|
-
direct-nameserver-follow-policy: false
|
|
46
|
-
fallback-filter:
|
|
47
|
-
geoip: true
|
|
48
|
-
geoip-code: "CN"
|
|
49
|
-
ipcidr:
|
|
50
|
-
- "240.0.0.0/4"
|
|
51
|
-
- "0.0.0.0/32"
|
|
52
|
-
domain:
|
|
53
|
-
- "+.google.com"
|
|
54
|
-
- "+.facebook.com"
|
|
55
|
-
- "+.youtube.com"
|
|
56
|
-
fallback: []
|
|
57
|
-
proxy-server-nameserver:
|
|
58
|
-
- "https://doh.pub/dns-query"
|
|
59
|
-
- "https://dns.alidns.com/dns-query"
|
|
60
|
-
- "tls://223.5.5.5"
|
|
61
|
-
direct-nameserver: []
|
|
62
|
-
external-controller-cors:
|
|
63
|
-
allow-private-network: true
|
|
64
|
-
allow-origins:
|
|
65
|
-
- "*"
|
|
66
|
-
proxies: []
|
|
67
|
-
proxy-providers: {}
|
|
68
|
-
proxy-groups: []
|
|
69
|
-
rule-providers: {}
|
|
70
|
-
rules: []
|
|
1
|
+
mixed-port: 7897
|
|
2
|
+
allow-lan: false
|
|
3
|
+
mode: rule
|
|
4
|
+
log-level: warning
|
|
5
|
+
external-controller: "127.0.0.1:9097"
|
|
6
|
+
client-fingerprint: chrome
|
|
7
|
+
unified-delay: true
|
|
8
|
+
ipv6: false
|
|
9
|
+
profile:
|
|
10
|
+
store-selected: true
|
|
11
|
+
tun:
|
|
12
|
+
mtu: 1500
|
|
13
|
+
dns:
|
|
14
|
+
enable: true
|
|
15
|
+
listen: ":53"
|
|
16
|
+
enhanced-mode: "fake-ip"
|
|
17
|
+
fake-ip-range: "198.18.0.1/16"
|
|
18
|
+
fake-ip-filter-mode: "blacklist"
|
|
19
|
+
prefer-h3: false
|
|
20
|
+
respect-rules: false
|
|
21
|
+
use-hosts: false
|
|
22
|
+
use-system-hosts: false
|
|
23
|
+
ipv6: true
|
|
24
|
+
fake-ip-filter:
|
|
25
|
+
- "*.lan"
|
|
26
|
+
- "*.local"
|
|
27
|
+
- "*.arpa"
|
|
28
|
+
- "time.*.com"
|
|
29
|
+
- "ntp.*.com"
|
|
30
|
+
- "time.*.com"
|
|
31
|
+
- "+.market.xiaomi.com"
|
|
32
|
+
- "localhost.ptlogin2.qq.com"
|
|
33
|
+
- "*.msftncsi.com"
|
|
34
|
+
- "www.msftconnecttest.com"
|
|
35
|
+
default-nameserver:
|
|
36
|
+
- "system"
|
|
37
|
+
- "223.6.6.6"
|
|
38
|
+
- "8.8.8.8"
|
|
39
|
+
- "2400:3200::1"
|
|
40
|
+
- "2001:4860:4860::8888"
|
|
41
|
+
nameserver:
|
|
42
|
+
- "8.8.8.8"
|
|
43
|
+
- "https://doh.pub/dns-query"
|
|
44
|
+
- "https://dns.alidns.com/dns-query"
|
|
45
|
+
direct-nameserver-follow-policy: false
|
|
46
|
+
fallback-filter:
|
|
47
|
+
geoip: true
|
|
48
|
+
geoip-code: "CN"
|
|
49
|
+
ipcidr:
|
|
50
|
+
- "240.0.0.0/4"
|
|
51
|
+
- "0.0.0.0/32"
|
|
52
|
+
domain:
|
|
53
|
+
- "+.google.com"
|
|
54
|
+
- "+.facebook.com"
|
|
55
|
+
- "+.youtube.com"
|
|
56
|
+
fallback: []
|
|
57
|
+
proxy-server-nameserver:
|
|
58
|
+
- "https://doh.pub/dns-query"
|
|
59
|
+
- "https://dns.alidns.com/dns-query"
|
|
60
|
+
- "tls://223.5.5.5"
|
|
61
|
+
direct-nameserver: []
|
|
62
|
+
external-controller-cors:
|
|
63
|
+
allow-private-network: true
|
|
64
|
+
allow-origins:
|
|
65
|
+
- "*"
|
|
66
|
+
proxies: []
|
|
67
|
+
proxy-providers: {}
|
|
68
|
+
proxy-groups: []
|
|
69
|
+
rule-providers: {}
|
|
70
|
+
rules: []
|
pymecli-0.4.4/api/v1/clash.py
DELETED
|
@@ -1,62 +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
|
-
"/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
|
-
)
|
|
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
|
|
File without changes
|