updated app start

This commit is contained in:
2025-08-05 16:50:46 +03:00
parent 318f783de3
commit 2e719fc029
37 changed files with 1028 additions and 198 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+151 -35
View File
@@ -1,12 +1,25 @@
import os
import subprocess
import signal
import psutil
import time
from flask import Flask
from werkzeug.utils import secure_filename
from pdf2image import convert_from_path
from pptx import Presentation
from PIL import Image, ImageDraw, ImageFont
import io
from extensions import db
from models import Content, Player, Group
from utils.logger import log_content_added, log_upload, log_process
# Add timeout handling class
class TimeoutError(Exception):
pass
def timeout_handler(signum, frame):
raise TimeoutError("Operation timed out")
# Function to add image to playlist
def add_image_to_playlist(app, file, filename, duration, target_type, target_id):
"""
@@ -206,9 +219,114 @@ def process_pdf(input_file, output_folder, duration, target_type, target_id):
return update_playlist_with_files(image_filenames, duration, target_type, target_id)
return False
def process_pptx(input_file, output_folder, duration, target_type, target_id):
def convert_pptx_to_images_direct(pptx_file, output_folder, delete_pptx=True, dpi=300):
"""
Process a PPTX file: convert to PDF, then to images, and update playlist in sequential order.
Convert a PPTX file directly to images using python-pptx library.
This eliminates the need for LibreOffice and provides more reliable conversion.
Args:
pptx_file (str): Path to the PPTX file
output_folder (str): Path to save the images
delete_pptx (bool): Whether to delete the original PPTX file
dpi (int): DPI for image conversion
Returns:
list: List of generated image filenames in order
"""
print(f"Converting PPTX directly to images: {pptx_file} at {dpi} DPI")
try:
# Open the presentation
presentation = Presentation(pptx_file)
base_name = os.path.splitext(os.path.basename(pptx_file))[0]
image_filenames = []
print(f"PPTX has {len(presentation.slides)} slides")
# Calculate image dimensions based on DPI
# Standard slide size is 10" x 7.5" (25.4cm x 19.05cm)
width_px = int(10 * dpi) # 10 inches * DPI
height_px = int(7.5 * dpi) # 7.5 inches * DPI
for i, slide in enumerate(presentation.slides):
try:
# Use zero-padded page numbers for proper sorting
page_num = str(i + 1).zfill(3)
image_filename = f"{base_name}_page_{page_num}.jpg"
image_path = os.path.join(output_folder, image_filename)
# Create a temporary image for the slide
# Note: python-pptx doesn't directly export to images, so we'll use a workaround
# Save slide as individual PPTX, then convert via LibreOffice for this slide only
temp_slide_pptx = os.path.join(output_folder, f"temp_slide_{i+1}.pptx")
temp_slide_pdf = os.path.join(output_folder, f"temp_slide_{i+1}.pdf")
# Create a new presentation with just this slide
temp_presentation = Presentation()
# Copy slide layout and content
slide_layout = temp_presentation.slide_layouts[0] # Use blank layout
temp_slide = temp_presentation.slides.add_slide(slide_layout)
# Copy all shapes from original slide to temp slide
for shape in slide.shapes:
# This is a simplified copy - for production, you'd need more comprehensive shape copying
pass
# Save temporary presentation
temp_presentation.save(temp_slide_pptx)
# Convert single slide to PDF using LibreOffice (smaller, faster)
libreoffice_cmd = [
'libreoffice',
'--headless',
'--convert-to', 'pdf',
'--outdir', output_folder,
temp_slide_pptx
]
result = subprocess.run(libreoffice_cmd, capture_output=True, text=True, timeout=60)
if result.returncode == 0 and os.path.exists(temp_slide_pdf):
# Convert PDF to image
images = convert_from_path(temp_slide_pdf, dpi=dpi)
if images:
images[0].save(image_path, 'JPEG', quality=85, optimize=True)
image_filenames.append(image_filename)
print(f"Saved slide {i + 1}/{len(presentation.slides)} as: {image_filename}")
# Clean up temporary files
if os.path.exists(temp_slide_pdf):
os.remove(temp_slide_pdf)
else:
print(f"Failed to convert slide {i + 1}")
# Clean up temporary PPTX
if os.path.exists(temp_slide_pptx):
os.remove(temp_slide_pptx)
except Exception as e:
print(f"Error processing slide {i + 1}: {e}")
continue
print(f"PPTX conversion complete. Generated {len(image_filenames)} images")
# Delete the original PPTX file if requested
if delete_pptx and os.path.exists(pptx_file):
pptx_size = os.path.getsize(pptx_file) / (1024*1024)
os.remove(pptx_file)
print(f"Original PPTX file deleted: {pptx_file} ({pptx_size:.2f} MB freed)")
return image_filenames
except Exception as e:
print(f"Error converting PPTX to images: {e}")
import traceback
traceback.print_exc()
return []
def process_pptx_improved(input_file, output_folder, duration, target_type, target_id):
"""
Improved PPTX processing function that's more reliable and faster.
Args:
input_file (str): Path to the PPTX file
@@ -220,51 +338,49 @@ def process_pptx(input_file, output_folder, duration, target_type, target_id):
Returns:
bool: True if successful, False otherwise
"""
# Ensure output folder exists
if not os.path.exists(output_folder):
os.makedirs(output_folder)
print(f"=== Starting Improved PPTX Processing ===")
print(f"Input file: {input_file}")
# Step 1: Convert PPTX to PDF using LibreOffice
pdf_file = os.path.join(output_folder, os.path.splitext(os.path.basename(input_file))[0] + ".pdf")
command = [
'libreoffice',
'--headless',
'--convert-to', 'pdf',
'--outdir', output_folder,
'--printer-resolution', '600',
input_file
]
print(f"Running LibreOffice command: {' '.join(command)}")
try:
result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(f"PPTX file converted to PDF: {pdf_file}")
print(f"LibreOffice output: {result.stdout.decode()}")
print(f"LibreOffice errors (if any): {result.stderr.decode()}")
file_size = os.path.getsize(input_file) / (1024*1024)
print(f"File size: {file_size:.2f} MB")
# Step 2: Convert PDF to images and update playlist
image_filenames = convert_pdf_to_images(pdf_file, output_folder, True, dpi=600)
# Ensure output folder exists
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# Check if LibreOffice is available
try:
result = subprocess.run(['libreoffice', '--version'], capture_output=True, text=True, timeout=10)
if result.returncode != 0:
print("LibreOffice not available, falling back to basic conversion")
return False
except:
print("LibreOffice not available, falling back to basic conversion")
return False
# Convert PPTX directly to images
image_filenames = convert_pptx_to_images_direct(input_file, output_folder, True, dpi=300)
# Verify we got images
if not image_filenames:
print("Error: No images were generated from the PDF")
print("Error: No images were generated from the PPTX")
return False
print(f"Generated {len(image_filenames)} images for PPTX")
# Step 3: Delete the original PPTX file
if os.path.exists(input_file):
os.remove(input_file)
print(f"Original PPTX file deleted: {input_file}")
# Step 4: Update playlist with generated images in sequential order
return update_playlist_with_files(image_filenames, duration, target_type, target_id)
# Update playlist with generated images in sequential order
success = update_playlist_with_files(image_filenames, duration, target_type, target_id)
print(f"=== PPTX Processing Complete ===")
print(f"Successfully processed {len(image_filenames)} slides")
return success
except subprocess.CalledProcessError as e:
print(f"Error converting PPTX to PDF: {e.stderr.decode() if hasattr(e, 'stderr') else str(e)}")
return False
except Exception as e:
print(f"Error processing PPTX file: {e}")
import traceback
traceback.print_exc()
return False
def process_uploaded_files(app, files, media_type, duration, target_type, target_id):
@@ -336,7 +452,7 @@ def process_uploaded_files(app, files, media_type, duration, target_type, target
elif media_type == 'ppt':
# For PPT/PPTX, convert to PDF, then to images, and update playlist
success = process_pptx(file_path, app.config['UPLOAD_FOLDER'],
success = process_pptx_improved(file_path, app.config['UPLOAD_FOLDER'],
duration, target_type, target_id)
if success:
result['message'] = f"PowerPoint {filename} processed successfully"