725 lines
20 KiB
Bash
725 lines
20 KiB
Bash
|
|
#!/bin/bash
|
|||
|
|
# 打包脚本:将配置编辑器项目打包成 deb 包
|
|||
|
|
|
|||
|
|
set -e # 遇到错误时退出
|
|||
|
|
|
|||
|
|
# ==================== 配置区域 ====================
|
|||
|
|
APP_NAME="config-editor"
|
|||
|
|
APP_VERSION="1.3"
|
|||
|
|
APP_DESCRIPTION="CE编辑器"
|
|||
|
|
MAINTAINER="hjy <hujinyang@jspwkj.com.cn>"
|
|||
|
|
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
|
|||
|
|
|