import os import re import requests import yaml import logging from pathlib import Path # 设置日志 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler("/tmp/github-release-mirror-log.txt"), logging.StreamHandler() ]) # 获取当前脚本所在目录的绝对路径 script_dir = os.path.dirname(os.path.abspath(__file__)) config_path = os.path.join(script_dir, "config.yaml") # 读取配置文件 with open(config_path, 'r') as file: config = yaml.safe_load(file) # 配置代理 proxies = {} if 'proxy' in config and config['proxy'].get('enabled', False): if 'http' in config['proxy']: proxies['http'] = config['proxy']['http'] if 'https' in config['proxy']: proxies['https'] = config['proxy']['https'] if proxies: logging.info(f"已启用代理: {proxies}") def download_file(url, filename): """下载文件到指定路径""" request_kwargs = {'stream': True} if proxies: request_kwargs['proxies'] = proxies with requests.get(url, **request_kwargs) as r: with open(filename, 'wb') as f: for chunk in r.iter_content(chunk_size=8192): f.write(chunk) logging.info(f"文件下载完成:{filename}") def change_ownership(path, uid, gid): """更改文件或目录的所有者""" os.chown(path, uid, gid) for root, dirs, files in os.walk(path): for d in dirs: os.chown(os.path.join(root, d), uid, gid) for f in files: os.chown(os.path.join(root, f), uid, gid) logging.info(f"已更改所有权:{path}") def process_repo(repo_config, base_path, uid, gid): repo_info = repo_config['repo-info'] folder_name = repo_config.get('folder-name', repo_info.split('/')[-1]) get_changes_info = repo_config.get('get-changes-info', True) file_type = repo_config.get('file-type', []) regex_pattern = repo_config.get('regex', None) logging.info(f"\n正在处理项目:{folder_name}") logging.info(f"仓库名称:{repo_info}") API_URL = f"https://api.github.com/repos/{repo_info}/releases/latest" request_kwargs = {} if proxies: request_kwargs['proxies'] = proxies response = requests.get(API_URL, **request_kwargs) latest_release = response.json() latest_version = latest_release['tag_name'] release_notes = latest_release['body'] assets = latest_release['assets'] version_dir = base_path / folder_name / latest_version if not version_dir.exists(): logging.info(f"发现新版本:{latest_version},正在下载...") version_dir.mkdir(parents=True) if get_changes_info: with open(version_dir / "CHANGELOG.md", "w") as f: f.write(release_notes) logging.info("已保存变更日志。") for asset in assets: if file_type and not any(asset['name'].endswith(ext) for ext in file_type): continue if regex_pattern and not re.match(regex_pattern, asset['name']): continue download_url = asset['browser_download_url'] filename = version_dir / asset['name'] download_file(download_url, filename) if config['run-as-root'] and config['fix-chown']: change_ownership(version_dir, uid, gid) logging.info(f"版本 {latest_version} 下载完成。") else: logging.info(f"最新版本 {latest_version} 已存在。") def main(): saved_path = Path(config['saved-path']) uid = config['apply-uid'] gid = config['apply-gid'] for track_item, track_config in config['track-list'].items(): process_repo(track_config, saved_path, uid, gid) if __name__ == "__main__": main()