add github-mirror

This commit is contained in:
FlintyLemming 2025-06-19 10:50:45 +08:00
parent 368aec13dc
commit 66800bd69a
3 changed files with 192 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.DS_Store

View File

@ -0,0 +1,76 @@
---
## 权限修改
# 是否以 root 运行。如果是,并且 fix-chown 为 true则会根据 apply-uid 和 apply-gid修改所有产生的文件的所有者和组如果不是则不进行任何文件权限相关的修改。
run-as-root: true
fix-chown: true
apply-uid: 1000
apply-gid: 100
## 代理设置
proxy:
enabled: false # 是否启用代理
http: "http://127.0.0.1:7890" # HTTP 代理地址
https: "http://127.0.0.1:7890" # HTTPS 代理地址
## 文件相关配置
saved-path: "/home/flintylemming/share/github-release-mirror"
## 跟踪配置
# 标题
track-list:
# netbird:
# # 必填Repo 的作者和项目名称,不需要完整地址
# repo-info: "netbirdio/netbird"
# # (选填)保存文件夹的名称,创建在 saved-path 下,如果不设置,使用该节标题名
# folder-name: "Netbird"
# # (选填)设置是否导出 What's Changed 为 md 文件,默认为 true
# get-changes-info: true
# # (选填)设置指定的后缀,只下载 Release 中指定后缀的文件
# file-type:
# - msi
# - deb
# - pkg
opentrace:
repo-info: "Archeb/opentrace"
folder-name: "OpenTrace"
get-changes-info: true
regex: "(osx|win)"
powertoys:
repo-info: "microsoft/PowerToys"
folder-name: "PowerToys"
get-changes-info: true
# rustdesk:
# repo-info: "rustdesk/rustdesk"
# folder-name: "RustDesk"
# file-type:
# - exe
# - dmg
smartporxy:
repo-info: "salarcode/SmartProxy"
folder-name: "SmartProxy"
ddns-go:
repo-info: "jeessy2/ddns-go"
folder-name: "ddns-go"
sms-forwarder:
repo-info: "pppscn/SmsForwarder"
folder-name: "SmsForwarder"
nezha-agent:
repo-info: "nezhahq/agent"
folder-name: "Nezha Agent"
# massCode:
# repo-info: "massCodeIO/massCode"
# folder-name: "massCode"
flclash:
repo-info: "chen08209/FlClash"
folder-name: "FlClash"
immich:
repo-info: "immich-app/immich"
folder-name: "immich"
file-type:
- apk
surge:
repo-info: "LanYunDev/InjectLib_bak"
folder-name: "Qurge"
beszel:
repo-info: "henrygd/beszel"
folder-name: "Beszel"
easytier:
repo-info: "EasyTier/EasyTier"
folder-name: "EasyTier"

View File

@ -0,0 +1,115 @@
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()