updated app start
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
186
utils/uploads.py
186
utils/uploads.py
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user