This commit is contained in:
2025-06-26 21:02:04 +03:00
parent e99e3a2263
commit f04e91ee08
10 changed files with 64 additions and 101 deletions

Binary file not shown.

Binary file not shown.

130
app.py
View File

@@ -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
View 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