diff --git a/__pycache__/models.cpython-312.pyc b/__pycache__/models.cpython-312.pyc index d181911..6e95c70 100644 Binary files a/__pycache__/models.cpython-312.pyc and b/__pycache__/models.cpython-312.pyc differ diff --git a/__pycache__/pptx_to_images.cpython-312.pyc b/__pycache__/pptx_to_images.cpython-312.pyc new file mode 100644 index 0000000..4ae4875 Binary files /dev/null and b/__pycache__/pptx_to_images.cpython-312.pyc differ diff --git a/app.py b/app.py index 2656aab..885eba3 100644 --- a/app.py +++ b/app.py @@ -8,9 +8,11 @@ from functools import wraps from extensions import db, bcrypt, login_manager from models import User, Player, Content, Group # Add Group to the imports from flask_login import login_user, logout_user, login_required, current_user -from pptx import Presentation -import cairosvg +from pptx_to_images import convert_pptx_to_images # Assuming you have a module for PPTX conversion import os +# Define global variables for server version and build date +SERVER_VERSION = "1.0.0" +BUILD_DATE = "2025-06-25" app = Flask(__name__, instance_relative_config=True) @@ -181,56 +183,18 @@ def convert_video_and_update_playlist(file_path, original_filename, target_type, def convert_pptx_to_images(input_file, output_folder): """ - Converts a PowerPoint file (.pptx) to images while preserving the format and look of the slides. - Each slide is saved as a separate image in the output folder. + Calls the external pptx_to_images.py script to convert PPTX to images. """ + command = [ + "python", "pptx_to_images.py", input_file, output_folder + ] try: - if not os.path.exists(output_folder): - os.makedirs(output_folder) - - # Load the PowerPoint presentation - presentation = Presentation(input_file) - base_name = os.path.splitext(os.path.basename(input_file))[0] - - for i, slide in enumerate(presentation.slides): - # Generate an SVG representation of the slide - svg_content = generate_svg_from_slide(slide) - - # Convert the SVG to a high-quality image (JPEG) - image_filename = f"{base_name}_slide_{i + 1}.jpg" - image_path = os.path.join(output_folder, image_filename) - cairosvg.svg2png(bytestring=svg_content, write_to=image_path, dpi=300) - print(f"Slide {i + 1} saved as image: {image_path}") - - # Delete the original PPTX file after conversion - if os.path.exists(input_file): - os.remove(input_file) - print(f"Original PPTX file deleted: {input_file}") - + subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) return True - except Exception as e: - print(f"Error processing PPTX file: {e}") + except subprocess.CalledProcessError as e: + print(f"Error converting PPTX: {e.stderr.decode()}") return False -def generate_svg_from_slide(slide): - """ - Generates an SVG representation of a PowerPoint slide. - This function extracts shapes, text, and other elements from the slide. - """ - svg_content = '' - for shape in slide.shapes: - if shape.has_text_frame: - text = shape.text_frame.text - # Add text to the SVG (adjust position and styling as needed) - svg_content += f'{text}' - elif shape.shape_type == 13: # Picture shape - if shape.image: - image_bytes = shape.image.blob - image_base64 = base64.b64encode(image_bytes).decode('utf-8') - svg_content += f'' - svg_content += '' - return svg_content - # Convert EMU to pixels def emu_to_pixels(emu): return int(emu / 914400 * 96) @@ -298,64 +262,30 @@ def upload_content(): filename = secure_filename(file.filename) file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(file_path) - filename = secure_filename(file.filename) - file_ext = os.path.splitext(filename)[1].lower() - # Handle PDF files - if media_type == 'pdf': - print(f"Processing PDF file: {file_path}") - convert_pdf_to_images(file_path, app.config['UPLOAD_FOLDER']) + file_ext = os.path.splitext(filename)[1].lower() - # Add the converted images to the playlist - if target_type == 'group': - group = Group.query.get_or_404(target_id) - for player in group.players: - for image_file in os.listdir(app.config['UPLOAD_FOLDER']): - if image_file.startswith(os.path.splitext(filename)[0]) and image_file.endswith('.jpg'): - new_content = Content(file_name=image_file, duration=duration, player_id=player.id) - db.session.add(new_content) - elif target_type == 'player': - for image_file in os.listdir(app.config['UPLOAD_FOLDER']): - if image_file.startswith(os.path.splitext(filename)[0]) and image_file.endswith('.jpg'): - new_content = Content(file_name=image_file, duration=duration, player_id=target_id) - db.session.add(new_content) - # --- Add this block for images --- - elif media_type in ['jpg', 'jpeg', 'png'] or (media_type == 'image' and file_ext in ['.jpg', '.jpeg', '.png']): - add_image_to_playlist(file, filename, duration, target_type, target_id) - - # Handle video files - elif media_type == 'video': - # Add the video file to the playlist - if target_type == 'group': - group = Group.query.get_or_404(target_id) - for player in group.players: - new_content = Content(file_name=filename, duration=duration, player_id=player.id) - db.session.add(new_content) - elif target_type == 'player': - new_content = Content(file_name=filename, duration=duration, player_id=target_id) - db.session.add(new_content) - - # Launch the video conversion function in a thread - thread = threading.Thread(target=convert_video_and_update_playlist, args=(file_path, filename, target_type, target_id, duration)) - thread.start() - - # Handle PPT files - elif media_type == 'ppt': + if media_type == 'ppt': print(f"Processing PPT file: {file_path}") success = convert_pptx_to_images(file_path, app.config['UPLOAD_FOLDER']) if success: - # Add each slide image to the playlist base_name = os.path.splitext(filename)[0] - for slide_image in sorted(os.listdir(app.config['UPLOAD_FOLDER'])): - if slide_image.startswith(base_name) and slide_image.endswith('.jpg'): - if target_type == 'group': - group = Group.query.get_or_404(target_id) - for player in group.players: - new_content = Content(file_name=slide_image, duration=duration, player_id=player.id) - db.session.add(new_content) - elif target_type == 'player': - new_content = Content(file_name=slide_image, duration=duration, player_id=target_id) + # Find all PNGs generated for this PPTX + slide_images = sorted([ + f for f in os.listdir(app.config['UPLOAD_FOLDER']) + if (f.startswith(base_name) and f.endswith('.png')) + ]) + print("Slide images found:", slide_images) + if target_type == 'group': + group = Group.query.get_or_404(target_id) + for player in group.players: + for slide_image in slide_images: + new_content = Content(file_name=slide_image, duration=duration, player_id=player.id) db.session.add(new_content) + elif target_type == 'player': + for slide_image in slide_images: + new_content = Content(file_name=slide_image, duration=duration, player_id=target_id) + db.session.add(new_content) except Exception as e: print(f"Error processing file {file.filename}: {e}") @@ -376,9 +306,7 @@ def upload_content(): return render_template('upload_content.html', target_type=target_type, target_id=target_id, players=players, groups=groups, return_url=return_url) -# Define global variables for server version and build date -SERVER_VERSION = "1.0.0" -BUILD_DATE = "2025-06-25" + @app.route('/admin') @login_required diff --git a/instance/dashboard.db b/instance/dashboard.db index 93418d9..e2d6b08 100644 Binary files a/instance/dashboard.db and b/instance/dashboard.db differ diff --git a/pptx_to_images.py b/pptx_to_images.py new file mode 100644 index 0000000..5a0178e --- /dev/null +++ b/pptx_to_images.py @@ -0,0 +1,35 @@ +import os +import sys +import subprocess + +def convert_pptx_to_images(input_file, output_folder): + """ + Converts a PowerPoint file (.ppt or .pptx) to images using LibreOffice. + Each slide is saved as a separate image in the output folder. + """ + if not os.path.exists(output_folder): + os.makedirs(output_folder) + + # Convert the PowerPoint file to images using LibreOffice + command = [ + 'libreoffice', + '--headless', + '--convert-to', 'png', + '--outdir', output_folder, + input_file + ] + try: + subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + print(f"PPTX file converted to images: {input_file}") + except subprocess.CalledProcessError as e: + print(f"Error converting PPTX to images: {e.stderr.decode()}") + return False + + # Rename the generated images to follow the naming convention + base_name = os.path.splitext(os.path.basename(input_file))[0] + png_files = sorted([f for f in os.listdir(output_folder) if f.endswith('.png') and base_name in f]) + for i, file_name in enumerate(png_files): + new_name = f"{base_name}_{i + 1}.png" + os.rename(os.path.join(output_folder, file_name), os.path.join(output_folder, new_name)) + print("Renamed slide images:", [f"{base_name}_{i + 1}.png" for i in range(len(png_files))]) + return True diff --git a/static/uploads/123.jpeg b/static/uploads/123.jpeg deleted file mode 100644 index 29d8372..0000000 Binary files a/static/uploads/123.jpeg and /dev/null differ diff --git a/static/uploads/20250417_09h25m37s_grim.png b/static/uploads/20250417_09h25m37s_grim.png deleted file mode 100644 index 1bcc6ab..0000000 Binary files a/static/uploads/20250417_09h25m37s_grim.png and /dev/null differ diff --git a/static/uploads/20250605_09h44m12s_grim.png b/static/uploads/20250605_09h44m12s_grim.png deleted file mode 100644 index 8ee25bd..0000000 Binary files a/static/uploads/20250605_09h44m12s_grim.png and /dev/null differ diff --git a/static/uploads/edit_pencil.png b/static/uploads/edit_pencil.png deleted file mode 100644 index da079d9..0000000 Binary files a/static/uploads/edit_pencil.png and /dev/null differ diff --git a/static/uploads/informare_tombola_slide_1.jpg b/static/uploads/informare_tombola_slide_1.jpg deleted file mode 100644 index 9673925..0000000 Binary files a/static/uploads/informare_tombola_slide_1.jpg and /dev/null differ