""" Content management routes """ from flask import Blueprint, render_template, request, redirect, url_for, flash, send_from_directory, current_app from flask_login import login_required from app.models.content import Content from app.models.player import Player from app.models.group import Group from app.extensions import db from app.utils.uploads import process_uploaded_files from app.routes.admin import admin_required import os bp = Blueprint('content', __name__) @bp.route('/upload', methods=['GET', 'POST']) @login_required @admin_required def upload(): """Upload content to players or groups""" if request.method == 'POST': target_type = request.form.get('target_type') target_id = request.form.get('target_id') files = request.files.getlist('files') duration = request.form.get('duration', 10, type=int) return_url = request.form.get('return_url', url_for('dashboard.index')) # Validation if not target_type or not target_id: flash('Please select a target type and target.', 'danger') return redirect(url_for('content.upload')) if not files or all(not file.filename for file in files): flash('Please select at least one file to upload.', 'danger') return redirect(url_for('content.upload')) if duration < 1: flash('Duration must be at least 1 second.', 'danger') return redirect(url_for('content.upload')) try: target_id = int(target_id) except ValueError: flash('Invalid target ID.', 'danger') return redirect(url_for('content.upload')) # Process files results = process_uploaded_files( app=current_app, files=files, duration=duration, target_type=target_type, target_id=target_id ) # Show results if results['success']: flash(f'Successfully uploaded {len(results["success"])} files.', 'success') if results['errors']: for error in results['errors']: flash(f'Error: {error}', 'danger') return redirect(return_url) # GET request - show upload form target_type = request.args.get('target_type') target_id = request.args.get('target_id') return_url = request.args.get('return_url', url_for('dashboard.index')) players = Player.query.order_by(Player.username).all() groups = Group.query.order_by(Group.name).all() return render_template( 'content/upload.html', target_type=target_type, target_id=target_id, players=players, groups=groups, return_url=return_url ) @bp.route('//edit', methods=['POST']) @login_required def edit(content_id): """Edit content duration""" content = Content.query.get_or_404(content_id) new_duration = request.form.get('duration', type=int) if not new_duration or new_duration < 1: flash('Duration must be at least 1 second.', 'danger') return redirect(request.referrer or url_for('dashboard.index')) try: content.duration = new_duration # Update playlist version for the player content.player.increment_playlist_version() db.session.commit() flash(f'Content duration updated to {new_duration} seconds.', 'success') except Exception as e: db.session.rollback() flash(f'Error updating content: {str(e)}', 'danger') return redirect(request.referrer or url_for('dashboard.index')) @bp.route('//delete', methods=['POST']) @login_required @admin_required def delete(content_id): """Delete content""" content = Content.query.get_or_404(content_id) player_id = content.player_id file_name = content.file_name try: # Delete file from disk file_path = os.path.join(current_app.static_folder, 'uploads', content.file_name) if os.path.exists(file_path): # Check if file is used by other content other_content = Content.query.filter( Content.file_name == content.file_name, Content.id != content_id ).first() if not other_content: os.remove(file_path) # Delete from database db.session.delete(content) # Update playlist version for the player player = Player.query.get(player_id) if player: player.increment_playlist_version() db.session.commit() flash(f'Content "{file_name}" deleted successfully.', 'success') except Exception as e: db.session.rollback() flash(f'Error deleting content: {str(e)}', 'danger') return redirect(request.referrer or url_for('dashboard.index')) @bp.route('/media/') def media(filename): """Serve media files""" upload_folder = os.path.join(current_app.static_folder, 'uploads') return send_from_directory(upload_folder, filename) @bp.route('/group//media//edit', methods=['POST']) @login_required @admin_required def edit_group_media(group_id, content_id): """Edit media duration for group content""" group = Group.query.get_or_404(group_id) content = Content.query.get_or_404(content_id) new_duration = request.form.get('duration', type=int) if not new_duration or new_duration < 1: flash('Duration must be at least 1 second.', 'danger') return redirect(url_for('group.manage', group_id=group_id)) try: # Update duration for all content with the same filename in the group player_ids = [player.id for player in group.players] Content.query.filter( Content.player_id.in_(player_ids), Content.file_name == content.file_name ).update({Content.duration: new_duration}) # Update playlist version for group group.increment_playlist_version() db.session.commit() flash('Media duration updated successfully.', 'success') except Exception as e: db.session.rollback() flash(f'Error updating media duration: {str(e)}', 'danger') return redirect(url_for('group.manage', group_id=group_id)) @bp.route('/group//media//delete', methods=['POST']) @login_required @admin_required def delete_group_media(group_id, content_id): """Delete media from group""" group = Group.query.get_or_404(group_id) content = Content.query.get_or_404(content_id) file_name = content.file_name try: player_ids = [player.id for player in group.players] # Get all content with the same filename in the group group_content = Content.query.filter( Content.player_id.in_(player_ids), Content.file_name == file_name ).all() # Delete all instances for content_item in group_content: db.session.delete(content_item) # Check if file is used elsewhere other_content = Content.query.filter( ~Content.player_id.in_(player_ids), Content.file_name == file_name ).first() # Delete file if not used elsewhere if not other_content: file_path = os.path.join(current_app.static_folder, 'uploads', file_name) if os.path.exists(file_path): os.remove(file_path) # Update playlist version for group group.increment_playlist_version() db.session.commit() flash('Media deleted successfully.', 'success') except Exception as e: db.session.rollback() flash(f'Error deleting media: {str(e)}', 'danger') return redirect(url_for('group.manage', group_id=group_id))