#!/bin/bash # 打包脚本:将配置编辑器项目打包成 deb 包 set -e # 遇到错误时退出 # ==================== 配置区域 ==================== APP_NAME="config-editor" APP_VERSION="1.3" APP_DESCRIPTION="CE编辑器" MAINTAINER="hjy " ARCHITECTURE="amd64" DEPENDENCIES="python3, python3-venv, python3-pip" PYTHON_VERSION="3.8" VENV_PATH="/opt/$APP_NAME/venv" APP_INSTALL_PATH="/opt/$APP_NAME" # ================================================= echo "========================================" echo "开始构建 $APP_NAME (版本 $APP_VERSION)" echo "========================================" echo "将使用虚拟环境: $VENV_PATH" # 1. 清理之前的构建 echo "1. 清理之前的构建..." rm -rf build/ dist/ deb_dist/ *.egg-info/ 2>/dev/null || true rm -rf /tmp/$APP_NAME-* 2>/dev/null || true # 2. 创建构建目录结构 echo "2. 创建构建目录结构..." BUILD_ROOT="/tmp/${APP_NAME}-${APP_VERSION}" DEBIAN_DIR="$BUILD_ROOT/DEBIAN" APP_DIR="$BUILD_ROOT$APP_INSTALL_PATH" BIN_DIR="$BUILD_ROOT/usr/bin" DESKTOP_DIR="$BUILD_ROOT/usr/share/applications" ICON_DIR="$BUILD_ROOT/usr/share/icons/hicolor" MIME_DIR="$BUILD_ROOT/usr/share/mime/packages" VAR_LIB_DIR="$BUILD_ROOT/var/lib/$APP_NAME" # 清理并重新创建目录 rm -rf "$BUILD_ROOT" mkdir -p "$DEBIAN_DIR" mkdir -p "$APP_DIR" mkdir -p "$BIN_DIR" mkdir -p "$DESKTOP_DIR" mkdir -p "$ICON_DIR/48x48/apps" mkdir -p "$ICON_DIR/64x64/apps" mkdir -p "$ICON_DIR/128x128/apps" mkdir -p "$MIME_DIR" mkdir -p "$VAR_LIB_DIR" # 3. 复制项目文件 echo "3. 复制项目文件..." cp -r *.py "$APP_DIR/" cp -r login/ "$APP_DIR/" cp -r requirements.txt "$APP_DIR/" # 清理不必要的文件 find "$APP_DIR" -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true find "$APP_DIR" -name "*.pyc" -delete 2>/dev/null || true find "$APP_DIR" -name ".DS_Store" -delete 2>/dev/null || true # 4. 创建启动脚本(使用虚拟环境中的 Python) echo "4. 创建启动脚本..." cat > "$BIN_DIR/$APP_NAME" << EOF #!/bin/bash # 配置编辑器启动脚本(使用虚拟环境) # 应用程序安装路径 APP_DIR="$APP_INSTALL_PATH" VENV_PATH="$VENV_PATH" # 检查虚拟环境是否存在 if [ ! -f "\$VENV_PATH/bin/activate" ]; then echo "错误: 虚拟环境不存在。请重新安装应用程序。" exit 1 fi # 激活虚拟环境并运行程序 cd "\$APP_DIR" source "\$VENV_PATH/bin/activate" exec python main.py "\$@" EOF chmod +x "$BIN_DIR/$APP_NAME" # 5. 创建桌面入口文件 echo "5. 创建桌面入口文件..." cat > "$DESKTOP_DIR/$APP_NAME.desktop" << EOF [Desktop Entry] Name=Config Editor Name[zh_CN]=配置编辑器 Comment=$APP_DESCRIPTION Comment[zh_CN]=用于管理和编辑配置文件 Exec=$APP_NAME Icon=$APP_NAME Terminal=false Type=Application Categories=Development;Utility; StartupNotify=true Keywords=config;editor;settings;configuration; MimeType=application/x-python; EOF # 6. 创建图标(如果没有提供图标,则生成一个简单的) echo "6. 创建图标..." if [ -f "logo.png" ]; then # 如果有现有图标,使用它 cp logo.png "$ICON_DIR/48x48/apps/$APP_NAME.png" cp logo.png "$ICON_DIR/64x64/apps/$APP_NAME.png" cp logo.png "$ICON_DIR/128x128/apps/$APP_NAME.png" else # 如果没有图标,创建一个简单的占位符 echo "未找到图标文件,创建简单图标..." # 使用 ImageMagick 创建图标(如果可用) if command -v convert &> /dev/null; then # 创建 48x48 图标 convert -size 48x48 xc:#2196F3 \ -fill white -pointsize 24 -gravity center -annotate 0 "CE" \ "$ICON_DIR/48x48/apps/$APP_NAME.png" # 创建 64x64 图标 convert -size 64x64 xc:#2196F3 \ -fill white -pointsize 32 -gravity center -annotate 0 "CE" \ "$ICON_DIR/64x64/apps/$APP_NAME.png" # 创建 128x128 图标 convert -size 128x128 xc:#2196F3 \ -fill white -pointsize 48 -gravity center -annotate 0 "CE" \ "$ICON_DIR/128x128/apps/$APP_NAME.png" else echo "警告: 未安装 ImageMagick (convert),跳过图标生成。" fi fi # 7. 创建 DEBIAN 控制文件 echo "7. 创建 DEBIAN 控制文件..." cat > "$DEBIAN_DIR/control" << EOF Package: $APP_NAME Version: $APP_VERSION Section: utils Priority: optional Architecture: $ARCHITECTURE Depends: $DEPENDENCIES Maintainer: $MAINTAINER Description: $APP_DESCRIPTION 配置编辑器是一个功能强大的工具,用于编辑和管理各种配置文件。 支持以下功能: * 智能解析配置文件 * 分组显示配置项 * 拖拽重新排序 * 加密配置项保护 * 会话超时锁定 * 用户认证系统 * 规则管理 * 在虚拟环境中运行,避免依赖冲突 Homepage: https://github.com/yourusername/config-editor EOF # 8. 创建安装后脚本(创建虚拟环境) echo "8. 创建安装后脚本..." cat > "$DEBIAN_DIR/postinst" << EOF #!/bin/bash # 安装后脚本 - 创建虚拟环境并安装依赖 set -e # 更新桌面数据库 if [ -d /usr/share/applications ]; then update-desktop-database /usr/share/applications || true fi # 更新图标缓存 if command -v gtk-update-icon-cache &> /dev/null; then gtk-update-icon-cache -f -t /usr/share/icons/hicolor || true fi # 设置文件权限 chmod 755 $APP_INSTALL_PATH/*.py chmod 755 $APP_INSTALL_PATH/login/*.py chmod 755 /usr/bin/$APP_NAME # 创建虚拟环境目录 echo "创建虚拟环境目录..." mkdir -p "$VENV_PATH" # 检查 Python3 是否可用 if ! command -v python3 &> /dev/null; then echo "错误: Python3 未安装。请安装 python3。" exit 1 fi # 创建虚拟环境 echo "创建 Python 虚拟环境..." python3 -m venv "$VENV_PATH" --system-site-packages # 激活虚拟环境并安装依赖 echo "在虚拟环境中安装依赖..." source "$VENV_PATH/bin/activate" # 升级 pip pip install --upgrade pip # 安装依赖 if [ -f "$APP_INSTALL_PATH/requirements.txt" ]; then echo "从 requirements.txt 安装依赖..." pip install -r "$APP_INSTALL_PATH/requirements.txt" else echo "安装 PyQt6..." pip install PyQt6 fi # 验证安装 if python3 -c "import PyQt6; print('PyQt6 安装成功')" 2>/dev/null; then echo "✅ 虚拟环境设置成功" else echo "❌ 虚拟环境设置失败,尝试重新安装 PyQt6..." pip install --force-reinstall PyQt6 fi # 确保规则文件可写 touch "$APP_INSTALL_PATH/config_editor_rules.json" 2>/dev/null || true chmod 666 "$APP_INSTALL_PATH/config_editor_rules.json" 2>/dev/null || true # 创建用户数据目录 mkdir -p "/var/lib/$APP_NAME" chmod 755 "/var/lib/$APP_NAME" echo "安装完成!您可以通过以下方式启动配置编辑器:" echo "1. 在应用程序菜单中搜索 'Config Editor'" echo "2. 在终端中运行: $APP_NAME" echo "3. 首次运行需要设置配置文件路径" echo "" echo "虚拟环境位置: $VENV_PATH" echo "应用程序位置: $APP_INSTALL_PATH" EOF chmod 755 "$DEBIAN_DIR/postinst" # 9. 创建卸载前脚本 echo "9. 创建卸载前脚本..." cat > "$DEBIAN_DIR/prerm" << EOF #!/bin/bash # 卸载前脚本 set -e # 检查程序是否正在运行 if pgrep -f "$APP_NAME" > /dev/null; then echo "正在停止运行中的配置编辑器..." pkill -f "$APP_NAME" || true sleep 2 fi EOF chmod 755 "$DEBIAN_DIR/prerm" # 10. 创建卸载后脚本 echo "10. 创建卸载后脚本..." cat > "$DEBIAN_DIR/postrm" << EOF #!/bin/bash # 卸载后脚本 set -e # 更新桌面数据库 if [ -d /usr/share/applications ]; then update-desktop-database /usr/share/applications || true fi # 更新图标缓存 if command -v gtk-update-icon-cache &> /dev/null; then gtk-update-icon-cache -f -t /usr/share/icons/hicolor || true fi # 删除虚拟环境(如果存在) if [ -d "$VENV_PATH" ]; then echo "删除虚拟环境..." rm -rf "$VENV_PATH" fi # 删除应用程序目录(如果存在) if [ -d "$APP_INSTALL_PATH" ]; then echo "删除应用程序目录..." rm -rf "$APP_INSTALL_PATH" fi # 删除系统数据目录 if [ -d "/var/lib/$APP_NAME" ]; then echo "删除系统数据目录..." rm -rf "/var/lib/$APP_NAME" fi # 删除用户数据(可选) echo "是否要删除用户数据?(n/yes)" echo "这包括:" echo " - ~/.config_editor/ 目录" echo " - ~/.config/config-editor/ 目录" read -p "输入 'yes' 确认删除,其他跳过: " choice if [ "\$choice" = "yes" ]; then rm -rf ~/.config_editor 2>/dev/null || true rm -rf ~/.config/config-editor 2>/dev/null || true echo "用户数据已删除。" else echo "用户数据保留。" fi EOF chmod 755 "$DEBIAN_DIR/postrm" # 11. 创建版权文件 echo "11. 创建版权文件..." cat > "$DEBIAN_DIR/copyright" << EOF Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: $APP_NAME Source: https://github.com/yourusername/config-editor Files: * Copyright: $(date +%Y) Your Name License: MIT License: MIT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. EOF # 12. 设置文件权限 echo "12. 设置文件权限..." find "$BUILD_ROOT" -type f -exec chmod 644 {} \; find "$BUILD_ROOT" -type d -exec chmod 755 {} \; chmod -R 755 "$DEBIAN_DIR"/* 2>/dev/null || true chmod 755 "$BIN_DIR/$APP_NAME" chmod 755 "$APP_DIR"/*.py 2>/dev/null || true chmod 755 "$APP_DIR"/login/*.py 2>/dev/null || true # 13. 创建虚拟环境占位符目录 echo "13. 创建虚拟环境占位符目录..." mkdir -p "$BUILD_ROOT$VENV_PATH" touch "$BUILD_ROOT$VENV_PATH/.placeholder" echo "这是一个虚拟环境占位符,将在安装时创建实际的虚拟环境。" > "$BUILD_ROOT$VENV_PATH/README.txt" # 14. 创建配置文件示例 echo "14. 创建配置文件示例..." cat > "$VAR_LIB_DIR/config_example.py" << 'EOF' """配置文件示例""" # 数据库配置 DATABASE_HOST = "localhost" DATABASE_PORT = 3306 DATABASE_USER = "admin" DATABASE_PASSWORD = "secret_password" DATABASE_NAME = "myapp_db" # 应用配置 APP_NAME = "My Application" DEBUG_MODE = False LOG_LEVEL = "INFO" MAX_CONNECTIONS = 100 # API配置 API_KEY = "your_api_key_here" API_TIMEOUT = 30 API_RETRIES = 3 # 服务配置 ENABLE_CACHE = True CACHE_SIZE = 1024 ENABLE_SSL = True # 邮件配置 SMTP_SERVER = "smtp.example.com" SMTP_PORT = 587 EMAIL_FROM = "noreply@example.com" # 安全配置 SESSION_TIMEOUT = 3600 PASSWORD_MIN_LENGTH = 8 ALLOWED_HOSTS = ["localhost", "127.0.0.1"] # 第三方服务配置 STRIPE_API_KEY = "sk_test_1234567890" AWS_ACCESS_KEY = "AKIAIOSFODNN7EXAMPLE" AWS_SECRET_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" EOF # 15. 创建虚拟环境初始化脚本 echo "15. 创建虚拟环境初始化脚本..." cat > "$APP_DIR/init_venv.sh" << EOF #!/bin/bash # 虚拟环境初始化脚本 VENV_PATH="$VENV_PATH" APP_DIR="$APP_INSTALL_PATH" echo "初始化虚拟环境..." echo "虚拟环境路径: \$VENV_PATH" echo "应用路径: \$APP_DIR" # 检查是否已存在虚拟环境 if [ -f "\$VENV_PATH/bin/activate" ]; then echo "虚拟环境已存在,重新创建吗?(y/N)" read -r response if [[ ! \$response =~ ^[Yy]$ ]]; then echo "操作取消。" exit 0 fi rm -rf "\$VENV_PATH" fi # 创建虚拟环境 echo "创建新的虚拟环境..." python3 -m venv "\$VENV_PATH" --system-site-packages # 激活虚拟环境 source "\$VENV_PATH/bin/activate" # 升级pip pip install --upgrade pip # 安装依赖 if [ -f "\$APP_DIR/requirements.txt" ]; then echo "安装依赖..." pip install -r "\$APP_DIR/requirements.txt" else echo "安装 PyQt6..." pip install PyQt6 fi # 验证安装 if python3 -c "import PyQt6" &> /dev/null; then echo "✅ 虚拟环境初始化成功!" echo "" echo "使用方法:" echo "1. 激活虚拟环境: source \$VENV_PATH/bin/activate" echo "2. 运行程序: cd \$APP_DIR && python main.py" echo "3. 退出虚拟环境: deactivate" else echo "❌ 虚拟环境初始化失败!" exit 1 fi EOF chmod +x "$APP_DIR/init_venv.sh" # 16. 创建虚拟环境管理脚本 echo "16. 创建虚拟环境管理脚本..." cat > "$APP_DIR/manage_venv.py" << 'EOF' #!/usr/bin/env python3 """ 虚拟环境管理脚本 用于检查和维护配置编辑器的虚拟环境 """ import os import sys import subprocess import venv VENV_PATH = "/opt/config-editor/venv" APP_DIR = "/opt/config-editor" def check_venv(): """检查虚拟环境状态""" print("检查虚拟环境状态...") print(f"虚拟环境路径: {VENV_PATH}") # 检查虚拟环境是否存在 if not os.path.exists(os.path.join(VENV_PATH, "bin", "activate")): print("❌ 虚拟环境不存在") return False # 检查 Python 是否可用 venv_python = os.path.join(VENV_PATH, "bin", "python3") if not os.path.exists(venv_python): print("❌ 虚拟环境中的 Python 不存在") return False # 检查 PyQt6 是否已安装 try: result = subprocess.run( [venv_python, "-c", "import PyQt6; print('✅ PyQt6 已安装')"], capture_output=True, text=True ) if result.returncode == 0: print(result.stdout.strip()) return True else: print("❌ PyQt6 未安装或有问题") print(f"错误信息: {result.stderr}") return False except Exception as e: print(f"❌ 检查时出错: {e}") return False def recreate_venv(): """重新创建虚拟环境""" print("重新创建虚拟环境...") # 删除现有虚拟环境 if os.path.exists(VENV_PATH): print(f"删除现有虚拟环境: {VENV_PATH}") subprocess.run(["rm", "-rf", VENV_PATH], check=False) # 创建新虚拟环境 print("创建新虚拟环境...") try: venv.create(VENV_PATH, with_pip=True, system_site_packages=True) except Exception as e: print(f"❌ 创建虚拟环境失败: {e}") return False # 安装依赖 print("安装依赖...") venv_pip = os.path.join(VENV_PATH, "bin", "pip3") requirements_file = os.path.join(APP_DIR, "requirements.txt") if os.path.exists(requirements_file): print(f"从 {requirements_file} 安装依赖...") result = subprocess.run([venv_pip, "install", "-r", requirements_file], capture_output=True, text=True) else: print("安装 PyQt6...") result = subprocess.run([venv_pip, "install", "PyQt6"], capture_output=True, text=True) if result.returncode != 0: print(f"❌ 安装依赖失败: {result.stderr}") return False print("✅ 虚拟环境重新创建成功!") return True def show_venv_info(): """显示虚拟环境信息""" print("虚拟环境信息:") print(f"路径: {VENV_PATH}") if os.path.exists(os.path.join(VENV_PATH, "bin", "python3")): venv_python = os.path.join(VENV_PATH, "bin", "python3") result = subprocess.run([venv_python, "--version"], capture_output=True, text=True) print(f"Python 版本: {result.stdout.strip()}") result = subprocess.run([venv_python, "-m", "pip", "list"], capture_output=True, text=True) print("\n已安装的包:") print(result.stdout) else: print("❌ 虚拟环境不存在或已损坏") def main(): """主函数""" print("配置编辑器虚拟环境管理工具") print("=" * 40) if len(sys.argv) < 2: print("使用方法:") print(" python manage_venv.py check - 检查虚拟环境状态") print(" python manage_venv.py recreate - 重新创建虚拟环境") print(" python manage_venv.py info - 显示虚拟环境信息") return command = sys.argv[1] if command == "check": if check_venv(): print("✅ 虚拟环境状态正常") else: print("❌ 虚拟环境有问题") print("建议运行: python manage_venv.py recreate") elif command == "recreate": if recreate_venv(): print("✅ 虚拟环境重新创建成功") else: print("❌ 重新创建虚拟环境失败") elif command == "info": show_venv_info() else: print(f"未知命令: {command}") if __name__ == "__main__": main() EOF chmod +x "$APP_DIR/manage_venv.py" # 17. 创建 README 文件 echo "17. 创建 README 文件..." cat > "$APP_DIR/README.md" << EOF # 配置编辑器 ($APP_NAME) 版本: $APP_VERSION ## 概述 配置编辑器是一个功能强大的工具,用于编辑和管理各种配置文件。 ## 虚拟环境 此应用程序在独立的虚拟环境中运行,以避免与其他 Python 应用程序的依赖冲突。 虚拟环境位置: $VENV_PATH ## 使用方法 ### 从菜单启动 1. 在应用程序菜单中搜索 "Config Editor" 2. 点击图标启动 ### 从终端启动 \`\`\`bash $APP_NAME \`\`\` ### 手动激活虚拟环境 \`\`\`bash source $VENV_PATH/bin/activate cd $APP_INSTALL_PATH python main.py \`\`\` ## 管理虚拟环境 ### 检查虚拟环境状态 \`\`\`bash cd $APP_INSTALL_PATH python manage_venv.py check \`\`\` ### 重新创建虚拟环境 \`\`\`bash cd $APP_INSTALL_PATH python manage_venv.py recreate \`\`\` 或使用脚本: \`\`\`bash cd $APP_INSTALL_PATH ./init_venv.sh \`\`\` ### 查看虚拟环境信息 \`\`\`bash cd $APP_INSTALL_PATH python manage_venv.py info \`\`\` ## 配置文件示例 配置文件示例位于: /var/lib/$APP_NAME/config_example.py ## 故障排除 ### 1. 虚拟环境问题 如果应用程序无法启动,可能是虚拟环境有问题: \`\`\`bash cd $APP_INSTALL_PATH ./init_venv.sh \`\`\` ### 2. 权限问题 如果无法保存设置,确保以下目录可写: - $APP_INSTALL_PATH/config_editor_rules.json - ~/.config_editor/ - ~/.config/config-editor/ ### 3. 依赖问题 如果 PyQt6 有问题,重新安装: \`\`\`bash source $VENV_PATH/bin/activate pip install --force-reinstall PyQt6 \`\`\` ## 支持 如有问题,请联系: $MAINTAINER EOF # 18. 计算安装大小 echo "18. 计算安装大小..." INSTALLED_SIZE=$(du -sk "$BUILD_ROOT" | cut -f1) sed -i "/^Architecture:/a Installed-Size: $INSTALLED_SIZE" "$DEBIAN_DIR/control" # 19. 构建 deb 包 echo "19. 构建 deb 包..." PACKAGE_NAME="${APP_NAME}_${APP_VERSION}_${ARCHITECTURE}.deb" dpkg-deb --build "$BUILD_ROOT" "$PACKAGE_NAME" # 20. 验证 deb 包 echo "20. 验证 deb 包..." if [ -f "$PACKAGE_NAME" ]; then echo "✅ 构建成功: $PACKAGE_NAME" echo "文件大小: $(du -h "$PACKAGE_NAME" | cut -f1)" # 显示包信息 echo -e "\n包内容:" dpkg -c "$PACKAGE_NAME" | head -30 echo -e "\n包信息:" dpkg -I "$PACKAGE_NAME" # 清理构建目录 rm -rf "$BUILD_ROOT" echo -e "\n========================================" echo "✅ 构建完成!" echo "生成的包: $PACKAGE_NAME" echo "安装命令: sudo dpkg -i $PACKAGE_NAME" echo "如果有依赖问题,运行: sudo apt-get install -f" echo "" echo "注意: 此版本使用虚拟环境" echo "虚拟环境将在安装时自动创建" echo "========================================" else echo "❌ 构建失败!" exit 1 fi