updated first commit
This commit is contained in:
232
app/routes/content.py
Normal file
232
app/routes/content.py
Normal file
@@ -0,0 +1,232 @@
|
||||
"""
|
||||
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('/<int:content_id>/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('/<int:content_id>/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/<path:filename>')
|
||||
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/<int:group_id>/media/<int:content_id>/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/<int:group_id>/media/<int:content_id>/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))
|
||||
Reference in New Issue
Block a user