|
@@ -7,12 +7,13 @@ from zipfile import ZipFile
|
|
|
import stat
|
|
|
import argparse
|
|
|
import subprocess
|
|
|
+import tempfile
|
|
|
|
|
|
# 定义常量
|
|
|
MIHOMO_BASE_URL = 'https://github.com/MetaCubeX/mihomo/releases/download'
|
|
|
-CORE_SERVICE_BASE_URL = 'https://github.com/alroyso/core-service/releases/download/test_2023.11.22_09-33'
|
|
|
+CORE_SERVICE_BASE_URL = 'https://github.com/alroyso/core-service/releases/download'
|
|
|
MIHOMO_VERSION = 'v1.18.8' # 根据实际版本修改
|
|
|
-CORE_SERVICE_VERSION = 'test_2023.11.22_09-33'
|
|
|
+CORE_SERVICE_VERSION = 'v1.0.2'
|
|
|
ASSETS_DIR = './assets/bin'
|
|
|
SYSTEM = platform.system().lower()
|
|
|
|
|
@@ -30,40 +31,75 @@ def get_download_urls():
|
|
|
"""
|
|
|
download_urls = []
|
|
|
|
|
|
- # mihomo 下载目录和 URL
|
|
|
- mihomo_dir = os.path.join(ASSETS_DIR, 'mihomo')
|
|
|
- if not os.path.exists(mihomo_dir):
|
|
|
- os.makedirs(mihomo_dir)
|
|
|
-
|
|
|
- # core-service 下载目录和 URL
|
|
|
- core_service_dir = os.path.join(ASSETS_DIR, 'core-service')
|
|
|
- if not os.path.exists(core_service_dir):
|
|
|
- os.makedirs(core_service_dir)
|
|
|
-
|
|
|
# 获取 ClashName 的 platform 和 arch
|
|
|
platform_name, arch_name = get_platform_arch()
|
|
|
|
|
|
- # 下载 macOS 的 arm64 和 x86_64 架构
|
|
|
+ # 下载 macOS、Linux、Windows 的 arm64 和 x86_64 架构
|
|
|
if SYSTEM == 'darwin':
|
|
|
+ # macOS
|
|
|
download_urls.append((
|
|
|
f'mihomo-darwin-arm64-{MIHOMO_VERSION}.gz',
|
|
|
f'{MIHOMO_BASE_URL}/{MIHOMO_VERSION}/mihomo-darwin-arm64-{MIHOMO_VERSION}.gz',
|
|
|
- mihomo_dir, 'arm64'
|
|
|
+ 'arm64'
|
|
|
))
|
|
|
download_urls.append((
|
|
|
f'mihomo-darwin-amd64-{MIHOMO_VERSION}.gz',
|
|
|
f'{MIHOMO_BASE_URL}/{MIHOMO_VERSION}/mihomo-darwin-amd64-{MIHOMO_VERSION}.gz',
|
|
|
- mihomo_dir, 'x86_64'
|
|
|
+ 'x86_64'
|
|
|
))
|
|
|
download_urls.append((
|
|
|
f'ccore-service-darwin-arm64-{CORE_SERVICE_VERSION}.gz',
|
|
|
- f'{CORE_SERVICE_BASE_URL}/ccore-service-darwin-arm64-{CORE_SERVICE_VERSION}.gz',
|
|
|
- core_service_dir, 'arm64'
|
|
|
+ f'{CORE_SERVICE_BASE_URL}/{CORE_SERVICE_VERSION}/ccore-service-darwin-arm64-{CORE_SERVICE_VERSION}.gz',
|
|
|
+ 'arm64'
|
|
|
))
|
|
|
download_urls.append((
|
|
|
f'ccore-service-darwin-amd64-{CORE_SERVICE_VERSION}.gz',
|
|
|
- f'{CORE_SERVICE_BASE_URL}/ccore-service-darwin-amd64-{CORE_SERVICE_VERSION}.gz',
|
|
|
- core_service_dir, 'x86_64'
|
|
|
+ f'{CORE_SERVICE_BASE_URL}/{CORE_SERVICE_VERSION}/ccore-service-darwin-amd64-{CORE_SERVICE_VERSION}.gz',
|
|
|
+ 'x86_64'
|
|
|
+ ))
|
|
|
+ elif SYSTEM == 'linux':
|
|
|
+ # Linux
|
|
|
+ download_urls.append((
|
|
|
+ f'mihomo-linux-arm64-{MIHOMO_VERSION}.gz',
|
|
|
+ f'{MIHOMO_BASE_URL}/{MIHOMO_VERSION}/mihomo-linux-arm64-{MIHOMO_VERSION}.gz',
|
|
|
+ 'arm64'
|
|
|
+ ))
|
|
|
+ download_urls.append((
|
|
|
+ f'mihomo-linux-amd64-{MIHOMO_VERSION}.gz',
|
|
|
+ f'{MIHOMO_BASE_URL}/{MIHOMO_VERSION}/mihomo-linux-amd64-{MIHOMO_VERSION}.gz',
|
|
|
+ 'x86_64'
|
|
|
+ ))
|
|
|
+ download_urls.append((
|
|
|
+ f'ccore-service-linux-arm64-{CORE_SERVICE_VERSION}.gz',
|
|
|
+ f'{CORE_SERVICE_BASE_URL}/{CORE_SERVICE_VERSION}/ccore-service-linux-arm64-{CORE_SERVICE_VERSION}.gz',
|
|
|
+ 'arm64'
|
|
|
+ ))
|
|
|
+ download_urls.append((
|
|
|
+ f'ccore-service-linux-amd64-{CORE_SERVICE_VERSION}.gz',
|
|
|
+ f'{CORE_SERVICE_BASE_URL}/{CORE_SERVICE_VERSION}/ccore-service-linux-amd64-{CORE_SERVICE_VERSION}.gz',
|
|
|
+ 'x86_64'
|
|
|
+ ))
|
|
|
+ elif SYSTEM == 'windows':
|
|
|
+ # Windows
|
|
|
+ download_urls.append((
|
|
|
+ f'mihomo-windows-arm64-{MIHOMO_VERSION}.zip',
|
|
|
+ f'{MIHOMO_BASE_URL}/{MIHOMO_VERSION}/mihomo-windows-arm64-{MIHOMO_VERSION}.zip',
|
|
|
+ 'arm64'
|
|
|
+ ))
|
|
|
+ download_urls.append((
|
|
|
+ f'mihomo-windows-amd64-{MIHOMO_VERSION}.zip',
|
|
|
+ f'{MIHOMO_BASE_URL}/{MIHOMO_VERSION}/mihomo-windows-amd64-{MIHOMO_VERSION}.zip',
|
|
|
+ 'x86_64'
|
|
|
+ ))
|
|
|
+ download_urls.append((
|
|
|
+ f'ccore-service-windows-arm64-{CORE_SERVICE_VERSION}.zip',
|
|
|
+ f'{CORE_SERVICE_BASE_URL}/{CORE_SERVICE_VERSION}/ccore-service-windows-arm64-{CORE_SERVICE_VERSION}.zip',
|
|
|
+ 'arm64'
|
|
|
+ ))
|
|
|
+ download_urls.append((
|
|
|
+ f'ccore-service-windows-amd64-{CORE_SERVICE_VERSION}.zip',
|
|
|
+ f'{CORE_SERVICE_BASE_URL}/{CORE_SERVICE_VERSION}/ccore-service-windows-amd64-{CORE_SERVICE_VERSION}.zip',
|
|
|
+ 'x86_64'
|
|
|
))
|
|
|
|
|
|
return download_urls
|
|
@@ -72,124 +108,126 @@ def download_file(url, output_path):
|
|
|
"""
|
|
|
下载文件
|
|
|
"""
|
|
|
- print(f"Downloading {url} ...")
|
|
|
+ print(f"正在下载 {url} ...")
|
|
|
response = requests.get(url, stream=True)
|
|
|
if response.status_code == 200:
|
|
|
with open(output_path, 'wb') as file:
|
|
|
shutil.copyfileobj(response.raw, file)
|
|
|
- print(f"Download complete: {output_path}")
|
|
|
+ print(f"下载完成: {output_path}")
|
|
|
else:
|
|
|
- print(f"Failed to download {url}, status code: {response.status_code}")
|
|
|
+ print(f"下载失败 {url}, 状态码: {response.status_code}")
|
|
|
|
|
|
def extract_gz_file(file_path, output_path):
|
|
|
"""
|
|
|
解压 .gz 文件
|
|
|
"""
|
|
|
- print(f"Extracting {file_path} ...")
|
|
|
+ print(f"正在解压 {file_path} ...")
|
|
|
with gzip.open(file_path, 'rb') as f_in:
|
|
|
with open(output_path, 'wb') as f_out:
|
|
|
shutil.copyfileobj(f_in, f_out)
|
|
|
- print(f"Extracted to {output_path}")
|
|
|
+ print(f"解压到 {output_path}")
|
|
|
|
|
|
def extract_zip_file(file_path, output_dir):
|
|
|
"""
|
|
|
解压 .zip 文件
|
|
|
"""
|
|
|
- print(f"Extracting {file_path} ...")
|
|
|
+ print(f"正在解压 {file_path} ...")
|
|
|
with ZipFile(file_path, 'r') as zip_ref:
|
|
|
zip_ref.extractall(output_dir)
|
|
|
- print(f"Extracted to {output_dir}")
|
|
|
+ print(f"解压到 {output_dir}")
|
|
|
|
|
|
def merge_binaries(arm_file, x86_file, output_file):
|
|
|
"""
|
|
|
使用 lipo 合并 arm64 和 x86_64 的二进制文件
|
|
|
"""
|
|
|
- print(f"Merging {arm_file} and {x86_file} into {output_file}")
|
|
|
+ print(f"正在合并 {arm_file} 和 {x86_file} 到 {output_file}")
|
|
|
subprocess.run(['lipo', '-create', '-output', output_file, arm_file, x86_file], check=True)
|
|
|
- print(f"Successfully merged into {output_file}")
|
|
|
+ print(f"成功合并到 {output_file}")
|
|
|
|
|
|
def add_executable_permission(file_path):
|
|
|
"""
|
|
|
添加可执行权限(适用于 macOS 和 Linux)
|
|
|
"""
|
|
|
- print(f"Adding executable permission to {file_path}")
|
|
|
+ print(f"正在添加可执行权限到 {file_path}")
|
|
|
st = os.stat(file_path)
|
|
|
os.chmod(file_path, st.st_mode | stat.S_IEXEC)
|
|
|
- print(f"Executable permission added to {file_path}")
|
|
|
+ print(f"已添加可执行权限到 {file_path}")
|
|
|
|
|
|
def rename_file(original_path, new_name):
|
|
|
"""
|
|
|
重命名文件
|
|
|
"""
|
|
|
- new_path = os.path.join(os.path.dirname(original_path), new_name)
|
|
|
- os.rename(original_path, new_path)
|
|
|
- print(f"Renamed {original_path} to {new_path}")
|
|
|
+ new_path = os.path.join(ASSETS_DIR, new_name)
|
|
|
+ shutil.move(original_path, new_path)
|
|
|
+ print(f"已重命名 {original_path} 为 {new_path}")
|
|
|
return new_path
|
|
|
|
|
|
-def construct_new_name(service_name, arch, ext):
|
|
|
- """
|
|
|
- 构建新的文件名,符合 ClashName 的命名格式
|
|
|
- """
|
|
|
- platform_name, _ = get_platform_arch()
|
|
|
- if "core-service" in service_name:
|
|
|
- new_name = f"ccore-service-{platform_name}-{arch}{ext}"
|
|
|
- else:
|
|
|
- new_name = f"ccore-{platform_name}-{arch}{ext}"
|
|
|
- return new_name
|
|
|
-
|
|
|
def main():
|
|
|
# 获取下载链接和文件名
|
|
|
download_urls = get_download_urls()
|
|
|
|
|
|
- # 存储架构对应的下载路径(仅适用于 macOS 合并)
|
|
|
- downloads = {
|
|
|
- 'mihomo': {'arm64': '', 'x86_64': ''},
|
|
|
- 'core-service': {'arm64': '', 'x86_64': ''}
|
|
|
- }
|
|
|
-
|
|
|
- for file_name, url, dir_path, arch in download_urls:
|
|
|
- # 下载文件
|
|
|
- download_path = os.path.join(dir_path, file_name)
|
|
|
- download_file(url, download_path)
|
|
|
-
|
|
|
- # 确定服务名称
|
|
|
- if 'core-service' in file_name:
|
|
|
- service_name = 'core-service'
|
|
|
- elif 'mihomo' in file_name:
|
|
|
- service_name = 'mihomo'
|
|
|
- else:
|
|
|
- raise ValueError(f"Unknown service name in file: {file_name}")
|
|
|
-
|
|
|
- # 构建输出路径
|
|
|
- output_file = os.path.join(dir_path, service_name + '-' + arch)
|
|
|
-
|
|
|
- # 解压文件
|
|
|
- if file_name.endswith('.gz'):
|
|
|
- extract_gz_file(download_path, output_file)
|
|
|
- elif file_name.endswith('.zip'):
|
|
|
- extract_zip_file(download_path, dir_path)
|
|
|
-
|
|
|
- # 如果是 macOS,记录不同架构的文件路径
|
|
|
+ # 创建临时目录
|
|
|
+ with tempfile.TemporaryDirectory() as temp_dir:
|
|
|
+ # 存储架构对应的下载路径(仅适用于 macOS 合并)
|
|
|
+ downloads = {
|
|
|
+ 'mihomo': {'arm64': '', 'x86_64': ''},
|
|
|
+ 'core-service': {'arm64': '', 'x86_64': ''}
|
|
|
+ }
|
|
|
+
|
|
|
+ for file_name, url, arch in download_urls:
|
|
|
+ # 下载文件
|
|
|
+ download_path = os.path.join(temp_dir, file_name)
|
|
|
+ download_file(url, download_path)
|
|
|
+
|
|
|
+ # 确定服务名称
|
|
|
+ if 'core-service' in file_name:
|
|
|
+ service_name = 'core-service'
|
|
|
+ elif 'mihomo' in file_name:
|
|
|
+ service_name = 'mihomo'
|
|
|
+ else:
|
|
|
+ raise ValueError(f"未知的服务名称: {file_name}")
|
|
|
+
|
|
|
+ # 构建输出路径
|
|
|
+ output_file = os.path.join(temp_dir, service_name + '-' + arch)
|
|
|
+
|
|
|
+ # 解压文件
|
|
|
+ if file_name.endswith('.gz'):
|
|
|
+ extract_gz_file(download_path, output_file)
|
|
|
+ elif file_name.endswith('.zip'):
|
|
|
+ extract_zip_file(download_path, temp_dir)
|
|
|
+
|
|
|
+ # 如果是 macOS,记录不同架构的文件路径
|
|
|
+ if SYSTEM == 'darwin':
|
|
|
+ downloads[service_name][arch] = output_file
|
|
|
+
|
|
|
+ # 合并 macOS 下的二进制文件或直接重命名
|
|
|
if SYSTEM == 'darwin':
|
|
|
- downloads[service_name][arch] = output_file
|
|
|
+ for service in ['mihomo', 'core-service']:
|
|
|
+ arm_file = downloads[service]['arm64']
|
|
|
+ x86_file = downloads[service]['x86_64']
|
|
|
+ if arm_file and x86_file:
|
|
|
+ merged_output = os.path.join(temp_dir, service)
|
|
|
+ merge_binaries(arm_file, x86_file, merged_output)
|
|
|
+ add_executable_permission(merged_output)
|
|
|
+
|
|
|
+ # 如果是合并改名,core-{SYSTEM}
|
|
|
+ # service-{SYSTEM}
|
|
|
+ # 其他平台不变
|
|
|
+ new_name = f"core-{SYSTEM}" if service == 'mihomo' else f"service-{SYSTEM}"
|
|
|
+ rename_file(merged_output, new_name)
|
|
|
else:
|
|
|
- # 如果不是 macOS,直接重命名并添加执行权限
|
|
|
- ext = '.gz' if file_name.endswith('.gz') else '.zip'
|
|
|
- new_name = construct_new_name(service_name, arch, ext)
|
|
|
- renamed_output = rename_file(output_file, new_name)
|
|
|
- add_executable_permission(renamed_output)
|
|
|
-
|
|
|
- # 合并 macOS 下的二进制文件
|
|
|
- if SYSTEM == 'darwin':
|
|
|
- for service in ['mihomo', 'core-service']:
|
|
|
- arm_file = downloads[service]['arm64']
|
|
|
- x86_file = downloads[service]['x86_64']
|
|
|
- if arm_file and x86_file:
|
|
|
- # 构建新的名称
|
|
|
- ext = '.gz' if 'gz' in arm_file else '.zip'
|
|
|
- merged_output = os.path.join(ASSETS_DIR, f'ccore-{service}-darwin-universal')
|
|
|
- merge_binaries(arm_file, x86_file, merged_output)
|
|
|
- add_executable_permission(merged_output)
|
|
|
+ # 对于 Linux 和 Windows,直接重命名最新下载的文件
|
|
|
+ for service in ['mihomo', 'core-service']:
|
|
|
+ latest_file = max(
|
|
|
+ [f for f in os.listdir(temp_dir) if service in f],
|
|
|
+ key=lambda x: os.path.getmtime(os.path.join(temp_dir, x))
|
|
|
+ )
|
|
|
+ new_name = f"core-{SYSTEM}-{platform.machine()}" if service == 'mihomo' else f"service-{SYSTEM}-{platform.machine()}"
|
|
|
+ if SYSTEM == 'windows':
|
|
|
+ new_name += '.exe'
|
|
|
+ rename_file(os.path.join(temp_dir, latest_file), new_name)
|
|
|
+ if SYSTEM == 'linux':
|
|
|
+ add_executable_permission(os.path.join(ASSETS_DIR, new_name))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
main()
|