|
@@ -5,37 +5,68 @@ import gzip
|
|
|
import shutil
|
|
|
from zipfile import ZipFile
|
|
|
import stat
|
|
|
+import argparse
|
|
|
+import subprocess
|
|
|
|
|
|
# 定义常量
|
|
|
-BASE_URL = 'https://github.com/MetaCubeX/mihomo/releases/download'
|
|
|
-VERSION = 'v1.18.8'
|
|
|
+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'
|
|
|
+MIHOMO_VERSION = 'v1.18.8' # 根据实际版本修改
|
|
|
+CORE_SERVICE_VERSION = 'test_2023.11.22_09-33'
|
|
|
ASSETS_DIR = './assets/bin'
|
|
|
SYSTEM = platform.system().lower()
|
|
|
-ARCH = platform.machine()
|
|
|
+
|
|
|
+# ClashName.platform 和 ClashName.arch 是动态生成的
|
|
|
+def get_platform_arch():
|
|
|
+ return SYSTEM, platform.machine()
|
|
|
|
|
|
# 如果目录不存在,创建下载目录
|
|
|
if not os.path.exists(ASSETS_DIR):
|
|
|
os.makedirs(ASSETS_DIR)
|
|
|
|
|
|
-def get_download_url():
|
|
|
+def get_download_urls():
|
|
|
"""
|
|
|
- 根据系统和架构生成下载链接
|
|
|
+ 根据系统生成 mihomo 和 core-service 的下载链接,分别下载 arm64 和 x86_64 架构
|
|
|
"""
|
|
|
- if SYSTEM == 'darwin' and ARCH == 'x86_64':
|
|
|
- file_name = f'mihomo-darwin-amd64-{VERSION}.gz'
|
|
|
- elif SYSTEM == 'darwin' and ARCH == 'arm64':
|
|
|
- file_name = f'mihomo-darwin-arm64-{VERSION}.gz'
|
|
|
- elif SYSTEM == 'linux' and ARCH == 'x86_64':
|
|
|
- file_name = f'mihomo-linux-amd64-{VERSION}.gz'
|
|
|
- elif SYSTEM == 'linux' and ARCH == 'arm64':
|
|
|
- file_name = f'mihomo-linux-arm64-{VERSION}.gz'
|
|
|
- elif SYSTEM == 'windows' and ARCH == 'x86_64':
|
|
|
- file_name = f'mihomo-windows-amd64-{VERSION}.zip'
|
|
|
- else:
|
|
|
- raise ValueError(f"Unsupported system/architecture: {SYSTEM} {ARCH}")
|
|
|
-
|
|
|
- return f"{BASE_URL}/{VERSION}/{file_name}", file_name
|
|
|
-
|
|
|
+ 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 架构
|
|
|
+ if SYSTEM == 'darwin':
|
|
|
+ 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'
|
|
|
+ ))
|
|
|
+ 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'
|
|
|
+ ))
|
|
|
+ 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'
|
|
|
+ ))
|
|
|
+ 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'
|
|
|
+ ))
|
|
|
+
|
|
|
+ return download_urls
|
|
|
|
|
|
def download_file(url, output_path):
|
|
|
"""
|
|
@@ -50,7 +81,6 @@ def download_file(url, output_path):
|
|
|
else:
|
|
|
print(f"Failed to download {url}, status code: {response.status_code}")
|
|
|
|
|
|
-
|
|
|
def extract_gz_file(file_path, output_path):
|
|
|
"""
|
|
|
解压 .gz 文件
|
|
@@ -61,7 +91,6 @@ def extract_gz_file(file_path, output_path):
|
|
|
shutil.copyfileobj(f_in, f_out)
|
|
|
print(f"Extracted to {output_path}")
|
|
|
|
|
|
-
|
|
|
def extract_zip_file(file_path, output_dir):
|
|
|
"""
|
|
|
解压 .zip 文件
|
|
@@ -71,43 +100,96 @@ def extract_zip_file(file_path, output_dir):
|
|
|
zip_ref.extractall(output_dir)
|
|
|
print(f"Extracted to {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}")
|
|
|
+ subprocess.run(['lipo', '-create', '-output', output_file, arm_file, x86_file], check=True)
|
|
|
+ print(f"Successfully merged into {output_file}")
|
|
|
|
|
|
def add_executable_permission(file_path):
|
|
|
"""
|
|
|
添加可执行权限(适用于 macOS 和 Linux)
|
|
|
"""
|
|
|
- if SYSTEM != 'windows':
|
|
|
- print(f"Adding executable permission to {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"Adding executable permission to {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}")
|
|
|
|
|
|
+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}")
|
|
|
+ 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():
|
|
|
# 获取下载链接和文件名
|
|
|
- url, file_name = get_download_url()
|
|
|
-
|
|
|
- # 下载文件
|
|
|
- download_path = os.path.join(ASSETS_DIR, file_name)
|
|
|
- download_file(url, download_path)
|
|
|
-
|
|
|
- # 构建输出路径和重命名文件
|
|
|
- service_name = f'ccore-{SYSTEM}-{ARCH}'
|
|
|
- output_file = os.path.join(ASSETS_DIR, service_name)
|
|
|
-
|
|
|
- # 解压文件并重命名
|
|
|
- if file_name.endswith('.gz'):
|
|
|
- extract_gz_file(download_path, output_file)
|
|
|
- elif file_name.endswith('.zip'):
|
|
|
- extract_zip_file(download_path, ASSETS_DIR)
|
|
|
-
|
|
|
- # 添加可执行权限
|
|
|
- add_executable_permission(output_file)
|
|
|
-
|
|
|
- # 删除下载的压缩文件
|
|
|
- if os.path.exists(download_path):
|
|
|
- os.remove(download_path)
|
|
|
- print(f"Deleted temp file: {download_path}")
|
|
|
+ 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,记录不同架构的文件路径
|
|
|
+ if SYSTEM == 'darwin':
|
|
|
+ downloads[service_name][arch] = output_file
|
|
|
+ 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)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
main()
|