- Added cleanup_old_logs() function to app_v3_simplified.py - Deletes log.txt if older than 15 days at app startup - Sends notification to monitoring server when cleanup occurs - Archived all legacy modules and documentation to oldcode/ - Updated device_info.txt with correct IP (192.168.1.104) - All changes validated and tested
131 lines
5.7 KiB
Python
131 lines
5.7 KiB
Python
"""
|
|
Dependency management
|
|
Handles package installation and verification
|
|
"""
|
|
|
|
import sys
|
|
import subprocess
|
|
import importlib.util
|
|
from config_settings import REQUIRED_PACKAGES, REPOSITORY_PATH
|
|
|
|
|
|
def install_package_from_wheel(wheel_path, package_name):
|
|
"""Install a Python package from a wheel file"""
|
|
try:
|
|
print(f"Installing {package_name} from {wheel_path}...")
|
|
result = subprocess.run([
|
|
sys.executable, "-m", "pip", "install", wheel_path,
|
|
"--no-index", "--no-deps", "--break-system-packages",
|
|
"--no-warn-script-location", "--force-reinstall"
|
|
], capture_output=True, text=True, timeout=60)
|
|
|
|
if result.returncode == 0:
|
|
print(f"✓ {package_name} installed successfully")
|
|
return True
|
|
else:
|
|
print(f"✗ Failed to install {package_name}: {result.stderr}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"✗ Error installing {package_name}: {e}")
|
|
return False
|
|
|
|
|
|
def check_and_install_dependencies():
|
|
"""Check if required packages are installed and install them from local repository if needed"""
|
|
print("Checking and installing dependencies...")
|
|
|
|
repository_path = str(REPOSITORY_PATH)
|
|
missing_packages = []
|
|
|
|
# Check each required package
|
|
for package_name, wheel_file in REQUIRED_PACKAGES.items():
|
|
try:
|
|
spec = importlib.util.find_spec(package_name)
|
|
if spec is not None:
|
|
print(f"✓ {package_name} is already installed")
|
|
else:
|
|
raise ImportError(f"Package {package_name} not found")
|
|
|
|
except ImportError:
|
|
print(f"✗ {package_name} is not installed")
|
|
missing_packages.append((package_name, wheel_file))
|
|
except Exception as e:
|
|
print(f"✗ Error checking {package_name}: {e}")
|
|
missing_packages.append((package_name, wheel_file))
|
|
|
|
# Install missing packages
|
|
if missing_packages:
|
|
print(f"\nInstalling {len(missing_packages)} missing packages...")
|
|
|
|
for package_name, wheel_file in missing_packages:
|
|
if wheel_file is None:
|
|
# Try to install via pip from internet (for system packages)
|
|
try:
|
|
print(f"Attempting to install {package_name} via pip...")
|
|
result = subprocess.run([
|
|
sys.executable, "-m", "pip", "install", package_name,
|
|
"--break-system-packages", "--no-warn-script-location"
|
|
], capture_output=True, text=True, timeout=120)
|
|
|
|
if result.returncode == 0:
|
|
print(f"✓ {package_name} installed via pip")
|
|
else:
|
|
print(f"⚠ pip install failed, trying apt...")
|
|
if package_name in ['gpiozero']:
|
|
try:
|
|
print(f"Attempting to install {package_name} via apt...")
|
|
result = subprocess.run([
|
|
'sudo', 'apt', 'install', '-y', f'python3-{package_name}',
|
|
'--no-install-recommends'
|
|
], capture_output=True, text=True, timeout=120)
|
|
|
|
if result.returncode == 0:
|
|
print(f"✓ {package_name} installed via apt")
|
|
else:
|
|
print(f"✗ Could not install {package_name} via apt")
|
|
except Exception as apt_e:
|
|
print(f"✗ apt install failed: {apt_e}")
|
|
except Exception as pip_e:
|
|
print(f"✗ pip install failed: {pip_e}")
|
|
else:
|
|
# Try to install from wheel file (pure Python wheels like rdm6300, certifi, etc.)
|
|
wheel_path = f"{repository_path}/{wheel_file}"
|
|
# Only try wheel files that are pure Python (not architecture-specific)
|
|
if not ('aarch64' in wheel_file or 'armv' in wheel_file):
|
|
install_package_from_wheel(wheel_path, package_name)
|
|
else:
|
|
# For architecture-specific wheels, try pip to get the right arch
|
|
print(f"Skipping wheel {package_name} (wrong architecture), trying pip...")
|
|
try:
|
|
result = subprocess.run([
|
|
sys.executable, "-m", "pip", "install", package_name,
|
|
"--break-system-packages", "--no-warn-script-location"
|
|
], capture_output=True, text=True, timeout=120)
|
|
|
|
if result.returncode == 0:
|
|
print(f"✓ {package_name} installed via pip")
|
|
else:
|
|
print(f"✗ Could not install {package_name}: {result.stderr}")
|
|
except Exception as e:
|
|
print(f"✗ Error installing {package_name}: {e}")
|
|
|
|
|
|
def verify_dependencies():
|
|
"""Verify that all required dependencies are available"""
|
|
print("Verifying dependencies...")
|
|
available = True
|
|
|
|
for package_name in REQUIRED_PACKAGES.keys():
|
|
try:
|
|
spec = importlib.util.find_spec(package_name)
|
|
if spec is not None:
|
|
print(f"✓ {package_name} verified")
|
|
else:
|
|
print(f"✗ {package_name} not available")
|
|
available = False
|
|
except Exception as e:
|
|
print(f"✗ Error verifying {package_name}: {e}")
|
|
available = False
|
|
|
|
return available
|