updated
This commit is contained in:
Binary file not shown.
BIN
__pycache__/pptx_to_images.cpython-312.pyc
Normal file
BIN
__pycache__/pptx_to_images.cpython-312.pyc
Normal file
Binary file not shown.
130
app.py
130
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 = '<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080">'
|
||||
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 x="50" y="50" font-size="20" fill="black">{text}</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'<image href="data:image/png;base64,{image_base64}" x="0" y="0" width="1920" height="1080"/>'
|
||||
svg_content += '</svg>'
|
||||
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
|
||||
|
||||
Binary file not shown.
35
pptx_to_images.py
Normal file
35
pptx_to_images.py
Normal file
@@ -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
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 537 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 85 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 374 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 77 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 64 KiB |
Reference in New Issue
Block a user