-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathmain.py
More file actions
101 lines (82 loc) · 3.38 KB
/
Copy pathmain.py
File metadata and controls
101 lines (82 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import asyncio
import os
import yaml
from typing import List
from core.fetcher import parallel_fetch
from core.processor import NodeProcessor
from core.generator import Generator
SOURCES_FILE = "sources.list"
TEMPLATE_FILE = "config.yaml"
OUTPUT_FILE = "list.meta.yml"
import datetime
async def main():
# 1. Load Sources from YAML
sources_file = "sources.yaml"
if not os.path.exists(sources_file):
print(f"Error: {sources_file} not found.")
return
now = datetime.datetime.now()
source_infos = []
with open(sources_file, 'r', encoding='utf-8') as f:
data = yaml.safe_load(f)
sources_data = data.get('sources', [])
# Append private sources from Environment Variable (GitHub Secrets)
private_sources = os.getenv('PRIVATE_SOURCES')
if private_sources:
try:
private_data = yaml.safe_load(private_sources)
if isinstance(private_data, list):
sources_data.extend(private_data)
print(f"Loaded {len(private_data)} private sources from Secrets.")
except Exception as e:
print(f"Failed to parse PRIVATE_SOURCES: {e}")
for s in sources_data:
if isinstance(s, dict):
url = s.get('url')
if not url: continue
# Handle date placeholders in URL
url = url.replace('%Y', now.strftime('%Y'))
url = url.replace('%m', now.strftime('%m'))
url = url.replace('%d', now.strftime('%d'))
# Translate recursive flag to * prefix
if s.get('recursive'):
url = '*' + url
ignore = s.get('ignore')
filters = {'ignore': ignore} if ignore else {}
source_infos.append({
'url': url,
'filters': filters
})
if not source_infos:
print("No active sources found.")
return
import time
start_time = time.time()
# 获取来源数量用于统计
active_source_count = len(source_infos)
print(f"Starting fetching from {active_source_count} active sources...")
# 2. Parallel fetching
all_raw_nodes = await parallel_fetch(source_infos)
raw_count = len(all_raw_nodes)
print(f"Fetched {raw_count} raw nodes.")
# 3. Processing (Deduplicate, Clean Names, Emoji Flags)
processor = NodeProcessor()
processed_nodes = processor.process_all(all_raw_nodes)
# 4. Generate Output (Merge with template)
if not os.path.exists(TEMPLATE_FILE):
print(f"Warning: {TEMPLATE_FILE} not found. Using node list only.")
with open(OUTPUT_FILE, "w", encoding="utf-8") as f:
yaml.dump({"proxies": [n.to_clash() for n in processed_nodes]}, f, allow_unicode=True)
else:
elapsed_time = time.time() - start_time
generator = Generator(TEMPLATE_FILE)
generator.generate(processed_nodes, OUTPUT_FILE, active_source_count, raw_count, elapsed_time)
# 5. Update README Source Contribution Table
try:
from utils.stats import update_readme_source_stats
await update_readme_source_stats()
except Exception as e:
print(f"Warning: Failed to update README source stats table: {e}")
print(f"\n[OK] All done! Generated: {OUTPUT_FILE}")
if __name__ == "__main__":
asyncio.run(main())