diff --git a/Dockerfile b/Dockerfile index dbbc95e..9c52b28 100644 --- a/Dockerfile +++ b/Dockerfile @@ -58,7 +58,6 @@ COPY --from=build /root/.cargo /root/.cargo COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt RUN pip install gunicorn -RUN apt-get update && apt-get install -y libreoffice poppler-utils # Make port 5000 available to the world outside this container EXPOSE 5000 diff --git a/__pycache__/app.cpython-311.pyc b/__pycache__/app.cpython-311.pyc index 6f41b6b..453db49 100644 Binary files a/__pycache__/app.cpython-311.pyc and b/__pycache__/app.cpython-311.pyc differ diff --git a/app.py b/app.py index d1b771f..6dcc24c 100644 --- a/app.py +++ b/app.py @@ -8,6 +8,10 @@ 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 +from pptx.util import Inches +from PIL import Image +import io app = Flask(__name__, instance_relative_config=True) @@ -55,6 +59,10 @@ def convert_ppt_to_pdf(input_file, output_file): command = ['libreoffice', '--headless', '--convert-to', 'pdf', '--outdir', os.path.dirname(output_file), input_file] subprocess.run(command, check=True) +# Convert EMU to pixels +def emu_to_pixels(emu): + return int(emu / 914400 * 96) + @app.route('/') @login_required def dashboard(): @@ -107,50 +115,61 @@ def upload_content(): duration = int(request.form['duration']) return_url = request.form['return_url'] media_type = request.form['media_type'] - + + print(f"Redirecting to: {return_url}") # Debugging: Log the return_url + for file in files: filename = secure_filename(file.filename) file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(file_path) - # Handle PDF to JPG conversion - if media_type == 'pdf': - images = convert_from_path(file_path, dpi=300) - for i, image in enumerate(images): - image_filename = f"{os.path.splitext(filename)[0]}_{i + 1}.jpg" - image_path = os.path.join(app.config['UPLOAD_FOLDER'], image_filename) - image.save(image_path, 'JPEG') - - # Add each converted image 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=image_filename, duration=duration, player_id=player.id) + # Handle PPT/PPTX to JPG conversion + if media_type == 'ppt': + try: + presentation = Presentation(file_path) + for i, slide in enumerate(presentation.slides): + slide_width = emu_to_pixels(presentation.slide_width) + slide_height = emu_to_pixels(presentation.slide_height) + img = Image.new('RGB', (slide_width, slide_height), 'white') + + # Save the slide as an image + image_filename = f"{os.path.splitext(filename)[0]}_slide_{i + 1}.jpg" + image_path = os.path.join(app.config['UPLOAD_FOLDER'], image_filename) + img.save(image_path, 'JPEG') + + # Add each converted image 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=image_filename, duration=duration, player_id=player.id) + db.session.add(new_content) + elif target_type == 'player': + new_content = Content(file_name=image_filename, duration=duration, player_id=target_id) db.session.add(new_content) - elif target_type == 'player': - new_content = Content(file_name=image_filename, duration=duration, player_id=target_id) - db.session.add(new_content) - - # Optionally, delete the original PDF file after conversion - os.remove(file_path) + finally: + # Ensure the original PPT file is deleted after processing + if os.path.exists(file_path): + os.remove(file_path) # Handle other media types - elif media_type in ['image', 'video', 'ppt']: - if media_type == 'ppt': - ppt_output_file = os.path.splitext(file_path)[0] + '.pdf' - convert_ppt_to_pdf(file_path, ppt_output_file) - os.remove(file_path) # Remove the original PPT file - file_path = ppt_output_file + elif media_type in ['image', 'video', 'pdf']: + if media_type == 'pdf': + images = convert_from_path(file_path, dpi=300) + for i, image in enumerate(images): + image_filename = f"{os.path.splitext(filename)[0]}_{i + 1}.jpg" + image_path = os.path.join(app.config['UPLOAD_FOLDER'], image_filename) + image.save(image_path, 'JPEG') + if target_type == 'group': + group = Group.query.get_or_404(target_id) + for player in group.players: + new_content = Content(file_name=image_filename, duration=duration, player_id=player.id) + db.session.add(new_content) + elif target_type == 'player': + new_content = Content(file_name=image_filename, duration=duration, player_id=target_id) + db.session.add(new_content) + if os.path.exists(file_path): + os.remove(file_path) - 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) - db.session.commit() return redirect(return_url) @@ -158,7 +177,6 @@ def upload_content(): target_id = request.args.get('target_id') return_url = request.args.get('return_url', url_for('dashboard')) - # Serialize players and groups into JSON-serializable dictionaries players = [{'id': player.id, 'username': player.username} for player in Player.query.filter(~Player.groups.any()).all()] groups = [{'id': group.id, 'name': group.name} for group in Group.query.all()] diff --git a/docker-compose.yml b/docker-compose.yml index f082a8b..51fb980 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,3 +19,4 @@ services: # when setting allready exist and data are setted and is performed an update use second line of command command: sh -c "python clear_db.py && python init_db.py && gunicorn -w 4 -b 0.0.0.0:5000 app:app" #command: sh -c "python init_db.py && gunicorn -w 4 -b 0.0.0.0:5000 app:app" + restart: unless-stopped \ No newline at end of file diff --git a/instance/dashboard.db b/instance/dashboard.db index d68bedb..a7f8c0f 100644 Binary files a/instance/dashboard.db and b/instance/dashboard.db differ diff --git a/requirements.txt b/requirements.txt index e1b948d..c947f8d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,4 +18,5 @@ Werkzeug==3.1.3 gunicorn==20.1.0 pdf2image==1.17.0 pillow==11.1.0 +python-pptx==0.6.21 setuptools==75.8.0 \ No newline at end of file diff --git a/static/uploads/merged_1.jpg b/static/uploads/merged_1.jpg new file mode 100644 index 0000000..1a56da3 Binary files /dev/null and b/static/uploads/merged_1.jpg differ diff --git a/static/uploads/merged_2.jpg b/static/uploads/merged_2.jpg new file mode 100644 index 0000000..915fc85 Binary files /dev/null and b/static/uploads/merged_2.jpg differ diff --git a/static/uploads/Operational_Plan_FY25_1.jpg b/static/uploads/merged_3.jpg similarity index 100% rename from static/uploads/Operational_Plan_FY25_1.jpg rename to static/uploads/merged_3.jpg diff --git a/static/uploads/welcome_Prodrive_slide_1.jpg b/static/uploads/welcome_Prodrive_slide_1.jpg new file mode 100644 index 0000000..4558cd1 Binary files /dev/null and b/static/uploads/welcome_Prodrive_slide_1.jpg differ diff --git a/templates/upload_content.html b/templates/upload_content.html index 3175770..8e75487 100644 --- a/templates/upload_content.html +++ b/templates/upload_content.html @@ -15,22 +15,24 @@ .dark-mode label, .dark-mode th, .dark-mode td { color: #ffffff; } - .popup-message { - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - background-color: rgba(0, 0, 0, 0.8); - color: white; - padding: 20px; - border-radius: 10px; - display: none; - z-index: 1000; - } .logo { max-height: 100px; margin-right: 20px; } + /* Modal styling for dark mode */ + .modal-content.dark-mode { + background-color: #1e1e1e; + color: #ffffff; + } + .modal-header.dark-mode { + border-bottom: 1px solid #444; + } + .modal-footer.dark-mode { + border-top: 1px solid #444; + } + .progress-bar { + background-color: #007bff; + }
@@ -41,7 +43,7 @@ {% endif %}