pymecli 0.5.1__tar.gz → 0.5.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.
Files changed (45) hide show
  1. {pymecli-0.5.1 → pymecli-0.5.3}/PKG-INFO +1 -1
  2. {pymecli-0.5.1 → pymecli-0.5.3}/cli/dst.py +9 -9
  3. {pymecli-0.5.1 → pymecli-0.5.3}/cli/util.py +4 -8
  4. pymecli-0.5.3/core/clash.py +368 -0
  5. {pymecli-0.5.1 → pymecli-0.5.3}/core/config.py +1 -1
  6. pymecli-0.5.3/data/template.yaml +180 -0
  7. {pymecli-0.5.1 → pymecli-0.5.3}/pyproject.toml +1 -1
  8. pymecli-0.5.1/core/clash.py +0 -664
  9. pymecli-0.5.1/data/template.yaml +0 -70
  10. {pymecli-0.5.1 → pymecli-0.5.3}/.gitignore +0 -0
  11. {pymecli-0.5.1 → pymecli-0.5.3}/README.md +0 -0
  12. {pymecli-0.5.1 → pymecli-0.5.3}/api/__init__.py +0 -0
  13. {pymecli-0.5.1 → pymecli-0.5.3}/api/v1/__init__.py +0 -0
  14. {pymecli-0.5.1 → pymecli-0.5.3}/api/v1/clash.py +0 -0
  15. {pymecli-0.5.1 → pymecli-0.5.3}/api/v1/redis.py +0 -0
  16. {pymecli-0.5.1 → pymecli-0.5.3}/cli/__init__.py +0 -0
  17. {pymecli-0.5.1 → pymecli-0.5.3}/cli/bitget.py +0 -0
  18. {pymecli-0.5.1 → pymecli-0.5.3}/cli/example.py +0 -0
  19. {pymecli-0.5.1 → pymecli-0.5.3}/cli/fast.py +0 -0
  20. {pymecli-0.5.1 → pymecli-0.5.3}/cli/gate.py +0 -0
  21. {pymecli-0.5.1 → pymecli-0.5.3}/cli/redis_csv.py +0 -0
  22. {pymecli-0.5.1 → pymecli-0.5.3}/core/__init__.py +0 -0
  23. {pymecli-0.5.1 → pymecli-0.5.3}/core/redis_client.py +0 -0
  24. {pymecli-0.5.1 → pymecli-0.5.3}/crypto/__init__.py +0 -0
  25. {pymecli-0.5.1 → pymecli-0.5.3}/crypto/bitget.py +0 -0
  26. {pymecli-0.5.1 → pymecli-0.5.3}/crypto/gate.py +0 -0
  27. {pymecli-0.5.1 → pymecli-0.5.3}/data/__init__.py +0 -0
  28. {pymecli-0.5.1 → pymecli-0.5.3}/data/dou_dict.py +0 -0
  29. {pymecli-0.5.1 → pymecli-0.5.3}/data/dou_list.py +0 -0
  30. {pymecli-0.5.1 → pymecli-0.5.3}/data/main.py +0 -0
  31. {pymecli-0.5.1 → pymecli-0.5.3}/models/__init__.py +0 -0
  32. {pymecli-0.5.1 → pymecli-0.5.3}/models/douzero_model.py +0 -0
  33. {pymecli-0.5.1 → pymecli-0.5.3}/models/ocr_model.py +0 -0
  34. {pymecli-0.5.1 → pymecli-0.5.3}/models/response.py +0 -0
  35. {pymecli-0.5.1 → pymecli-0.5.3}/utils/__init__.py +0 -0
  36. {pymecli-0.5.1 → pymecli-0.5.3}/utils/elapsed.py +0 -0
  37. {pymecli-0.5.1 → pymecli-0.5.3}/utils/helper.py +0 -0
  38. {pymecli-0.5.1 → pymecli-0.5.3}/utils/logger.py +0 -0
  39. {pymecli-0.5.1 → pymecli-0.5.3}/utils/mysql.py +0 -0
  40. {pymecli-0.5.1 → pymecli-0.5.3}/utils/path.py +0 -0
  41. {pymecli-0.5.1 → pymecli-0.5.3}/utils/pd.py +0 -0
  42. {pymecli-0.5.1 → pymecli-0.5.3}/utils/pyredis.py +0 -0
  43. {pymecli-0.5.1 → pymecli-0.5.3}/utils/sleep.py +0 -0
  44. {pymecli-0.5.1 → pymecli-0.5.3}/utils/text.py +0 -0
  45. {pymecli-0.5.1 → pymecli-0.5.3}/utils/toml.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymecli
3
- Version: 0.5.1
3
+ Version: 0.5.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
@@ -149,13 +149,13 @@ def convert_update(
149
149
  continue
150
150
  mod_data = versions.get(wid)
151
151
  if mod_data is None:
152
- typer.secho(f"⚠️ {mod_key}: 未获取到版本信息", fg=typer.colors.YELLOW)
152
+ typer.secho(f"✗ {mod_key}: 未获取到版本信息", fg=typer.colors.YELLOW)
153
153
  continue
154
154
  new_version = mod_data.get("version")
155
155
  title = mod_data.get("title", "")
156
156
  if new_version is None:
157
157
  typer.secho(
158
- f"⚠️ {mod_key} ({title}): 未获取到版本信息", fg=typer.colors.YELLOW
158
+ f"✗ {mod_key} ({title}): 未获取到版本信息", fg=typer.colors.YELLOW
159
159
  )
160
160
  continue
161
161
  old_version = mod_info.get("version")
@@ -163,7 +163,7 @@ def convert_update(
163
163
  mod_info["version"] = new_version
164
164
  updated_count += 1
165
165
  typer.secho(
166
- f"✅ {mod_key} ({title}): {old_version} -> {new_version}",
166
+ f"✓ {mod_key} ({title}): {old_version} -> {new_version}",
167
167
  fg=typer.colors.GREEN,
168
168
  )
169
169
  else:
@@ -185,9 +185,9 @@ def convert_update(
185
185
  raise typer.Exit(code=1)
186
186
 
187
187
  if updated_count > 0:
188
- typer.secho(f"\n🎉 成功更新 {updated_count} 个 mod 版本", fg=typer.colors.GREEN)
188
+ typer.secho(f"🎉 成功更新 {updated_count} 个 mod 版本", fg=typer.colors.GREEN)
189
189
  else:
190
- typer.secho("\n✅ 所有 mod 已是最新版本", fg=typer.colors.YELLOW)
190
+ typer.secho("✓ 所有MOD已是最新版本", fg=typer.colors.YELLOW)
191
191
 
192
192
 
193
193
  @app.command()
@@ -255,12 +255,12 @@ def mod_setup(
255
255
  title = mod_data.get("title", "")
256
256
 
257
257
  typer.secho(
258
- f"✅ {item} ({title}): {new_version}",
258
+ f"{item} ({title}): {new_version}",
259
259
  fg=typer.colors.WHITE,
260
260
  )
261
261
 
262
262
  typer.secho(
263
- f"\n📋 client_mods({len(client_ids)}):",
263
+ f"📢 client_mods({len(client_ids)}):",
264
264
  fg=typer.colors.GREEN,
265
265
  )
266
266
 
@@ -277,14 +277,14 @@ def mod_setup(
277
277
  title = mod_data.get("title", "")
278
278
 
279
279
  typer.secho(
280
- f"✅ {item} ({title}): {new_version}",
280
+ f"{item} ({title}): {new_version}",
281
281
  fg=typer.colors.WHITE,
282
282
  )
283
283
 
284
284
  for p in output:
285
285
  with open(p, "w", encoding="utf-8") as f:
286
286
  f.write("\n".join(setup_list))
287
- typer.secho(f"\n💾 <setup_list>已保存到: {p}", fg=typer.colors.CYAN)
287
+ typer.secho(f"💾 <setup_list>已保存到: {p}", fg=typer.colors.CYAN)
288
288
 
289
289
 
290
290
  if __name__ == "__main__":
@@ -68,12 +68,8 @@ def emoji():
68
68
  emoji_list = [
69
69
  "『",
70
70
  "』",
71
- "✔",
72
- "✘",
73
- "❗",
74
- "⭕",
75
- "❓",
76
- "❌",
71
+ "✓",
72
+ "✗",
77
73
  "⤴︎",
78
74
  "⤵︎",
79
75
  "⇡",
@@ -147,7 +143,7 @@ def say():
147
143
  @app.command()
148
144
  def ipv6():
149
145
  """
150
- 获取本地 IPV6 稳定地址
146
+ 获取本地 IPv6 稳定地址
151
147
  """
152
148
  ips = []
153
149
  adapters = ifaddr.get_adapters(include_unconfigured=False)
@@ -178,7 +174,7 @@ def ipv6():
178
174
  print("未找到稳定 IPV6 地址")
179
175
  return ips
180
176
 
181
- print(f"IPV6 稳定地址: {ips}")
177
+ print(f"IPv6 稳定地址: {ips}")
182
178
 
183
179
  r = get_redis_client_sync()
184
180
  r.set("local.IPv6", ips[0])
@@ -0,0 +1,368 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ import requests
5
+ import yaml
6
+ from fastapi import Depends
7
+
8
+ module_dir = Path(__file__).resolve().parent.parent
9
+
10
+ TEMPLATE_URL = "https://raw.githubusercontent.com/meme2046/data/main/clash/template.yaml"
11
+
12
+ # 白名单模式最终规则
13
+ WHITELIST_RULES = [
14
+ "RULE-SET,applications,DIRECT",
15
+ "RULE-SET,private,DIRECT",
16
+ "RULE-SET,icloud,DIRECT",
17
+ "RULE-SET,apple,DIRECT",
18
+ "RULE-SET,google,全局选择",
19
+ "RULE-SET,proxy,全局选择",
20
+ "RULE-SET,direct,DIRECT",
21
+ "RULE-SET,lancidr,DIRECT",
22
+ "RULE-SET,cncidr,DIRECT",
23
+ "RULE-SET,telegramcidr,全局选择",
24
+ "GEOIP,LAN,DIRECT",
25
+ "GEOIP,CN,DIRECT",
26
+ "MATCH,全局选择",
27
+ ]
28
+
29
+ # 黑名单模式最终规则
30
+ BLACKLIST_RULES = [
31
+ "RULE-SET,applications,DIRECT",
32
+ "RULE-SET,private,DIRECT",
33
+ "RULE-SET,tld-not-cn,全局选择",
34
+ "RULE-SET,gfw,全局选择",
35
+ "RULE-SET,telegramcidr,全局选择",
36
+ "MATCH,DIRECT",
37
+ ]
38
+
39
+
40
+ class ClashConfig:
41
+ def __init__(self, rule_base_url: str, my_rule_base_url: str, request_proxy: str):
42
+ self.rule_base_url = rule_base_url.rstrip("/")
43
+ self.my_rule_base_url = my_rule_base_url.rstrip("/")
44
+ self.request_proxy = request_proxy
45
+
46
+
47
+ class ClashYamlGenerator:
48
+ def __init__(self, config: ClashConfig):
49
+ self.rule_base_url = config.rule_base_url
50
+ self.my_rule_base_url = config.my_rule_base_url
51
+ self.request_proxy = config.request_proxy
52
+
53
+ # ---------- 通用 helpers ----------
54
+
55
+ def _get_proxies(self):
56
+ if not self.request_proxy:
57
+ return None
58
+ return {"http": self.request_proxy, "https": self.request_proxy}
59
+
60
+ def _load_template(self, proxies=None):
61
+ """从远程获取 template.yaml,失败时回退到本地文件"""
62
+ try:
63
+ response = requests.get(TEMPLATE_URL, proxies=proxies)
64
+ response.raise_for_status()
65
+ template = yaml.safe_load(response.text)
66
+ if template:
67
+ return template
68
+ except Exception:
69
+ pass
70
+ with open(str(module_dir / "data/template.yaml"), "r", encoding="utf-8") as f:
71
+ return yaml.safe_load(f)
72
+
73
+ def _fetch_subscriptions(self, sub_list, proxies):
74
+ """抓取并校验所有订阅,返回 [(item, ps), ...] 和 userinfo"""
75
+ userinfo = ""
76
+ results = []
77
+ for item in sub_list:
78
+ headers = {"User-Agent": item["user_agent"]} if item["user_agent"] else {}
79
+
80
+ if not item["url"]:
81
+ raise ValueError("Invalid subscription URL.")
82
+ response = requests.get(item["url"], headers=headers, proxies=proxies)
83
+ response.raise_for_status()
84
+ if not userinfo:
85
+ userinfo = response.headers["Subscription-Userinfo"]
86
+ remote_config = yaml.safe_load(response.text)
87
+
88
+ # 检查 remote_config 是否为 None
89
+ if remote_config is None:
90
+ raise ValueError("Invalid subscription content: empty or invalid YAML.")
91
+
92
+ ps = remote_config.get("proxies", [])
93
+ if not ps:
94
+ raise ValueError("No proxies found in subscription.")
95
+
96
+ results.append((item, ps))
97
+ return results, userinfo
98
+
99
+ def _add_inline_rule_providers(self, template, proxies):
100
+ """从 my_rule_base_url 拉取 inline 规则集并写入 template"""
101
+ rule_list = [
102
+ [f"{self.my_rule_base_url}/direct.yaml", "DIRECT"],
103
+ [f"{self.my_rule_base_url}/proxy.yaml", "全局选择"],
104
+ [f"{self.my_rule_base_url}/round.yaml", "轮询"],
105
+ [f"{self.my_rule_base_url}/reject.yaml", "REJECT"],
106
+ ]
107
+ for url, target in rule_list:
108
+ response = requests.get(url, proxies=proxies)
109
+ response.raise_for_status()
110
+ remote = yaml.safe_load(response.text)
111
+ name = os.path.basename(url)
112
+ template["rule-providers"][name] = {
113
+ "type": "inline",
114
+ "behavior": "classical",
115
+ "payload": remote["payload"],
116
+ }
117
+ template["rules"].append(f"RULE-SET,{name},{target}")
118
+
119
+ def _http_rule_provider(self, name, behavior):
120
+ """生成单个 http 类型 rule-provider"""
121
+ return {
122
+ "type": "http",
123
+ "format": "yaml",
124
+ "behavior": behavior,
125
+ "url": f"{self.rule_base_url}/{name}.txt",
126
+ "path": f"./ruleset/{name}.yaml",
127
+ "interval": 86400,
128
+ }
129
+
130
+ def _whitelist_http_rule_providers(self):
131
+ return {
132
+ "applications": self._http_rule_provider("applications", "classical"),
133
+ "private": self._http_rule_provider("private", "domain"),
134
+ "icloud": self._http_rule_provider("icloud", "domain"),
135
+ "apple": self._http_rule_provider("apple", "domain"),
136
+ "google": self._http_rule_provider("google", "domain"),
137
+ "proxy": self._http_rule_provider("proxy", "domain"),
138
+ "direct": self._http_rule_provider("direct", "domain"),
139
+ "lancidr": self._http_rule_provider("lancidr", "ipcidr"),
140
+ "cncidr": self._http_rule_provider("cncidr", "ipcidr"),
141
+ "telegramcidr": self._http_rule_provider("telegramcidr", "ipcidr"),
142
+ }
143
+
144
+ def _blacklist_http_rule_providers(self):
145
+ return {
146
+ "applications": self._http_rule_provider("applications", "classical"),
147
+ "private": self._http_rule_provider("private", "domain"),
148
+ "tld-not-cn": self._http_rule_provider("tld-not-cn", "domain"),
149
+ "telegramcidr": self._http_rule_provider("telegramcidr", "ipcidr"),
150
+ "gfw": self._http_rule_provider("gfw", "domain"),
151
+ }
152
+
153
+ def _provider_proxy_groups(self, sub_list):
154
+ """provider 风格的 proxy-groups(genPW / genPB)"""
155
+ use_list = [f"provider.{item['name']}" for item in sub_list]
156
+ return [
157
+ {
158
+ "name": "全局选择",
159
+ "type": "select",
160
+ "proxies": ["自动选择", "手动选择", "轮询"]
161
+ + [item["name"] for item in sub_list],
162
+ },
163
+ {
164
+ "name": "自动选择",
165
+ "type": "url-test",
166
+ "url": "https://www.gstatic.com/generate_204",
167
+ "interval": 300,
168
+ "tolerance": 11,
169
+ "lazy": True,
170
+ "use": use_list,
171
+ },
172
+ {
173
+ "name": "手动选择",
174
+ "type": "select",
175
+ "use": use_list,
176
+ },
177
+ {
178
+ "name": "轮询",
179
+ "type": "load-balance",
180
+ "url": "https://api.bitget.com/api/v2/public/time",
181
+ "interval": 300,
182
+ "lazy": True,
183
+ "strategy": "round-robin",
184
+ "use": use_list,
185
+ },
186
+ ]
187
+
188
+ def _inline_proxy_groups(self, sub_list):
189
+ """include-all 风格的 proxy-groups(genB)"""
190
+ return [
191
+ {
192
+ "name": "全局选择",
193
+ "type": "select",
194
+ "proxies": ["自动选择", "手动选择", "轮询"]
195
+ + [item["name"] for item in sub_list],
196
+ },
197
+ {"name": "自动选择", "type": "url-test", "include-all": True},
198
+ {"name": "手动选择", "type": "select", "include-all": True},
199
+ {
200
+ "name": "轮询",
201
+ "type": "load-balance",
202
+ "url": "https://api.bitget.com/api/v2/public/time",
203
+ "strategy": "round-robin",
204
+ "include-all": True,
205
+ },
206
+ ]
207
+
208
+ def _add_provider_sub(self, template, item, ps):
209
+ """单个订阅写入 proxy-providers + url-test group(genPW / genPB)"""
210
+ template["proxy-providers"][f"provider.{item['name']}"] = {
211
+ "type": "inline",
212
+ "payload": ps,
213
+ }
214
+ template["proxy-groups"].append(
215
+ {
216
+ "name": item["name"],
217
+ "type": "url-test",
218
+ "url": "https://www.gstatic.com/generate_204",
219
+ "interval": 300,
220
+ "tolerance": 11,
221
+ "lazy": True,
222
+ "use": [f"provider.{item['name']}"],
223
+ }
224
+ )
225
+
226
+ def _add_inline_sub(self, template, item, ps):
227
+ """单个订阅直接写入 proxies + url-test group(genB)"""
228
+ template["proxies"].extend(ps)
229
+ template["proxy-groups"].append(
230
+ {
231
+ "name": item["name"],
232
+ "type": "url-test",
233
+ "proxies": [p["name"] for p in ps],
234
+ }
235
+ )
236
+
237
+ def _add_base_rules(self, template, with_dst_port=False):
238
+ """IP-CIDR / DOMAIN 基础规则(genPB / genB),genB 含饥荒端口"""
239
+ template["rules"].extend(
240
+ [
241
+ "IP-CIDR,192.168.0.0/16,DIRECT,no-resolve",
242
+ "IP-CIDR,10.0.0.0/8,DIRECT,no-resolve",
243
+ "IP-CIDR,172.16.0.0/12,DIRECT,no-resolve",
244
+ "IP-CIDR,127.0.0.0/8,DIRECT,no-resolve",
245
+ ]
246
+ )
247
+ if with_dst_port:
248
+ template["rules"].extend(
249
+ [
250
+ "DST-PORT,10999,DIRECT",
251
+ "DST-PORT,10998,DIRECT",
252
+ "DST-PORT,27016,DIRECT",
253
+ "DST-PORT,27017,DIRECT",
254
+ "DST-PORT,8766,DIRECT",
255
+ "DST-PORT,8767,DIRECT",
256
+ ]
257
+ )
258
+ template["rules"].extend(
259
+ [
260
+ "DOMAIN,clash.razord.top,DIRECT",
261
+ "DOMAIN,yacd.haishan.me,DIRECT",
262
+ # "DOMAIN,accounts.klei.com,全局选择",
263
+ ]
264
+ )
265
+
266
+ # ---------- 三种生成模式 ----------
267
+
268
+ # 白名单模式 Rules 配置方式
269
+ def genPW(self, sub_list: list[dict]):
270
+ proxies = self._get_proxies()
271
+ template = self._load_template(proxies)
272
+
273
+ template["proxy-groups"].extend(self._provider_proxy_groups(sub_list))
274
+
275
+ subs, userinfo = self._fetch_subscriptions(sub_list, proxies)
276
+ for item, ps in subs:
277
+ self._add_provider_sub(template, item, ps)
278
+
279
+ self._add_inline_rule_providers(template, proxies)
280
+ template["rule-providers"].update(self._whitelist_http_rule_providers())
281
+ template["rules"].extend(WHITELIST_RULES)
282
+
283
+ return template, userinfo
284
+
285
+ # 黑名单模式 Rules 配置方式
286
+ def genPB(self, sub_list: list[dict]):
287
+ proxies = self._get_proxies()
288
+ template = self._load_template(proxies)
289
+
290
+ template["proxy-groups"].extend(self._provider_proxy_groups(sub_list))
291
+
292
+ subs, userinfo = self._fetch_subscriptions(sub_list, proxies)
293
+ for item, ps in subs:
294
+ self._add_provider_sub(template, item, ps)
295
+
296
+ self._add_base_rules(template, with_dst_port=False)
297
+ self._add_inline_rule_providers(template, proxies)
298
+ template["rule-providers"].update(self._blacklist_http_rule_providers())
299
+ template["rules"].extend(BLACKLIST_RULES)
300
+
301
+ return template, userinfo
302
+
303
+ def genB(self, sub_list: list[dict]):
304
+ proxies = self._get_proxies()
305
+ template = self._load_template(proxies)
306
+
307
+ template["proxy-groups"].extend(self._inline_proxy_groups(sub_list))
308
+
309
+ template["proxies"] = []
310
+ subs, userinfo = self._fetch_subscriptions(sub_list, proxies)
311
+ for item, ps in subs:
312
+ self._add_inline_sub(template, item, ps)
313
+
314
+ self._add_base_rules(template, with_dst_port=True)
315
+ self._add_inline_rule_providers(template, proxies)
316
+ template["rule-providers"].update(self._blacklist_http_rule_providers())
317
+ template["rules"].extend(BLACKLIST_RULES)
318
+
319
+ return template, userinfo
320
+
321
+ def query2sub(self, urls: str, agents: str, names: str):
322
+ url_list = urls.split(",") if urls and urls.strip() else []
323
+ agents_list = agents.split(",") if agents else []
324
+ name_list = names.split(",") if names else []
325
+
326
+ max_length = max(len(url_list), len(agents_list), len(name_list))
327
+
328
+ while len(url_list) < max_length:
329
+ url_list.append("")
330
+ while len(agents_list) < max_length:
331
+ agents_list.append("")
332
+ while len(name_list) < max_length:
333
+ name_list.append("")
334
+
335
+ sub_list = []
336
+
337
+ for i in range(max_length):
338
+ if not url_list[i]:
339
+ raise ValueError(f"Invalid subscription URL. #{i + 1}")
340
+
341
+ sub_list.append(
342
+ {
343
+ "url": url_list[i],
344
+ "user_agent": agents_list[i] if agents_list[i] else "",
345
+ "name": name_list[i] if name_list[i] else f"订阅{i}",
346
+ }
347
+ )
348
+
349
+ return sub_list
350
+
351
+
352
+ generator_instance = None
353
+
354
+
355
+ def init_generator(config: ClashConfig):
356
+ global generator_instance
357
+ generator_instance = ClashYamlGenerator(config)
358
+
359
+
360
+ def get_generator():
361
+ global generator_instance
362
+ if generator_instance is None:
363
+ raise RuntimeError("ClashYamlGenerator not initialized")
364
+ return generator_instance
365
+
366
+
367
+ def get_generator_dependency():
368
+ return Depends(get_generator)
@@ -19,7 +19,7 @@ class Settings(BaseSettings):
19
19
  REDIS_PASSWORD: str = ""
20
20
 
21
21
  PROJECT_DESCRIPTION: str = (
22
- f"{metadata['Summary']}, FastAPI提供: clash订阅转换、finance.baidu api"
22
+ f"{metadata['Summary']}, FastAPI提供: clash订阅转换、redis API"
23
23
  )
24
24
  PROJECT_VERSION: str = metadata["Version"]
25
25
 
@@ -0,0 +1,180 @@
1
+ external-controller: ""
2
+ ipv6: true
3
+ mode: rule
4
+ mixed-port: 7897
5
+ socks-port: 0
6
+ port: 0
7
+ redir-port: 0
8
+ tproxy-port: 0
9
+ allow-lan: true
10
+ unified-delay: true
11
+ tcp-concurrent: false
12
+ log-level: warning
13
+ find-process-mode: strict
14
+ bind-address: "*"
15
+ lan-allowed-ips:
16
+ - 0.0.0.0/0
17
+ - ::/0
18
+ lan-disallowed-ips: []
19
+ authentication: []
20
+ skip-auth-prefixes:
21
+ - 127.0.0.1/32
22
+ - ::1/128
23
+ tun:
24
+ enable: false
25
+ stack: mixed
26
+ auto-route: true
27
+ auto-redirect: false
28
+ auto-detect-interface: true
29
+ dns-hijack:
30
+ - any:53
31
+ route-exclude-address: []
32
+ mtu: 1500
33
+ device: Mihomo
34
+ dns:
35
+ enable: true
36
+ ipv6: true
37
+ enhanced-mode: fake-ip
38
+ fake-ip-range: 198.18.0.1/16
39
+ fake-ip-filter:
40
+ - "*"
41
+ - +.lan
42
+ - +.local
43
+ - time.*.com
44
+ - ntp.*.com
45
+ - +.market.xiaomi.com
46
+ - api.memeniu.xyz
47
+ - meme.us.kg
48
+ - +.steamserver.net
49
+ - +.recaptcha.net
50
+ use-hosts: false
51
+ use-system-hosts: false
52
+ respect-rules: true
53
+ default-nameserver:
54
+ - https://223.5.5.5/dns-query
55
+ - https://223.6.6.6/dns-query
56
+ - https://8.8.8.8/dns-query
57
+ - https://1.1.1.1/dns-query
58
+ - 223.5.5.5
59
+ nameserver:
60
+ - https://dns.alidns.com/dns-query
61
+ - https://doh.pub/dns-query
62
+ proxy-server-nameserver:
63
+ - https://cloudflare-dns.com/dns-query
64
+ - https://dns.google/dns-query
65
+ - https://dns.alidns.com/dns-query
66
+ - https://doh.pub/dns-query
67
+ direct-nameserver:
68
+ - https://dns.alidns.com/dns-query
69
+ - https://doh.pub/dns-query
70
+ fallback:
71
+ - https://cloudflare-dns.com/dns-query
72
+ - https://dns.google/dns-query
73
+ fallback-filter:
74
+ geoip: true
75
+ geoip-code: CN
76
+ ipcidr:
77
+ - 240.0.0.0/4
78
+ - 0.0.0.0/32
79
+ - 127.0.0.0/8
80
+ - 10.0.0.0/8
81
+ - 192.168.0.0/16
82
+ domain:
83
+ - +.google.com
84
+ - +.facebook.com
85
+ - +.youtube.com
86
+ direct-nameserver-follow-policy: true
87
+ prefer-h3: false
88
+ nameserver-policy:
89
+ geosite:cn:
90
+ - https://dns.alidns.com/dns-query
91
+ - https://doh.pub/dns-query
92
+ geosite:geolocation-!cn:
93
+ - https://cloudflare-dns.com/dns-query
94
+ - https://dns.google/dns-query
95
+ +.jsdelivr.net:
96
+ - https://cloudflare-dns.com/dns-query
97
+ - https://dns.google/dns-query
98
+ +.github.com:
99
+ - https://cloudflare-dns.com/dns-query
100
+ - https://dns.google/dns-query
101
+ +.githubusercontent.com:
102
+ - https://cloudflare-dns.com/dns-query
103
+ - https://dns.google/dns-query
104
+ +.githubassets.com:
105
+ - https://cloudflare-dns.com/dns-query
106
+ - https://dns.google/dns-query
107
+ +.fastly.net:
108
+ - https://cloudflare-dns.com/dns-query
109
+ - https://dns.google/dns-query
110
+ api.memeniu.xyz:
111
+ - https://[2402:4e00::]/dns-query
112
+ - https://[2400:3200::1]/dns-query
113
+ - https://dns.alidns.com/dns-query
114
+ - https://doh.pub/dns-query
115
+ meme.us.kg:
116
+ - https://[2402:4e00::]/dns-query
117
+ - https://[2400:3200::1]/dns-query
118
+ - https://dns.alidns.com/dns-query
119
+ - https://doh.pub/dns-query
120
+ +.steamserver.net:
121
+ - https://[2402:4e00::]/dns-query
122
+ - https://[2400:3200::1]/dns-query
123
+ - https://dns.alidns.com/dns-query
124
+ - https://doh.pub/dns-query
125
+ +.recaptcha.net:
126
+ - https://[2402:4e00::]/dns-query
127
+ - https://[2400:3200::1]/dns-query
128
+ - https://dns.alidns.com/dns-query
129
+ - https://doh.pub/dns-query
130
+ sniffer:
131
+ enable: true
132
+ parse-pure-ip: true
133
+ force-dns-mapping: true
134
+ override-destination: true
135
+ sniff:
136
+ HTTP:
137
+ ports:
138
+ - "80"
139
+ - 8080-8880
140
+ override-destination: true
141
+ TLS:
142
+ ports:
143
+ - "443"
144
+ - "8443"
145
+ QUIC:
146
+ ports:
147
+ - "443"
148
+ - "8443"
149
+ - "4433"
150
+ skip-domain:
151
+ - +.push.apple.com
152
+ skip-dst-address:
153
+ - 91.105.192.0/23
154
+ - 91.108.4.0/22
155
+ - 91.108.8.0/21
156
+ - 91.108.16.0/21
157
+ - 91.108.56.0/22
158
+ - 95.161.64.0/20
159
+ - 149.154.160.0/20
160
+ - 185.76.151.0/24
161
+ - 2001:67c:4e8::/48
162
+ - 2001:b28:f23c::/47
163
+ - 2001:b28:f23f::/48
164
+ - 2a0a:f280:203::/48
165
+ profile:
166
+ store-selected: true
167
+ store-fake-ip: true
168
+ geo-auto-update: false
169
+ geo-update-interval: 24
170
+ geodata-mode: true
171
+ geox-url:
172
+ geoip: https://fastly.jsdelivr.net/gh/Loyalsoldier/geoip@release/geoip.dat
173
+ mmdb: https://fastly.jsdelivr.net/gh/Loyalsoldier/geoip@release/Country.mmdb
174
+ asn: https://fastly.jsdelivr.net/gh/Loyalsoldier/geoip@release/GeoLite2-ASN.mmdb
175
+ geosite: https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat
176
+ proxies: []
177
+ proxy-providers: {}
178
+ proxy-groups: []
179
+ rule-providers: {}
180
+ rules: []
@@ -35,7 +35,7 @@
35
35
  name = "pymecli"
36
36
  readme = "README.md"
37
37
  requires-python = ">=3.10"
38
- version = "0.5.1"
38
+ version = "0.5.3"
39
39
 
40
40
  [project.urls]
41
41
  Homepage = "https://pypi.org/project/pymecli"