Files
digiserver-v2/app/utils/pptx_converter.py
ske087 53ab7fa4ab Add models and utils with type hints and optimizations
Models (6 + 1 association table):
- User: Authentication with bcrypt, admin role check, last_login tracking
- Player: Digital signage devices with auth codes, status tracking, online detection
- Group: Player/content organization with statistics properties
- Content: Media files with type detection, file size helpers, position ordering
- ServerLog: Audit trail with class methods for logging levels
- PlayerFeedback: Player status updates with error tracking
- group_content: Many-to-many association table for groups and content

Model improvements:
- Added type hints to all methods and properties
- Added database indexes on frequently queried columns (username, auth_code, group_id, player_id, position, level, timestamp, status)
- Added comprehensive docstrings
- Added helper properties (is_online, is_admin, file_size_mb, etc.)
- Added relationship back_populates for bidirectional navigation
- Added timestamps (created_at, updated_at, last_seen, uploaded_at)

Utils (4 modules):
- logger.py: Logging utility with level-based functions (info, warning, error)
- uploads.py: File upload handling with progress tracking, video optimization
- group_player_management.py: Player/group status tracking and bulk operations
- pptx_converter.py: PowerPoint to PDF conversion using LibreOffice

Utils improvements:
- Full type hints on all functions
- Comprehensive error handling
- Progress tracking for long-running operations
- Video optimization (H.264, 30fps, max 1080p, 8Mbps)
- Helper functions for time formatting and statistics
- Proper logging of all operations

Performance optimizations:
- Database indexes on all foreign keys and frequently filtered columns
- Lazy loading for relationships where appropriate
- Efficient queries with proper ordering
- Helper properties to avoid repeated calculations

Ready for template migration and testing
2025-11-12 10:26:19 +02:00

107 lines
3.3 KiB
Python

"""PowerPoint to PDF converter using LibreOffice."""
import os
import subprocess
import time
import logging
from typing import Optional
logger = logging.getLogger(__name__)
def cleanup_libreoffice_processes() -> None:
"""Clean up any hanging LibreOffice processes."""
try:
subprocess.run(['pkill', '-f', 'soffice'], capture_output=True, timeout=10)
time.sleep(1) # Give processes time to terminate
except Exception as e:
logger.warning(f"Failed to cleanup LibreOffice processes: {e}")
def pptx_to_pdf_libreoffice(pptx_path: str, output_dir: str) -> Optional[str]:
"""Convert PPTX to PDF using LibreOffice for highest quality.
This function is the core component of the PPTX processing workflow:
PPTX → PDF (this function) → JPG images (handled in uploads.py)
Args:
pptx_path: Path to the PPTX file
output_dir: Directory to save the PDF
Returns:
Path to the generated PDF file, or None if conversion failed
"""
try:
# Clean up any existing LibreOffice processes
cleanup_libreoffice_processes()
# Ensure output directory exists
os.makedirs(output_dir, exist_ok=True)
# Use LibreOffice to convert PPTX to PDF
cmd = [
'libreoffice',
'--headless',
'--convert-to', 'pdf',
'--outdir', output_dir,
'--invisible',
'--nodefault',
pptx_path
]
logger.info(f"Converting PPTX to PDF using LibreOffice: {pptx_path}")
# Increase timeout to 300 seconds (5 minutes) for large presentations
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
if result.returncode != 0:
logger.error(f"LibreOffice conversion failed: {result.stderr}")
logger.error(f"LibreOffice stdout: {result.stdout}")
cleanup_libreoffice_processes()
return None
# Find the generated PDF file
base_name = os.path.splitext(os.path.basename(pptx_path))[0]
pdf_path = os.path.join(output_dir, f"{base_name}.pdf")
if os.path.exists(pdf_path):
logger.info(f"PDF conversion successful: {pdf_path}")
cleanup_libreoffice_processes()
return pdf_path
else:
logger.error(f"PDF file not found after conversion: {pdf_path}")
cleanup_libreoffice_processes()
return None
except subprocess.TimeoutExpired:
logger.error("LibreOffice conversion timed out (300s)")
cleanup_libreoffice_processes()
return None
except Exception as e:
logger.error(f"Error in PPTX to PDF conversion: {e}")
cleanup_libreoffice_processes()
return None
def validate_pptx_file(filepath: str) -> bool:
"""Validate if file is a valid PowerPoint file.
Args:
filepath: Path to file to validate
Returns:
True if valid PPTX file, False otherwise
"""
if not os.path.exists(filepath):
return False
# Check file extension
if not filepath.lower().endswith(('.ppt', '.pptx')):
return False
# Check file size (must be > 0)
if os.path.getsize(filepath) == 0:
return False
return True