Showing
1 changed file
with
87 additions
and
61 deletions
| @@ -9,6 +9,13 @@ from pathlib import Path | @@ -9,6 +9,13 @@ from pathlib import Path | ||
| 9 | from loguru import logger | 9 | from loguru import logger |
| 10 | from ctypes import util as ctypes_util | 10 | from ctypes import util as ctypes_util |
| 11 | 11 | ||
| 12 | +BOX_CONTENT_WIDTH = 62 | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +def _box_line(text: str = "") -> str: | ||
| 16 | + """Render a single line inside the 66-char help box.""" | ||
| 17 | + return f"║ {text:<{BOX_CONTENT_WIDTH}}║\n" | ||
| 18 | + | ||
| 12 | 19 | ||
| 13 | def _get_platform_specific_instructions(): | 20 | def _get_platform_specific_instructions(): |
| 14 | """ | 21 | """ |
| @@ -19,55 +26,71 @@ def _get_platform_specific_instructions(): | @@ -19,55 +26,71 @@ def _get_platform_specific_instructions(): | ||
| 19 | """ | 26 | """ |
| 20 | system = platform.system() | 27 | system = platform.system() |
| 21 | 28 | ||
| 29 | + def _box_lines(lines): | ||
| 30 | + return "".join(_box_line(line) for line in lines) | ||
| 31 | + | ||
| 22 | if system == "Darwin": # macOS | 32 | if system == "Darwin": # macOS |
| 23 | - return ( | ||
| 24 | - "║ 🍎 macOS 系统解决方案: ║\n" | ||
| 25 | - "║ ║\n" | ||
| 26 | - "║ 1. 安装系统依赖: ║\n" | ||
| 27 | - "║ brew install pango gdk-pixbuf libffi ║\n" | ||
| 28 | - "║ ║\n" | ||
| 29 | - "║ 2. 设置环境变量(重要!): ║\n" | ||
| 30 | - "║ Apple Silicon: export DYLD_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_LIBRARY_PATH ║\n" | ||
| 31 | - "║ Intel Mac: export DYLD_LIBRARY_PATH=/usr/local/lib:$DYLD_LIBRARY_PATH ║\n" | ||
| 32 | - "║ ║\n" | ||
| 33 | - "║ 3. 永久生效(推荐): ║\n" | ||
| 34 | - "║ echo 'export DYLD_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_LIBRARY_PATH' >> ~/.zshrc ║\n" | ||
| 35 | - "║ 或 echo 'export DYLD_LIBRARY_PATH=/usr/local/lib:$DYLD_LIBRARY_PATH' >> ~/.zshrc ║\n" | ||
| 36 | - "║ source ~/.zshrc ║\n" | 33 | + return _box_lines( |
| 34 | + [ | ||
| 35 | + "🍎 macOS 系统解决方案:", | ||
| 36 | + "", | ||
| 37 | + "步骤 1: 安装依赖(宿主机执行)", | ||
| 38 | + " brew install pango gdk-pixbuf libffi", | ||
| 39 | + "", | ||
| 40 | + "步骤 2: 设置 DYLD_LIBRARY_PATH(必做)", | ||
| 41 | + " Apple Silicon:", | ||
| 42 | + " export DYLD_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_LIBRARY_PATH", | ||
| 43 | + " Intel:", | ||
| 44 | + " export DYLD_LIBRARY_PATH=/usr/local/lib:$DYLD_LIBRARY_PATH", | ||
| 45 | + "", | ||
| 46 | + "步骤 3: 永久生效(推荐)", | ||
| 47 | + " 将 export DYLD_LIBRARY_PATH=... 追加到 ~/.zshrc", | ||
| 48 | + " Apple 用 /opt/homebrew/lib,Intel 用 /usr/local/lib", | ||
| 49 | + " 执行 source ~/.zshrc 后再打开新终端", | ||
| 50 | + "", | ||
| 51 | + "步骤 4: 新开终端执行验证", | ||
| 52 | + " python -m ReportEngine.utils.dependency_check", | ||
| 53 | + " 输出含 “✓ Pango 依赖检测通过” 即配置正确", | ||
| 54 | + ] | ||
| 37 | ) | 55 | ) |
| 38 | elif system == "Linux": | 56 | elif system == "Linux": |
| 39 | - return ( | ||
| 40 | - "║ 🐧 Linux 系统解决方案: ║\n" | ||
| 41 | - "║ ║\n" | ||
| 42 | - "║ Ubuntu/Debian: ║\n" | ||
| 43 | - "║ sudo apt-get install libpango-1.0-0 libpangoft2-1.0-0 \\ ║\n" | ||
| 44 | - "║ libgdk-pixbuf2.0-0 libffi-dev libcairo2 ║\n" | ||
| 45 | - "║ ║\n" | ||
| 46 | - "║ CentOS/RHEL: ║\n" | ||
| 47 | - "║ sudo yum install pango gdk-pixbuf2 libffi-devel cairo ║\n" | ||
| 48 | - "║ ║\n" | ||
| 49 | - "║ 若仍提示缺库:export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH ║\n" | ||
| 50 | - "║ sudo ldconfig ║\n" | 57 | + return _box_lines( |
| 58 | + [ | ||
| 59 | + "🐧 Linux 系统解决方案:", | ||
| 60 | + "", | ||
| 61 | + "Ubuntu/Debian(宿主机执行):", | ||
| 62 | + " sudo apt-get update", | ||
| 63 | + " sudo apt-get install -y \\", | ||
| 64 | + " libpango-1.0-0 libpangoft2-1.0-0 libffi-dev libcairo2", | ||
| 65 | + " libgdk-pixbuf-2.0-0(缺失时改为 libgdk-pixbuf2.0-0)", | ||
| 66 | + "", | ||
| 67 | + "CentOS/RHEL:", | ||
| 68 | + " sudo yum install -y pango gdk-pixbuf2 libffi-devel cairo", | ||
| 69 | + "", | ||
| 70 | + "Docker 部署无需额外安装,镜像已包含依赖", | ||
| 71 | + ] | ||
| 51 | ) | 72 | ) |
| 52 | elif system == "Windows": | 73 | elif system == "Windows": |
| 53 | - return ( | ||
| 54 | - "║ 🪟 Windows 系统解决方案: ║\n" | ||
| 55 | - "║ ║\n" | ||
| 56 | - "║ 1. 安装 GTK3 Runtime: ║\n" | ||
| 57 | - "║ https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases ║\n" | ||
| 58 | - "║ ║\n" | ||
| 59 | - "║ 2. 将 GTK 安装目录下的 bin 加入 PATH(需新开终端): ║\n" | ||
| 60 | - "║ set PATH=C:\\Program Files\\GTK3-Runtime Win64\\bin;%PATH% ║\n" | ||
| 61 | - "║ (若自定义路径,请替换为实际安装路径) ║\n" | ||
| 62 | - "║ ║\n" | ||
| 63 | - "║ 3. 验证:在新终端运行 ║\n" | ||
| 64 | - "║ python -m ReportEngine.utils.dependency_check ║\n" | ||
| 65 | - "║ 看到 ✓ 提示即表示 PDF 导出可用 ║\n" | 74 | + return _box_lines( |
| 75 | + [ | ||
| 76 | + "🪟 Windows 系统解决方案:", | ||
| 77 | + "", | ||
| 78 | + "步骤 1: 安装 GTK3 Runtime(宿主机执行)", | ||
| 79 | + " 下载页: README 中的 GTK3 Runtime 链接(建议默认路径)", | ||
| 80 | + "", | ||
| 81 | + "步骤 2: 将 GTK 安装目录下的 bin 加入 PATH(需新终端)", | ||
| 82 | + " set PATH=C:\\Program Files\\GTK3-Runtime Win64\\bin;%PATH%", | ||
| 83 | + " 自定义路径请替换,或设置环境变量 GTK_BIN_PATH", | ||
| 84 | + " 可选: 永久添加 PATH 示例:", | ||
| 85 | + " setx PATH \"C:\\Program Files\\GTK3-Runtime Win64\\bin;%PATH%\"", | ||
| 86 | + "", | ||
| 87 | + "步骤 3: 验证(新终端执行)", | ||
| 88 | + " python -m ReportEngine.utils.dependency_check", | ||
| 89 | + " 输出含 “✓ Pango 依赖检测通过” 即配置正确", | ||
| 90 | + ] | ||
| 66 | ) | 91 | ) |
| 67 | else: | 92 | else: |
| 68 | - return ( | ||
| 69 | - "║ 请查看 README.md 了解您系统的安装方法 ║\n" | ||
| 70 | - ) | 93 | + return _box_lines(["请查看 PDF 导出 README 了解您系统的安装方法"]) |
| 71 | 94 | ||
| 72 | 95 | ||
| 73 | def _ensure_windows_gtk_paths(): | 96 | def _ensure_windows_gtk_paths(): |
| @@ -247,34 +270,37 @@ def check_pango_available(): | @@ -247,34 +270,37 @@ def check_pango_available(): | ||
| 247 | platform_instructions = _get_platform_specific_instructions() | 270 | platform_instructions = _get_platform_specific_instructions() |
| 248 | windows_hint = "" | 271 | windows_hint = "" |
| 249 | if platform.system() == "Windows": | 272 | if platform.system() == "Windows": |
| 273 | + prefix = "已尝试自动添加 GTK 路径: " | ||
| 274 | + max_path_len = BOX_CONTENT_WIDTH - len(prefix) | ||
| 250 | path_display = added_path or "未找到默认路径" | 275 | path_display = added_path or "未找到默认路径" |
| 251 | - # 控制长度,避免破坏提示框宽度 | ||
| 252 | - if len(path_display) > 38: | ||
| 253 | - path_display = path_display[:35] + "..." | ||
| 254 | - windows_hint = f"║ 已尝试自动添加 GTK 路径: {path_display:<38}║\n" | ||
| 255 | - arch_note = "║ 🔍 若已安装仍报错:确认 Python/GTK 位数一致,重开终端 ║\n" | 276 | + if len(path_display) > max_path_len: |
| 277 | + path_display = path_display[: max_path_len - 3] + "..." | ||
| 278 | + windows_hint = _box_line(prefix + path_display) | ||
| 279 | + arch_note = _box_line("🔍 若已安装仍报错:确认 Python 与 GTK 位数一致后重开终端") | ||
| 256 | else: | 280 | else: |
| 257 | arch_note = "" | 281 | arch_note = "" |
| 258 | 282 | ||
| 259 | missing_note = "" | 283 | missing_note = "" |
| 260 | if missing_native: | 284 | if missing_native: |
| 261 | missing_str = ", ".join(missing_native) | 285 | missing_str = ", ".join(missing_native) |
| 262 | - missing_note = f"║ 未识别到的依赖: {missing_str:<46}║\n" | 286 | + missing_note = _box_line(f"未识别到的依赖: {missing_str}") |
| 263 | 287 | ||
| 264 | if 'gobject' in error_msg.lower() or 'pango' in error_msg.lower() or 'gdk' in error_msg.lower(): | 288 | if 'gobject' in error_msg.lower() or 'pango' in error_msg.lower() or 'gdk' in error_msg.lower(): |
| 289 | + box_top = "╔" + "═" * 64 + "╗\n" | ||
| 290 | + box_bottom = "╚" + "═" * 64 + "╝" | ||
| 265 | return False, ( | 291 | return False, ( |
| 266 | - "╔════════════════════════════════════════════════════════════════╗\n" | ||
| 267 | - "║ ⚠️ PDF 导出依赖缺失 ║\n" | ||
| 268 | - "║ ║\n" | ||
| 269 | - "║ 📄 PDF 导出功能将不可用(其他功能不受影响) ║\n" | ||
| 270 | - "║ ║\n" | ||
| 271 | - f"{windows_hint}" | ||
| 272 | - f"{arch_note}" | ||
| 273 | - f"{missing_note}" | ||
| 274 | - f"{platform_instructions}" | ||
| 275 | - "║ ║\n" | ||
| 276 | - "║ 📖 完整文档:根目录 README.md ‘源码启动’的第二步 ║\n" | ||
| 277 | - "╚════════════════════════════════════════════════════════════════╝" | 292 | + box_top |
| 293 | + + _box_line("⚠️ PDF 导出依赖缺失") | ||
| 294 | + + _box_line() | ||
| 295 | + + _box_line("📄 PDF 导出功能将不可用(其他功能不受影响)") | ||
| 296 | + + _box_line() | ||
| 297 | + + windows_hint | ||
| 298 | + + arch_note | ||
| 299 | + + missing_note | ||
| 300 | + + platform_instructions | ||
| 301 | + + _box_line() | ||
| 302 | + + _box_line("📖 文档:static/Partial README for PDF Exporting/README.md") | ||
| 303 | + + box_bottom | ||
| 278 | ) | 304 | ) |
| 279 | return False, f"⚠ PDF 依赖加载失败: {error_msg};缺失/未识别: {', '.join(missing_native) if missing_native else '未知'}" | 305 | return False, f"⚠ PDF 依赖加载失败: {error_msg};缺失/未识别: {', '.join(missing_native) if missing_native else '未知'}" |
| 280 | except ImportError as e: | 306 | except ImportError as e: |
| @@ -299,7 +325,7 @@ def log_dependency_status(): | @@ -299,7 +325,7 @@ def log_dependency_status(): | ||
| 299 | else: | 325 | else: |
| 300 | logger.warning(message) | 326 | logger.warning(message) |
| 301 | logger.info("💡 提示:PDF 导出功能需要 Pango 库支持,但不影响系统其他功能的正常使用") | 327 | logger.info("💡 提示:PDF 导出功能需要 Pango 库支持,但不影响系统其他功能的正常使用") |
| 302 | - logger.info("📚 安装说明请参考:根目录下的 README.md 文件") | 328 | + logger.info("📚 安装说明请参考:static/Partial README for PDF Exporting/README.md") |
| 303 | 329 | ||
| 304 | return is_available | 330 | return is_available |
| 305 | 331 |
-
Please register or login to post a comment