Add rename functionality for recordings
- Added /rename/<filename> API endpoint - Accepts new_name in JSON body - Automatically appends .wav extension if missing - Uses secure_filename() for safety - Checks for existing files to prevent overwrites - Backs up renamed file to USB if backup enabled - Updated web interface (template v1.6.0) - Added "Rename" button to each recording - Added renameRecording() JavaScript function - Uses prompt dialog for name input - Pre-fills current name (without .wav extension) - Reloads page after successful rename This allows users to assign guest names to recordings for easier organization (e.g., "John_Smith.wav"). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -81,7 +81,7 @@ BACKUP_ON_WRITE = BACKUP_CONFIG.get('backup_on_write', True)
|
|||||||
WEB_PORT = SYS_CONFIG['web']['port']
|
WEB_PORT = SYS_CONFIG['web']['port']
|
||||||
|
|
||||||
# Template version - increment this when HTML template changes
|
# Template version - increment this when HTML template changes
|
||||||
TEMPLATE_VERSION = "1.5.0" # Updated: Redesigned sound selection with dropdowns
|
TEMPLATE_VERSION = "1.6.0" # Updated: Added rename functionality for recordings
|
||||||
|
|
||||||
# Flask app
|
# Flask app
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@@ -945,6 +945,40 @@ def delete_recording(filename):
|
|||||||
return jsonify({"success": True})
|
return jsonify({"success": True})
|
||||||
return jsonify({"error": "File not found"}), 404
|
return jsonify({"error": "File not found"}), 404
|
||||||
|
|
||||||
|
@app.route('/rename/<filename>', methods=['POST'])
|
||||||
|
def rename_recording(filename):
|
||||||
|
"""Rename a recording"""
|
||||||
|
data = request.get_json()
|
||||||
|
new_name = data.get('new_name', '').strip()
|
||||||
|
|
||||||
|
if not new_name:
|
||||||
|
return jsonify({"error": "New name is required"}), 400
|
||||||
|
|
||||||
|
# Ensure .wav extension
|
||||||
|
if not new_name.endswith('.wav'):
|
||||||
|
new_name += '.wav'
|
||||||
|
|
||||||
|
# Sanitize filenames
|
||||||
|
old_filepath = os.path.join(OUTPUT_DIR, secure_filename(filename))
|
||||||
|
new_filepath = os.path.join(OUTPUT_DIR, secure_filename(new_name))
|
||||||
|
|
||||||
|
if not os.path.exists(old_filepath):
|
||||||
|
return jsonify({"error": "File not found"}), 404
|
||||||
|
|
||||||
|
if os.path.exists(new_filepath):
|
||||||
|
return jsonify({"error": "A file with that name already exists"}), 409
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.rename(old_filepath, new_filepath)
|
||||||
|
|
||||||
|
# Also backup renamed file if backup is enabled
|
||||||
|
if SYS_CONFIG['backup']['enabled'] and SYS_CONFIG['backup']['backup_on_write']:
|
||||||
|
backup_file_to_usb(new_filepath, 'recordings')
|
||||||
|
|
||||||
|
return jsonify({"success": True, "new_name": secure_filename(new_name)})
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
@app.route('/restore_default_sound', methods=['POST'])
|
@app.route('/restore_default_sound', methods=['POST'])
|
||||||
def restore_default_sound():
|
def restore_default_sound():
|
||||||
"""Restore default dial tone"""
|
"""Restore default dial tone"""
|
||||||
@@ -1752,10 +1786,10 @@ def main():
|
|||||||
{% for recording in recordings %}
|
{% for recording in recordings %}
|
||||||
<div class="recording-item" id="recording-{{ loop.index }}">
|
<div class="recording-item" id="recording-{{ loop.index }}">
|
||||||
<div class="recording-info">
|
<div class="recording-info">
|
||||||
<h3>{{ recording.filename }}</h3>
|
<h3 id="filename-{{ loop.index }}">{{ recording.filename }}</h3>
|
||||||
<div class="recording-meta">
|
<div class="recording-meta">
|
||||||
📅 {{ recording.date }} |
|
📅 {{ recording.date }} |
|
||||||
⏱️ {{ "%.1f"|format(recording.duration) }}s |
|
⏱️ {{ "%.1f"|format(recording.duration) }}s |
|
||||||
💾 {{ "%.2f"|format(recording.size_mb) }} MB
|
💾 {{ "%.2f"|format(recording.size_mb) }} MB
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1766,6 +1800,9 @@ def main():
|
|||||||
<button class="btn btn-primary" onclick="downloadRecording('{{ recording.filename }}')">
|
<button class="btn btn-primary" onclick="downloadRecording('{{ recording.filename }}')">
|
||||||
⬇️ Download
|
⬇️ Download
|
||||||
</button>
|
</button>
|
||||||
|
<button class="btn btn-secondary" onclick="renameRecording('{{ recording.filename }}', {{ loop.index }})">
|
||||||
|
✏️ Rename
|
||||||
|
</button>
|
||||||
<button class="btn btn-danger" onclick="deleteRecording('{{ recording.filename }}', {{ loop.index }})">
|
<button class="btn btn-danger" onclick="deleteRecording('{{ recording.filename }}', {{ loop.index }})">
|
||||||
🗑️ Delete
|
🗑️ Delete
|
||||||
</button>
|
</button>
|
||||||
@@ -1985,6 +2022,30 @@ def main():
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renameRecording(filename, index) {
|
||||||
|
// Remove .wav extension for cleaner input
|
||||||
|
const nameWithoutExt = filename.replace('.wav', '');
|
||||||
|
const newName = prompt('Enter new name for recording:', nameWithoutExt);
|
||||||
|
|
||||||
|
if (newName && newName.trim() !== '' && newName !== nameWithoutExt) {
|
||||||
|
fetch('/rename/' + filename, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ new_name: newName.trim() })
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
showAlert('Recording renamed! ✓', 'success');
|
||||||
|
setTimeout(() => location.reload(), 1500);
|
||||||
|
} else {
|
||||||
|
showAlert('Error: ' + data.error, 'error');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => showAlert('Error: ' + error, 'error'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function playAudio(type, filename) {
|
function playAudio(type, filename) {
|
||||||
const modal = document.getElementById('audio-modal');
|
const modal = document.getElementById('audio-modal');
|
||||||
const player = document.getElementById('audio-player');
|
const player = document.getElementById('audio-player');
|
||||||
|
|||||||
Reference in New Issue
Block a user