clash-linux commited on
Commit
9fd3d43
·
verified ·
1 Parent(s): 438d71d

Upload 18 files

Browse files
Files changed (2) hide show
  1. app/main.py +46 -0
  2. app/sub_manager.py +103 -73
app/main.py CHANGED
@@ -244,6 +244,23 @@ def debug_show_config():
244
  logger.error(f"读取配置文件时出错: {str(e)}")
245
  return jsonify({"success": False, "error": str(e)}), 500
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  # --- Yacd UI & Clash API 反向代理路由 ---
248
 
249
  @app.route('/ui/')
@@ -422,6 +439,34 @@ def index():
422
  configDiv.innerHTML = '<p style="color:red">请求失败: ' + error + '</p>';
423
  }});
424
  }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
425
  </script>
426
  </head>
427
  <body>
@@ -439,6 +484,7 @@ def index():
439
  <div class="debug-section">
440
  <h3>调试选项</h3>
441
  <button class="button" onclick="viewConfig()">查看当前配置文件</button>
 
442
  <button class="button danger" onclick="if(confirm('确定要清理配置并重启服务吗?此操作不可逆!')) requestWithApiKey('/debug/clean')">清理配置并重启</button>
443
  <div id="config-content" style="margin-top: 15px;"></div>
444
  </div>
 
244
  logger.error(f"读取配置文件时出错: {str(e)}")
245
  return jsonify({"success": False, "error": str(e)}), 500
246
 
247
+ @app.route("/debug/raw-config", methods=["GET"])
248
+ @authenticate
249
+ def debug_show_raw_config():
250
+ """获取并显示原始下载的订阅内容"""
251
+ config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "data", "config.yaml.raw")
252
+
253
+ if not os.path.exists(config_path):
254
+ return jsonify({"success": False, "error": "原始配置文件不存在"}), 404
255
+
256
+ try:
257
+ with open(config_path, "r", encoding="utf-8") as f:
258
+ content = f.read()
259
+ return jsonify({"success": True, "content": content})
260
+ except Exception as e:
261
+ logger.error(f"读取原始配置文件时出错: {str(e)}")
262
+ return jsonify({"success": False, "error": str(e)}), 500
263
+
264
  # --- Yacd UI & Clash API 反向代理路由 ---
265
 
266
  @app.route('/ui/')
 
439
  configDiv.innerHTML = '<p style="color:red">请求失败: ' + error + '</p>';
440
  }});
441
  }}
442
+
443
+ function viewRawConfig() {{
444
+ const apiKey = prompt('请输入API密钥 (默认为 changeme)', 'changeme');
445
+ if (apiKey === null) return;
446
+
447
+ fetch('/debug/raw-config', {{
448
+ headers: {{ 'X-API-Key': apiKey }}
449
+ }})
450
+ .then(response => response.json())
451
+ .then(data => {{
452
+ const configDiv = document.getElementById('config-content');
453
+ configDiv.innerHTML = ''; // 清空之前的内容
454
+ if (data.success) {{
455
+ const pre = document.createElement('pre');
456
+ pre.textContent = data.content;
457
+ configDiv.appendChild(pre);
458
+ }} else {{
459
+ const errorP = document.createElement('p');
460
+ errorP.style.color = 'red';
461
+ errorP.textContent = '获取原始配置失败: ' + data.error;
462
+ configDiv.appendChild(errorP);
463
+ }}
464
+ }})
465
+ .catch(error => {{
466
+ const configDiv = document.getElementById('config-content');
467
+ configDiv.innerHTML = '<p style="color:red">请求失败: ' + error + '</p>';
468
+ }});
469
+ }}
470
  </script>
471
  </head>
472
  <body>
 
484
  <div class="debug-section">
485
  <h3>调试选项</h3>
486
  <button class="button" onclick="viewConfig()">查看当前配置文件</button>
487
+ <button class="button" onclick="viewRawConfig()">查看原始订阅内容</button>
488
  <button class="button danger" onclick="if(confirm('确定要清理配置并重启服务吗?此操作不可逆!')) requestWithApiKey('/debug/clean')">清理配置并重启</button>
489
  <div id="config-content" style="margin-top: 15px;"></div>
490
  </div>
app/sub_manager.py CHANGED
@@ -303,7 +303,10 @@ secret: ""
303
  config_content = "secret: ''\n" + config_content
304
  has_patch = True
305
 
306
- # 尝试解析YAML并修复代理组引用问题
 
 
 
307
  try:
308
  import yaml
309
  logger.info("正在使用PyYAML解析和修复配置")
@@ -313,95 +316,128 @@ secret: ""
313
 
314
  # 检查是否有代理和代理组
315
  if config_yaml and isinstance(config_yaml, dict):
316
- if "proxies" in config_yaml and "proxy-groups" in config_yaml:
317
- # 获取所有代理节点名称
 
 
 
 
 
 
 
318
  proxy_names = set()
319
- for proxy in config_yaml.get("proxies", []):
320
  if isinstance(proxy, dict) and "name" in proxy:
321
  proxy_names.add(proxy["name"])
 
322
 
323
  # 添加内置代理
324
  proxy_names.add("DIRECT")
325
  proxy_names.add("REJECT")
326
 
327
- # 修复代理组引用
328
- groups_fixed = False
329
- for group in config_yaml.get("proxy-groups", []):
330
- if isinstance(group, dict) and "proxies" in group:
331
- # 删除组中引用的不存在的代理
332
- valid_proxies = []
333
- for proxy in group["proxies"]:
334
- if proxy in proxy_names or proxy == group.get("name", ""):
335
- valid_proxies.append(proxy)
336
- else:
337
- logger.warning(f"删除代理组 {group.get('name', '未知')} 中的无效引用: {proxy}")
 
 
 
 
 
 
 
 
 
 
 
338
  groups_fixed = True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
 
340
- # 确保代理组至少有一个有效代理
341
- if not valid_proxies:
342
- valid_proxies.append("DIRECT")
343
- logger.warning(f"为空代理组 {group.get('name', '未知')} 添加默认代理: DIRECT")
344
- groups_fixed = True
345
 
346
- group["proxies"] = valid_proxies
 
 
 
 
 
 
 
347
 
348
- # 检查是否有GLOBAL组,如果没有,添加一个
349
- has_global = False
350
- for group in config_yaml.get("proxy-groups", []):
351
- if isinstance(group, dict) and group.get("name") == "GLOBAL":
352
- has_global = True
353
- break
354
 
355
- if not has_global:
 
356
  # 添加GLOBAL策略组
357
  logger.info("添加GLOBAL策略组")
358
- if "proxy-groups" not in config_yaml:
359
- config_yaml["proxy-groups"] = []
360
 
361
  # 确定要放入GLOBAL组的代理
362
  global_proxies = ["DIRECT"]
363
- # 添加所有代理节点到GLOBAL组
364
- for proxy in config_yaml.get("proxies", []):
365
- if isinstance(proxy, dict) and "name" in proxy:
366
- proxy_name = proxy["name"]
367
- if proxy_name != "DIRECT" and proxy_name != "REJECT":
368
- global_proxies.append(proxy_name)
369
 
370
- config_yaml["proxy-groups"].insert(0, {
371
- "name": "GLOBAL",
372
- "type": "select",
373
- "proxies": global_proxies
374
- })
375
- groups_fixed = True
376
- has_patch = True
377
-
378
- # 如果修复了代理组,重新生成配置
379
- if groups_fixed:
380
- config_content = yaml.dump(config_yaml, sort_keys=False, allow_unicode=True)
381
- has_patch = True
382
- else:
383
- # 配置缺少代理或代理组,添加基本结构
384
- if "proxies" not in config_yaml:
385
- config_yaml["proxies"] = [{"name": "DIRECT", "type": "direct"}]
386
- has_patch = True
387
-
388
- if "proxy-groups" not in config_yaml:
389
  config_yaml["proxy-groups"] = [{
390
  "name": "GLOBAL",
391
  "type": "select",
392
- "proxies": ["DIRECT"]
393
  }]
 
394
  has_patch = True
395
-
396
- # 更新配置内容
 
 
 
 
 
 
 
 
 
397
  config_content = yaml.dump(config_yaml, sort_keys=False, allow_unicode=True)
 
398
  else:
399
- # 配置为空或无效,添加基本配置
400
- logger.warning("配置为空或无效,添加基本配置结构")
401
- # 使用简单的文本分析,避免添加重复的配置
402
- has_proxy_groups = "proxy-groups:" in config_content
403
- has_global_group = "GLOBAL" in config_content or "- name: GLOBAL" in config_content
404
-
405
  if not has_proxy_groups and not has_global_group:
406
  logger.info("未检测到proxy-groups或GLOBAL策略组,添加基本的GLOBAL策略组")
407
  config_content += """
@@ -414,13 +450,10 @@ proxy-groups:
414
  has_patch = True
415
  else:
416
  logger.info("检测到已有proxy-groups或GLOBAL配置,跳过添加")
417
-
418
  except ImportError as e:
419
  logger.error(f"导入PyYAML模块失败: {str(e)}")
420
- # 使用简单的文本分析,避免添加重复的配置
421
- has_proxy_groups = "proxy-groups:" in config_content
422
- has_global_group = "GLOBAL" in config_content or "- name: GLOBAL" in config_content
423
-
424
  if not has_proxy_groups and not has_global_group:
425
  logger.info("未检测到proxy-groups或GLOBAL策略组,添加基本的GLOBAL策略组")
426
  config_content += """
@@ -435,10 +468,7 @@ proxy-groups:
435
  logger.info("检测到已有proxy-groups或GLOBAL配置,跳过添加")
436
  except Exception as yaml_err:
437
  logger.error(f"处理YAML配置时出错: {str(yaml_err)}")
438
- # 使用简单的文本分析,避免添加重复的配置
439
- has_proxy_groups = "proxy-groups:" in config_content
440
- has_global_group = "GLOBAL" in config_content or "- name: GLOBAL" in config_content
441
-
442
  if not has_proxy_groups and not has_global_group:
443
  logger.info("未检测到proxy-groups或GLOBAL策略组,添加基本的GLOBAL策略组")
444
  config_content += """
 
303
  config_content = "secret: ''\n" + config_content
304
  has_patch = True
305
 
306
+ # 确保配置了全局策略组 - 使用简单的文本检查
307
+ has_proxy_groups = "proxy-groups:" in config_content
308
+ has_global_group = "GLOBAL" in config_content or "- name: GLOBAL" in config_content
309
+
310
  try:
311
  import yaml
312
  logger.info("正在使用PyYAML解析和修复配置")
 
316
 
317
  # 检查是否有代理和代理组
318
  if config_yaml and isinstance(config_yaml, dict):
319
+ # 确保proxies存在并且是一个有效的列表
320
+ if "proxies" not in config_yaml or not isinstance(config_yaml["proxies"], list):
321
+ logger.warning("配置中未找到有效的proxies列表,尝试保留原始内容")
322
+
323
+ # 即使没有proxy-groups,也先保留所有已有的proxies
324
+ if "proxies" in config_yaml and isinstance(config_yaml["proxies"], list):
325
+ proxies_list = config_yaml["proxies"]
326
+
327
+ # 收集所有代理节点名称
328
  proxy_names = set()
329
+ for proxy in proxies_list:
330
  if isinstance(proxy, dict) and "name" in proxy:
331
  proxy_names.add(proxy["name"])
332
+ logger.info(f"找到 {len(proxy_names)} 个代理节点")
333
 
334
  # 添加内置代理
335
  proxy_names.add("DIRECT")
336
  proxy_names.add("REJECT")
337
 
338
+ # 检查并固定proxy-groups
339
+ if "proxy-groups" in config_yaml and isinstance(config_yaml["proxy-groups"], list):
340
+ groups_fixed = False
341
+ for group in config_yaml["proxy-groups"]:
342
+ if isinstance(group, dict) and "proxies" in group and "name" in group:
343
+ group_name = group["name"]
344
+ # 检查group["proxies"]中哪些是无效引用
345
+ invalid_proxies = []
346
+ valid_proxies = []
347
+
348
+ for proxy in group["proxies"]:
349
+ if proxy in proxy_names or proxy == group_name:
350
+ valid_proxies.append(proxy)
351
+ else:
352
+ logger.warning(f"删除代理组 {group_name} 中的无效引用: {proxy}")
353
+ invalid_proxies.append(proxy)
354
+ groups_fixed = True
355
+
356
+ # 确保代理组至少有一个有效代理
357
+ if not valid_proxies:
358
+ valid_proxies.append("DIRECT")
359
+ logger.warning(f"为空代理组 {group_name} 添加默认代理: DIRECT")
360
  groups_fixed = True
361
+
362
+ group["proxies"] = valid_proxies
363
+
364
+ # 检查是否有GLOBAL组,如果没有,添加一个
365
+ has_global = False
366
+ for group in config_yaml["proxy-groups"]:
367
+ if isinstance(group, dict) and group.get("name") == "GLOBAL":
368
+ has_global = True
369
+ break
370
+
371
+ if not has_global:
372
+ # 添加GLOBAL策略组
373
+ logger.info("添加GLOBAL策略组")
374
+
375
+ # 确定要放入GLOBAL组的代理
376
+ global_proxies = ["DIRECT"]
377
+ # 从代理节点和其他策略组中选择要添加到GLOBAL的项
378
+ # 优先添加策略组
379
+ for group in config_yaml["proxy-groups"]:
380
+ if isinstance(group, dict) and "name" in group:
381
+ group_name = group["name"]
382
+ if group_name != "GLOBAL":
383
+ global_proxies.append(group_name)
384
 
385
+ # 如果没有其他策略组,添加所有代理节点
386
+ if len(global_proxies) <= 1: # 只有DIRECT
387
+ for proxy_name in proxy_names:
388
+ if proxy_name != "DIRECT" and proxy_name != "REJECT":
389
+ global_proxies.append(proxy_name)
390
 
391
+ # 添加GLOBAL组到配置
392
+ config_yaml["proxy-groups"].insert(0, {
393
+ "name": "GLOBAL",
394
+ "type": "select",
395
+ "proxies": global_proxies
396
+ })
397
+ groups_fixed = True
398
+ has_patch = True
399
 
400
+ # 如果修复了代理组,重新生成配置
401
+ if groups_fixed:
402
+ config_content = yaml.dump(config_yaml, sort_keys=False, allow_unicode=True)
403
+ has_patch = True
 
 
404
 
405
+ # 如果没有proxy-groups,添加基本的proxy-groups
406
+ elif not "proxy-groups" in config_yaml:
407
  # 添加GLOBAL策略组
408
  logger.info("添加GLOBAL策略组")
 
 
409
 
410
  # 确定要放入GLOBAL组的代理
411
  global_proxies = ["DIRECT"]
412
+ # 如果有代理节点,添加所有代理节点
413
+ for proxy_name in proxy_names:
414
+ if proxy_name != "DIRECT" and proxy_name != "REJECT":
415
+ global_proxies.append(proxy_name)
 
 
416
 
417
+ # 添加proxy-groups到配置
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
  config_yaml["proxy-groups"] = [{
419
  "name": "GLOBAL",
420
  "type": "select",
421
+ "proxies": global_proxies
422
  }]
423
+ config_content = yaml.dump(config_yaml, sort_keys=False, allow_unicode=True)
424
  has_patch = True
425
+
426
+ # 如果既没有proxies也没有proxy-groups,添加基本配置
427
+ elif "proxies" not in config_yaml and "proxy-groups" not in config_yaml:
428
+ # 可能不是Clash配置或非常基础的配置
429
+ logger.warning("配置中未找到proxies和proxy-groups,添加基本配置")
430
+ config_yaml["proxies"] = [{"name": "DIRECT", "type": "direct"}]
431
+ config_yaml["proxy-groups"] = [{
432
+ "name": "GLOBAL",
433
+ "type": "select",
434
+ "proxies": ["DIRECT"]
435
+ }]
436
  config_content = yaml.dump(config_yaml, sort_keys=False, allow_unicode=True)
437
+ has_patch = True
438
  else:
439
+ # 无法解析为有效的YAML,尝试简单文本修复
440
+ logger.warning("配置无法解析为有效的YAML,使用简单文本修复")
 
 
 
 
441
  if not has_proxy_groups and not has_global_group:
442
  logger.info("未检测到proxy-groups或GLOBAL策略组,添加基本的GLOBAL策略组")
443
  config_content += """
 
450
  has_patch = True
451
  else:
452
  logger.info("检测到已有proxy-groups或GLOBAL配置,跳过添加")
453
+
454
  except ImportError as e:
455
  logger.error(f"导入PyYAML模块失败: {str(e)}")
456
+ # 回退到简单的文本检查
 
 
 
457
  if not has_proxy_groups and not has_global_group:
458
  logger.info("未检测到proxy-groups或GLOBAL策略组,添加基本的GLOBAL策略组")
459
  config_content += """
 
468
  logger.info("检测到已有proxy-groups或GLOBAL配置,跳过添加")
469
  except Exception as yaml_err:
470
  logger.error(f"处理YAML配置时出错: {str(yaml_err)}")
471
+ # 回退到简单的文本检查
 
 
 
472
  if not has_proxy_groups and not has_global_group:
473
  logger.info("未检测到proxy-groups或GLOBAL策略组,添加基本的GLOBAL策略组")
474
  config_content += """