技能备份 - 2026-04-15 (40个技能)
This commit is contained in:
@@ -0,0 +1,343 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Dependencies checker and auto-installer for Super OCR
|
||||
|
||||
This module handles:
|
||||
- Dependency detection
|
||||
- Auto-installation of missing packages
|
||||
- Version checking
|
||||
- Clear error messages with troubleshooting steps
|
||||
"""
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
|
||||
# Dependency definitions
|
||||
DEPENDENCIES = {
|
||||
'paddleocr': {
|
||||
'package': 'paddleocr',
|
||||
'required': ['paddleocr'],
|
||||
'optional': [],
|
||||
'install_cmd': 'pip install paddleocr paddlepaddle',
|
||||
'check_fn': 'check_paddleocr'
|
||||
},
|
||||
'pytesseract': {
|
||||
'package': 'pytesseract',
|
||||
'required': ['pytesseract', 'PIL', 'cv2', 'numpy'],
|
||||
'optional': [],
|
||||
'install_cmd': 'pip install pytesseract pillow opencv-python numpy',
|
||||
'check_fn': 'check_pytesseract'
|
||||
},
|
||||
'common': {
|
||||
'package': 'common',
|
||||
'required': ['pathlib', 'argparse', 'logging'],
|
||||
'optional': ['yaml'],
|
||||
'install_cmd': None,
|
||||
'check_fn': None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def _check_module(module_name: str) -> bool:
|
||||
"""Check if a Python module is available"""
|
||||
return importlib.util.find_spec(module_name) is not None
|
||||
|
||||
|
||||
def check_paddleocr() -> Tuple[bool, List[str]]:
|
||||
"""Check PaddleOCR and paddlepaddle availability"""
|
||||
missing = []
|
||||
|
||||
if not _check_module('paddleocr'):
|
||||
missing.append('paddleocr')
|
||||
|
||||
# Check paddlepaddle (the actual library)
|
||||
if not _check_module('paddle'):
|
||||
missing.append('paddlepaddle')
|
||||
|
||||
return len(missing) == 0, missing
|
||||
|
||||
|
||||
def check_pytesseract() -> Tuple[bool, List[str]]:
|
||||
"""Check Tesseract-related dependencies"""
|
||||
missing = []
|
||||
|
||||
# Python packages
|
||||
for pkg in ['pytesseract', 'PIL', 'cv2', 'numpy']:
|
||||
if not _check_module(pkg):
|
||||
missing.append(pkg)
|
||||
|
||||
return len(missing) == 0, missing
|
||||
|
||||
|
||||
def check_tesseract_binary() -> Tuple[bool, str]:
|
||||
"""Check if tesseract binary is installed"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
['tesseract', '--version'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=5
|
||||
)
|
||||
return True, result.stdout.strip()
|
||||
except (subprocess.TimeoutExpired, FileNotFoundError, PermissionError):
|
||||
return False, ""
|
||||
|
||||
|
||||
def check_dependency(dep_name: str) -> Tuple[bool, List[str], Optional[str]]:
|
||||
"""
|
||||
Check a specific dependency.
|
||||
|
||||
Returns:
|
||||
(is_available, missing_items, installation_hint)
|
||||
"""
|
||||
if dep_name not in DEPENDENCIES:
|
||||
return False, [], None
|
||||
|
||||
dep = DEPENDENCIES[dep_name]
|
||||
|
||||
# Check if we have a custom check function
|
||||
if dep.get('check_fn'):
|
||||
check_fn_name = dep['check_fn']
|
||||
check_fns = {
|
||||
'check_paddleocr': check_paddleocr,
|
||||
'check_pytesseract': check_pytesseract,
|
||||
'check_tesseract_binary': check_tesseract_binary
|
||||
}
|
||||
|
||||
if check_fn_name in check_fns:
|
||||
is_available, result = check_fns[check_fn_name]()
|
||||
return is_available, result if isinstance(result, list) else [], None
|
||||
|
||||
# Generic check for required packages
|
||||
missing = []
|
||||
for pkg in dep.get('required', []):
|
||||
if not _check_module(pkg):
|
||||
missing.append(pkg)
|
||||
|
||||
return len(missing) == 0, missing, dep.get('install_cmd')
|
||||
|
||||
|
||||
def auto_install(dependency: str) -> bool:
|
||||
"""
|
||||
Auto-install a dependency.
|
||||
|
||||
Returns:
|
||||
True if installation succeeded, False otherwise
|
||||
"""
|
||||
if dependency not in DEPENDENCIES:
|
||||
print(f"[ERROR] Unknown dependency: {dependency}")
|
||||
return False
|
||||
|
||||
dep = DEPENDENCIES[dependency]
|
||||
install_cmd = dep.get('install_cmd')
|
||||
|
||||
if not install_cmd:
|
||||
print(f"[INFO] No auto-install command for {dependency}")
|
||||
return False
|
||||
|
||||
print(f"[INFO] Installing {dependency}...")
|
||||
print(f" Command: {install_cmd}")
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
install_cmd.split(),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=120
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"[OK] {dependency} installed successfully")
|
||||
return True
|
||||
else:
|
||||
print(f"[ERROR] Installation failed:")
|
||||
print(f" {result.stderr}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Auto-install failed: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def print_installation_guide() -> None:
|
||||
"""Print comprehensive installation instructions"""
|
||||
print("\n" + "=" * 60)
|
||||
print("Super OCR Dependencies Installation Guide")
|
||||
print("=" * 60)
|
||||
|
||||
print("\n[OPTION 1] Install PaddleOCR (Recommended for Chinese)")
|
||||
print("-" * 40)
|
||||
print("pip install paddleocr paddlepaddle")
|
||||
print()
|
||||
print("For macOS/Linux (CPU only):")
|
||||
print(" pip install paddleocr paddlepaddle")
|
||||
print()
|
||||
print("For Windows (CPU only):")
|
||||
print(" pip install paddleocr paddlepaddle")
|
||||
print()
|
||||
print("For GPU support:")
|
||||
print(" # CUDA 11.2")
|
||||
print(" pip install paddlepaddle-gpu==2.4.0 -f https://www.paddlepaddle.org.cn/whl/stable.html")
|
||||
print(" # CUDA 11.6")
|
||||
print(" pip install paddlepaddle-gpu==2.4.0 -f https://www.paddlepaddle.org.cn/whl/lite.html")
|
||||
|
||||
print("\n[OPTION 2] Install Tesseract")
|
||||
print("-" * 40)
|
||||
print("macOS:")
|
||||
print(" brew install tesseract")
|
||||
print()
|
||||
print("Ubuntu/Debian:")
|
||||
print(" sudo apt update && sudo apt install tesseract-ocr")
|
||||
print()
|
||||
print("Windows:")
|
||||
print(" Download from: https://github.com/UB-Mannheim/tesseract/wiki")
|
||||
|
||||
print("\n[OPTION 3] Install Tesseract Python bindings")
|
||||
print("-" * 40)
|
||||
print("pip install pytesseract pillow opencv-python numpy")
|
||||
|
||||
print("\n[OPTION 4] Install all at once")
|
||||
print("-" * 40)
|
||||
print("pip install paddleocr paddlepaddle pytesseract pillow opencv-python numpy")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
|
||||
|
||||
def check_all_dependencies(interactive: bool = True) -> bool:
|
||||
"""
|
||||
Check all dependencies and optionally install missing ones.
|
||||
|
||||
Returns:
|
||||
True if all dependencies are satisfied
|
||||
"""
|
||||
print("\n" + "=" * 60)
|
||||
print("Checking Super OCR Dependencies")
|
||||
print("=" * 60)
|
||||
|
||||
all_ok = True
|
||||
missing = []
|
||||
|
||||
# Check PaddleOCR
|
||||
print("\n[1/3] Checking PaddleOCR...")
|
||||
ok, missing_pkgs = check_paddleocr()
|
||||
if ok:
|
||||
print("[OK] PaddleOCR is available")
|
||||
else:
|
||||
print(f"[MISSING] Missing: {', '.join(missing_pkgs)}")
|
||||
all_ok = False
|
||||
missing.extend(missing_pkgs)
|
||||
|
||||
# Check Tesseract binary
|
||||
print("\n[2/3] Checking Tesseract binary...")
|
||||
ok, info = check_tesseract_binary()
|
||||
if ok:
|
||||
print(f"[OK] Tesseract is available: {info.split()[2] if info else 'unknown'}")
|
||||
else:
|
||||
print("[MISSING] Tesseract binary not found")
|
||||
print(" Install: brew install tesseract (macOS) or apt install tesseract-ocr (Ubuntu)")
|
||||
all_ok = False
|
||||
|
||||
# Check Tesseract Python bindings
|
||||
print("\n[3/3] Checking Tesseract Python bindings...")
|
||||
ok, missing_pkgs = check_pytesseract()
|
||||
if ok:
|
||||
print("[OK] Tesseract Python bindings are available")
|
||||
else:
|
||||
print(f"[MISSING] Missing: {', '.join(missing_pkgs)}")
|
||||
all_ok = False
|
||||
|
||||
# Summary
|
||||
print("\n" + "=" * 60)
|
||||
if all_ok:
|
||||
print("[OK] All dependencies satisfied!")
|
||||
return True
|
||||
else:
|
||||
print("[WARNING] Some dependencies are missing")
|
||||
print(f"Missing: {', '.join(missing)}")
|
||||
|
||||
if interactive:
|
||||
response = input("\nAuto-install missing dependencies? [y/N]: ")
|
||||
if response.lower() == 'y':
|
||||
# Install PaddleOCR if missing
|
||||
if 'paddleocr' in missing or 'paddlepaddle' in missing:
|
||||
print("\n[INSTALL] Installing PaddleOCR...")
|
||||
auto_install('paddleocr')
|
||||
|
||||
# Install Tesseract packages if missing
|
||||
if any(pkg in missing for pkg in ['pytesseract', 'PIL', 'cv2', 'numpy']):
|
||||
print("\n[INSTALL] Installing Tesseract packages...")
|
||||
auto_install('pytesseract')
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("Manual Installation:")
|
||||
print("=" * 60)
|
||||
print_installation_guide()
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Super OCR Dependencies Checker and Installer'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--check', '-c',
|
||||
action='store_true',
|
||||
help='Check dependencies without installing'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--install', '-i',
|
||||
action='store_true',
|
||||
help='Auto-install missing dependencies'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--dependency', '-d',
|
||||
choices=['paddleocr', 'pytesseract', 'all'],
|
||||
default='all',
|
||||
help='Specific dependency to check/install'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--guide', '-g',
|
||||
action='store_true',
|
||||
help='Show installation guide only'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--quiet', '-q',
|
||||
action='store_true',
|
||||
help='Suppress output'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.guide:
|
||||
print_installation_guide()
|
||||
return 0
|
||||
|
||||
if args.check or args.install:
|
||||
if args.dependency == 'all':
|
||||
success = check_all_dependencies(interactive=not args.quiet and not args.install)
|
||||
else:
|
||||
ok, missing, cmd = check_dependency(args.dependency)
|
||||
if ok:
|
||||
print(f"[OK] {args.dependency} is available")
|
||||
return 0
|
||||
else:
|
||||
print(f"[MISSING] {args.dependency}: {', '.join(missing)}")
|
||||
if args.install:
|
||||
success = auto_install(args.dependency)
|
||||
return 0 if success else 1
|
||||
return 1
|
||||
else:
|
||||
# Default: interactive check
|
||||
success = check_all_dependencies(interactive=True)
|
||||
return 0 if success else 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user