Files
config-man/src/config_man/core/config_manager.py

119 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
import os
import subprocess
import requests
from typing import Dict, Optional, Tuple
from ..utils.crypto import encrypt, decrypt
class ConfigManager:
"""配置文件管理器"""
def __init__(self, storage_path: str = "ab", cdn_base_url: str = ""):
self.storage_path = storage_path
self.cdn_base_url = cdn_base_url
def version_to_path(self, version: str) -> str:
"""将版本号转换为存储路径格式"""
# 0.29 -> 0_29
return version.replace('.', '_')
def get_config_path(self, version: str, platform: str) -> str:
"""获取配置文件在对象存储中的路径"""
version_path = self.version_to_path(version)
filename = f"{platform}config.json"
return f"{self.storage_path}/{version_path}/{filename}"
def get_cdn_url(self, version: str, platform: str) -> str:
"""获取配置文件在CDN中的URL"""
if not self.cdn_base_url:
return ""
version_path = self.version_to_path(version)
filename = f"{platform}config.json"
return f"{self.cdn_base_url}/{self.storage_path}/{version_path}/{filename}"
def download_from_storage(self, version: str, platform: str) -> Optional[str]:
"""从对象存储下载并解密配置文件"""
try:
config_path = self.get_config_path(version, platform)
# 使用rclone下载文件
result = subprocess.run(
["rclone", "cat", config_path],
capture_output=True,
text=True,
timeout=30
)
if result.returncode != 0:
print(f"警告: 无法从对象存储下载 {config_path}: {result.stderr}")
return None
# 解密文件内容
encrypted_content = result.stdout.strip()
if not encrypted_content:
print(f"警告: 文件 {config_path} 为空")
return None
decrypted_content = decrypt(encrypted_content)
return decrypted_content
except subprocess.TimeoutExpired:
print(f"错误: 下载 {config_path} 超时")
return None
except Exception as e:
print(f"错误: 下载 {config_path} 失败: {str(e)}")
return None
def get_from_cdn(self, version: str, platform: str) -> Optional[str]:
"""从CDN获取配置文件内容"""
try:
cdn_url = self.get_cdn_url(version, platform)
if not cdn_url:
print(f"警告: CDN URL未配置跳过CDN内容获取")
return None
response = requests.get(cdn_url, timeout=10)
response.raise_for_status()
# CDN中的内容应该是解密后的JSON
return response.text
except requests.RequestException as e:
print(f"警告: 无法从CDN获取 {cdn_url}: {str(e)}")
return None
except Exception as e:
print(f"错误: 获取CDN内容失败: {str(e)}")
return None
def parse_config(self, content: str) -> Optional[Dict]:
"""解析配置文件内容"""
try:
return json.loads(content)
except json.JSONDecodeError as e:
print(f"错误: 配置文件格式错误: {str(e)}")
return None
def compare_configs(self, storage_config: Dict, cdn_config: Dict) -> Dict:
"""比较存储配置和CDN配置的差异"""
all_keys = set(storage_config.keys()) | set(cdn_config.keys())
differences = {}
for key in sorted(all_keys):
storage_value = storage_config.get(key, "N/A")
cdn_value = cdn_config.get(key, "N/A")
if storage_value != cdn_value:
differences[key] = {
"storage": storage_value,
"cdn": cdn_value,
"different": True
}
else:
differences[key] = {
"storage": storage_value,
"cdn": cdn_value,
"different": False
}
return differences