fix
This commit is contained in:
286
scripts/setup_embedded_python.py
Normal file
286
scripts/setup_embedded_python.py
Normal file
@@ -0,0 +1,286 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
设置嵌入式Python环境
|
||||
下载Python嵌入式版本并配置依赖
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import urllib.request
|
||||
import zipfile
|
||||
import subprocess
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
def get_project_root():
|
||||
"""获取项目根目录"""
|
||||
return Path(__file__).parent.parent
|
||||
|
||||
def download_embedded_python(project_root):
|
||||
"""下载Python嵌入式版本"""
|
||||
print("📦 Downloading Python embedded version...")
|
||||
|
||||
# Python 3.11.0 嵌入式版本
|
||||
python_url = "https://www.python.org/ftp/python/3.11.0/python-3.11.0-embed-amd64.zip"
|
||||
embed_dir = project_root / "src-tauri" / "python-embed"
|
||||
zip_file = embed_dir / "python-embed.zip"
|
||||
|
||||
# 创建目录
|
||||
embed_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 下载文件
|
||||
if not zip_file.exists():
|
||||
print(f"Downloading from {python_url}...")
|
||||
urllib.request.urlretrieve(python_url, zip_file)
|
||||
print("✅ Download completed")
|
||||
else:
|
||||
print("✅ Python embed zip already exists")
|
||||
|
||||
# 解压文件
|
||||
print("📂 Extracting Python...")
|
||||
with zipfile.ZipFile(zip_file, 'r') as zip_ref:
|
||||
zip_ref.extractall(embed_dir)
|
||||
|
||||
# 删除zip文件
|
||||
zip_file.unlink()
|
||||
|
||||
return embed_dir
|
||||
|
||||
def setup_pip(embed_dir):
|
||||
"""设置pip"""
|
||||
print("🔧 Setting up pip...")
|
||||
|
||||
python_exe = embed_dir / "python.exe"
|
||||
|
||||
# 下载get-pip.py
|
||||
get_pip_url = "https://bootstrap.pypa.io/get-pip.py"
|
||||
get_pip_file = embed_dir / "get-pip.py"
|
||||
|
||||
if not get_pip_file.exists():
|
||||
print("Downloading get-pip.py...")
|
||||
urllib.request.urlretrieve(get_pip_url, get_pip_file)
|
||||
|
||||
# 修改python311._pth文件以启用site-packages
|
||||
pth_file = embed_dir / "python311._pth"
|
||||
if pth_file.exists():
|
||||
content = pth_file.read_text()
|
||||
if "#import site" in content:
|
||||
content = content.replace("#import site", "import site")
|
||||
pth_file.write_text(content)
|
||||
print("✅ Enabled site-packages")
|
||||
|
||||
# 安装pip
|
||||
try:
|
||||
result = subprocess.run([
|
||||
str(python_exe), str(get_pip_file)
|
||||
], capture_output=True, text=True, cwd=embed_dir)
|
||||
|
||||
if result.returncode == 0:
|
||||
print("✅ pip installed successfully")
|
||||
else:
|
||||
print(f"❌ pip installation failed: {result.stderr}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"❌ Error installing pip: {e}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def install_dependencies(embed_dir):
|
||||
"""安装Python依赖"""
|
||||
print("📦 Installing Python dependencies...")
|
||||
|
||||
python_exe = embed_dir / "python.exe"
|
||||
|
||||
# 基础依赖
|
||||
dependencies = [
|
||||
"requests",
|
||||
"Pillow",
|
||||
"certifi",
|
||||
"urllib3",
|
||||
"charset-normalizer",
|
||||
"idna",
|
||||
# 如果需要其他依赖,在这里添加
|
||||
# "numpy",
|
||||
# "opencv-python-headless",
|
||||
# "pandas",
|
||||
]
|
||||
|
||||
for dep in dependencies:
|
||||
print(f"Installing {dep}...")
|
||||
try:
|
||||
result = subprocess.run([
|
||||
str(python_exe), "-m", "pip", "install", dep
|
||||
], capture_output=True, text=True, cwd=embed_dir)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"✅ {dep} installed")
|
||||
else:
|
||||
print(f"❌ Failed to install {dep}: {result.stderr}")
|
||||
except Exception as e:
|
||||
print(f"❌ Error installing {dep}: {e}")
|
||||
|
||||
def copy_python_core(project_root, embed_dir):
|
||||
"""复制python_core模块到嵌入式Python"""
|
||||
print("📋 Copying python_core module...")
|
||||
|
||||
source_dir = project_root / "python_core"
|
||||
target_dir = embed_dir / "python_core"
|
||||
|
||||
if source_dir.exists():
|
||||
if target_dir.exists():
|
||||
shutil.rmtree(target_dir)
|
||||
|
||||
shutil.copytree(source_dir, target_dir)
|
||||
print("✅ python_core module copied")
|
||||
else:
|
||||
print("❌ python_core directory not found")
|
||||
|
||||
def create_launcher_script(embed_dir):
|
||||
"""创建启动脚本"""
|
||||
print("📝 Creating launcher script...")
|
||||
|
||||
launcher_content = '''@echo off
|
||||
REM Python Core Launcher Script
|
||||
set PYTHON_DIR=%~dp0
|
||||
set PYTHONPATH=%PYTHON_DIR%;%PYTHON_DIR%\\python_core
|
||||
"%PYTHON_DIR%\\python.exe" -m python_core.main %*
|
||||
'''
|
||||
|
||||
launcher_file = embed_dir / "python-core.bat"
|
||||
launcher_file.write_text(launcher_content)
|
||||
print("✅ Launcher script created")
|
||||
|
||||
def test_embedded_python(embed_dir):
|
||||
"""测试嵌入式Python"""
|
||||
print("🧪 Testing embedded Python...")
|
||||
|
||||
python_exe = embed_dir / "python.exe"
|
||||
|
||||
# 测试Python版本
|
||||
try:
|
||||
result = subprocess.run([
|
||||
str(python_exe), "--version"
|
||||
], capture_output=True, text=True)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"✅ Python version: {result.stdout.strip()}")
|
||||
else:
|
||||
print(f"❌ Python test failed: {result.stderr}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"❌ Error testing Python: {e}")
|
||||
return False
|
||||
|
||||
# 测试依赖
|
||||
test_imports = ["requests", "PIL", "json"]
|
||||
for module in test_imports:
|
||||
try:
|
||||
result = subprocess.run([
|
||||
str(python_exe), "-c", f"import {module}; print('{module} OK')"
|
||||
], capture_output=True, text=True)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"✅ {module}: {result.stdout.strip()}")
|
||||
else:
|
||||
print(f"❌ {module} test failed: {result.stderr}")
|
||||
except Exception as e:
|
||||
print(f"❌ Error testing {module}: {e}")
|
||||
|
||||
# 测试python_core模块
|
||||
try:
|
||||
result = subprocess.run([
|
||||
str(python_exe), "-c", "import python_core; print('python_core OK')"
|
||||
], capture_output=True, text=True, cwd=embed_dir)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"✅ python_core: {result.stdout.strip()}")
|
||||
else:
|
||||
print(f"❌ python_core test failed: {result.stderr}")
|
||||
except Exception as e:
|
||||
print(f"❌ Error testing python_core: {e}")
|
||||
|
||||
return True
|
||||
|
||||
def update_tauri_config(project_root, embed_dir):
|
||||
"""更新Tauri配置"""
|
||||
print("⚙️ Updating Tauri configuration...")
|
||||
|
||||
import json
|
||||
|
||||
config_file = project_root / "src-tauri" / "tauri.conf.json"
|
||||
|
||||
if config_file.exists():
|
||||
with open(config_file, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
|
||||
# 添加Python嵌入式目录到资源
|
||||
if 'bundle' not in config:
|
||||
config['bundle'] = {}
|
||||
|
||||
if 'resources' not in config['bundle']:
|
||||
config['bundle']['resources'] = []
|
||||
|
||||
python_resource = "python-embed/**"
|
||||
if python_resource not in config['bundle']['resources']:
|
||||
config['bundle']['resources'].append(python_resource)
|
||||
|
||||
# 写回配置
|
||||
with open(config_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(config, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print("✅ Tauri configuration updated")
|
||||
else:
|
||||
print("❌ Tauri config file not found")
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("🚀 Setting up embedded Python for MixVideo V2...")
|
||||
print("=" * 50)
|
||||
|
||||
project_root = get_project_root()
|
||||
print(f"Project root: {project_root}")
|
||||
|
||||
try:
|
||||
# 1. 下载嵌入式Python
|
||||
embed_dir = download_embedded_python(project_root)
|
||||
|
||||
# 2. 设置pip
|
||||
if not setup_pip(embed_dir):
|
||||
print("❌ Failed to setup pip")
|
||||
return 1
|
||||
|
||||
# 3. 安装依赖
|
||||
install_dependencies(embed_dir)
|
||||
|
||||
# 4. 复制python_core模块
|
||||
copy_python_core(project_root, embed_dir)
|
||||
|
||||
# 5. 创建启动脚本
|
||||
create_launcher_script(embed_dir)
|
||||
|
||||
# 6. 测试
|
||||
if not test_embedded_python(embed_dir):
|
||||
print("❌ Embedded Python test failed")
|
||||
return 1
|
||||
|
||||
# 7. 更新Tauri配置
|
||||
update_tauri_config(project_root, embed_dir)
|
||||
|
||||
print("\n🎉 Embedded Python setup completed successfully!")
|
||||
print(f"📁 Python location: {embed_dir}")
|
||||
print("\n📋 Next steps:")
|
||||
print("1. Test the embedded Python:")
|
||||
print(f" {embed_dir}\\python.exe --version")
|
||||
print("2. Build your Tauri app:")
|
||||
print(" cargo tauri build")
|
||||
print("3. The Python environment will be bundled with your app")
|
||||
|
||||
return 0
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Setup failed: {e}")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user