Add revision history log and music files ZIP backup
This commit is contained in:
parent
8246f641a2
commit
cda4d57859
4 changed files with 127 additions and 14 deletions
50
app.py
50
app.py
|
|
@ -58,7 +58,7 @@ from werkzeug.utils import secure_filename
|
|||
# Project imports
|
||||
from config import Config
|
||||
from models import init_db, close_db, create_request, get_request_by_id, get_request_by_token, list_requests, update_request, now_utc, delete_request, reset_all_requests, get_db
|
||||
from models import SCHEMA, get_requests_by_email
|
||||
from models import SCHEMA, get_requests_by_email, log_revision, list_revision_history
|
||||
|
||||
# Audio metadata import
|
||||
from mutagen.mp3 import MP3
|
||||
|
|
@ -630,6 +630,8 @@ def revise(token):
|
|||
# Increment revision counter and archive current files before new versions are uploaded.
|
||||
new_count = current_count + 1
|
||||
upload_dir = Path(current_app.config['UPLOAD_FOLDER']) / str(req['id'])
|
||||
old_a, old_b = req.get('song_a_path'), req.get('song_b_path')
|
||||
new_a, new_b = old_a, old_b
|
||||
if upload_dir.exists():
|
||||
for field, version in (('song_a_path', 'A'), ('song_b_path', 'B')):
|
||||
path = req.get(field)
|
||||
|
|
@ -638,9 +640,14 @@ def revise(token):
|
|||
archived = upload_dir / f"Rev{new_count}-{old.name}"
|
||||
try:
|
||||
old.rename(archived)
|
||||
if field == 'song_a_path':
|
||||
new_a = str(archived)
|
||||
else:
|
||||
new_b = str(archived)
|
||||
req[field] = str(archived)
|
||||
except OSError:
|
||||
pass
|
||||
log_revision(req['id'], new_count, note, old_a=old_a, old_b=old_b, new_a=new_a, new_b=new_b)
|
||||
update_request(req['id'], revision_note=note, status='revisions_requested',
|
||||
song_a_path=req.get('song_a_path'), song_b_path=req.get('song_b_path'),
|
||||
customer_approved='none', revision_count=new_count)
|
||||
|
|
@ -963,7 +970,7 @@ def admin_request(rid):
|
|||
|
||||
return redirect(url_for('admin_request', rid=rid))
|
||||
|
||||
return render_template('admin/request.html', req=req, statuses=STATUS_LABELS, file_exists=file_exists, basename=basename, extra_files=extra_files, callback_url=build_prompt_callback_url(rid))
|
||||
return render_template('admin/request.html', req=req, statuses=STATUS_LABELS, file_exists=file_exists, basename=basename, extra_files=extra_files, callback_url=build_prompt_callback_url(rid), revision_history=list_revision_history(rid))
|
||||
|
||||
|
||||
@app.route('/admin/request/<int:rid>/delete', methods=['POST'])
|
||||
|
|
@ -1088,19 +1095,20 @@ def admin_settings():
|
|||
action = request.form.get('action')
|
||||
|
||||
if action == 'fix_db':
|
||||
# Attempt to add missing columns via ALTER TABLE.
|
||||
if not health['ok'] and health['missing_columns']:
|
||||
try:
|
||||
db = get_db()
|
||||
# Attempt to create missing tables and add missing columns via ALTER TABLE.
|
||||
try:
|
||||
db = get_db()
|
||||
db.executescript(SCHEMA)
|
||||
if not health['ok'] and health['missing_columns']:
|
||||
for col in health['missing_columns']:
|
||||
# Default to TEXT columns; adequate for current schema.
|
||||
db.execute(f'ALTER TABLE requests ADD COLUMN {col} TEXT')
|
||||
db.commit()
|
||||
flash(f'Added missing columns: {", ".join(health["missing_columns"])}. Please refresh the page.', 'success')
|
||||
except Exception as e:
|
||||
flash(f'Failed to fix database: {e}', 'error')
|
||||
else:
|
||||
flash('No columns need fixing.', 'success')
|
||||
flash(f'Created missing tables and added columns: {", ".join(health["missing_columns"])}. Please refresh the page.', 'success')
|
||||
else:
|
||||
flash('Database schema is up to date.', 'success')
|
||||
db.commit()
|
||||
except Exception as e:
|
||||
flash(f'Failed to fix database: {e}', 'error')
|
||||
return redirect(url_for('admin_settings'))
|
||||
|
||||
elif action == 'reset_system':
|
||||
|
|
@ -1199,6 +1207,24 @@ def admin_settings():
|
|||
flash('Database file not found.', 'error')
|
||||
return redirect(url_for('admin_settings'))
|
||||
|
||||
elif action == 'download_uploads_zip':
|
||||
# Zip all files under UPLOAD_FOLDER and send as a download.
|
||||
import zipfile
|
||||
zip_path = db_path.with_suffix('.uploads-' + str(int(time.time())) + '.zip')
|
||||
try:
|
||||
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
|
||||
if upload_root.exists():
|
||||
for entry in upload_root.rglob('*'):
|
||||
if entry.is_file():
|
||||
zf.write(str(entry), str(entry.relative_to(upload_root)))
|
||||
return send_file(str(zip_path), as_attachment=True, download_name='theme-song-booth-uploads.zip')
|
||||
except Exception as e:
|
||||
flash(f'Failed to create uploads ZIP: {e}', 'error')
|
||||
return redirect(url_for('admin_settings'))
|
||||
finally:
|
||||
if zip_path.exists():
|
||||
zip_path.unlink()
|
||||
|
||||
elif action == 'restore_db':
|
||||
# Replace the current database file with an uploaded SQLite backup.
|
||||
file_obj = request.files.get('db_backup')
|
||||
|
|
|
|||
Reference in a new issue