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 extensions import db, bcrypt, login_manager
|
||||||
from models import User, Player, Content, Group # Add Group to the imports
|
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 flask_login import login_user, logout_user, login_required, current_user
|
||||||
from pptx import Presentation
|
from pptx_to_images import convert_pptx_to_images # Assuming you have a module for PPTX conversion
|
||||||
import cairosvg
|
|
||||||
import os
|
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)
|
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):
|
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.
|
Calls the external pptx_to_images.py script to convert PPTX to images.
|
||||||
Each slide is saved as a separate image in the output folder.
|
|
||||||
"""
|
"""
|
||||||
|
command = [
|
||||||
|
"python", "pptx_to_images.py", input_file, output_folder
|
||||||
|
]
|
||||||
try:
|
try:
|
||||||
if not os.path.exists(output_folder):
|
subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
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}")
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except subprocess.CalledProcessError as e:
|
||||||
print(f"Error processing PPTX file: {e}")
|
print(f"Error converting PPTX: {e.stderr.decode()}")
|
||||||
return False
|
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
|
# Convert EMU to pixels
|
||||||
def emu_to_pixels(emu):
|
def emu_to_pixels(emu):
|
||||||
return int(emu / 914400 * 96)
|
return int(emu / 914400 * 96)
|
||||||
@@ -298,64 +262,30 @@ def upload_content():
|
|||||||
filename = secure_filename(file.filename)
|
filename = secure_filename(file.filename)
|
||||||
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
||||||
file.save(file_path)
|
file.save(file_path)
|
||||||
filename = secure_filename(file.filename)
|
file_ext = os.path.splitext(filename)[1].lower()
|
||||||
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'])
|
|
||||||
|
|
||||||
# Add the converted images to the playlist
|
if media_type == 'ppt':
|
||||||
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':
|
|
||||||
print(f"Processing PPT file: {file_path}")
|
print(f"Processing PPT file: {file_path}")
|
||||||
success = convert_pptx_to_images(file_path, app.config['UPLOAD_FOLDER'])
|
success = convert_pptx_to_images(file_path, app.config['UPLOAD_FOLDER'])
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
# Add each slide image to the playlist
|
|
||||||
base_name = os.path.splitext(filename)[0]
|
base_name = os.path.splitext(filename)[0]
|
||||||
for slide_image in sorted(os.listdir(app.config['UPLOAD_FOLDER'])):
|
# Find all PNGs generated for this PPTX
|
||||||
if slide_image.startswith(base_name) and slide_image.endswith('.jpg'):
|
slide_images = sorted([
|
||||||
if target_type == 'group':
|
f for f in os.listdir(app.config['UPLOAD_FOLDER'])
|
||||||
group = Group.query.get_or_404(target_id)
|
if (f.startswith(base_name) and f.endswith('.png'))
|
||||||
for player in group.players:
|
])
|
||||||
new_content = Content(file_name=slide_image, duration=duration, player_id=player.id)
|
print("Slide images found:", slide_images)
|
||||||
db.session.add(new_content)
|
if target_type == 'group':
|
||||||
elif target_type == 'player':
|
group = Group.query.get_or_404(target_id)
|
||||||
new_content = Content(file_name=slide_image, duration=duration, player_id=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)
|
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:
|
except Exception as e:
|
||||||
print(f"Error processing file {file.filename}: {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)
|
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')
|
@app.route('/admin')
|
||||||
@login_required
|
@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