Add database cleanup buttons
This commit is contained in:
177
routes/admin.py
177
routes/admin.py
@@ -62,6 +62,183 @@ def sync_files():
|
||||
db.session.add(rf)
|
||||
db.session.commit()
|
||||
return jsonify({'success': True, 'message': 'File system synchronized successfully'})
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
@admin.route('/api/admin/verify-db-state', methods=['GET'])
|
||||
@login_required
|
||||
def verify_db_state():
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'error': 'Unauthorized'}), 403
|
||||
|
||||
try:
|
||||
DATA_ROOT = '/data/rooms'
|
||||
verification_results = {
|
||||
'rooms_checked': 0,
|
||||
'files_in_db_not_fs': [],
|
||||
'files_in_fs_not_db': [],
|
||||
'permission_mismatches': [],
|
||||
'size_mismatches': [],
|
||||
'modified_time_mismatches': [],
|
||||
'total_files_checked': 0,
|
||||
'total_folders_checked': 0
|
||||
}
|
||||
|
||||
rooms = Room.query.all()
|
||||
for room in rooms:
|
||||
verification_results['rooms_checked'] += 1
|
||||
room_dir = os.path.join(DATA_ROOT, str(room.id))
|
||||
|
||||
# Get all files and folders from database for this room
|
||||
db_files = RoomFile.query.filter_by(room_id=room.id, deleted=False).all()
|
||||
db_paths = {(f.path, f.name): f for f in db_files}
|
||||
|
||||
# Check filesystem if directory exists
|
||||
if os.path.exists(room_dir):
|
||||
for root, dirs, files in os.walk(room_dir):
|
||||
rel_root = os.path.relpath(root, room_dir)
|
||||
rel_path = '' if rel_root == '.' else rel_root.replace('\\', '/')
|
||||
|
||||
# Check folders
|
||||
for d in dirs:
|
||||
verification_results['total_folders_checked'] += 1
|
||||
folder_path = os.path.join(root, d)
|
||||
stat = os.stat(folder_path)
|
||||
|
||||
# Check if folder exists in database
|
||||
db_file = db_paths.get((rel_path, d))
|
||||
if not db_file:
|
||||
verification_results['files_in_fs_not_db'].append({
|
||||
'room_id': room.id,
|
||||
'room_name': room.name,
|
||||
'path': rel_path,
|
||||
'name': d,
|
||||
'type': 'folder'
|
||||
})
|
||||
else:
|
||||
# Verify folder metadata
|
||||
if abs(stat.st_mtime - db_file.modified) > 1: # Allow 1 second difference
|
||||
verification_results['modified_time_mismatches'].append({
|
||||
'room_id': room.id,
|
||||
'room_name': room.name,
|
||||
'path': rel_path,
|
||||
'name': d,
|
||||
'type': 'folder',
|
||||
'fs_modified': stat.st_mtime,
|
||||
'db_modified': db_file.modified
|
||||
})
|
||||
# Remove from db_paths as we've checked it
|
||||
db_paths.pop((rel_path, d), None)
|
||||
|
||||
# Check files
|
||||
for f in files:
|
||||
verification_results['total_files_checked'] += 1
|
||||
file_path = os.path.join(root, f)
|
||||
stat = os.stat(file_path)
|
||||
|
||||
# Check if file exists in database
|
||||
db_file = db_paths.get((rel_path, f))
|
||||
if not db_file:
|
||||
verification_results['files_in_fs_not_db'].append({
|
||||
'room_id': room.id,
|
||||
'room_name': room.name,
|
||||
'path': rel_path,
|
||||
'name': f,
|
||||
'type': 'file'
|
||||
})
|
||||
else:
|
||||
# Verify file metadata
|
||||
if abs(stat.st_mtime - db_file.modified) > 1: # Allow 1 second difference
|
||||
verification_results['modified_time_mismatches'].append({
|
||||
'room_id': room.id,
|
||||
'room_name': room.name,
|
||||
'path': rel_path,
|
||||
'name': f,
|
||||
'type': 'file',
|
||||
'fs_modified': stat.st_mtime,
|
||||
'db_modified': db_file.modified
|
||||
})
|
||||
if stat.st_size != db_file.size:
|
||||
verification_results['size_mismatches'].append({
|
||||
'room_id': room.id,
|
||||
'room_name': room.name,
|
||||
'path': rel_path,
|
||||
'name': f,
|
||||
'type': 'file',
|
||||
'fs_size': stat.st_size,
|
||||
'db_size': db_file.size
|
||||
})
|
||||
# Remove from db_paths as we've checked it
|
||||
db_paths.pop((rel_path, f), None)
|
||||
|
||||
# Any remaining items in db_paths are in DB but not in filesystem
|
||||
for (path, name), db_file in db_paths.items():
|
||||
verification_results['files_in_db_not_fs'].append({
|
||||
'room_id': room.id,
|
||||
'room_name': room.name,
|
||||
'path': path,
|
||||
'name': name,
|
||||
'type': db_file.type
|
||||
})
|
||||
|
||||
# Calculate total issues
|
||||
total_issues = (
|
||||
len(verification_results['files_in_db_not_fs']) +
|
||||
len(verification_results['files_in_fs_not_db']) +
|
||||
len(verification_results['permission_mismatches']) +
|
||||
len(verification_results['size_mismatches']) +
|
||||
len(verification_results['modified_time_mismatches'])
|
||||
)
|
||||
|
||||
# Add summary statistics
|
||||
verification_results['summary'] = {
|
||||
'total_issues': total_issues,
|
||||
'status': 'healthy' if total_issues == 0 else 'issues_found'
|
||||
}
|
||||
|
||||
return jsonify(verification_results)
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
@admin.route('/api/admin/cleanup-orphaned-records', methods=['POST'])
|
||||
@login_required
|
||||
def cleanup_orphaned_records():
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'error': 'Unauthorized'}), 403
|
||||
|
||||
try:
|
||||
DATA_ROOT = '/data/rooms'
|
||||
rooms = Room.query.all()
|
||||
cleaned_records = []
|
||||
|
||||
for room in rooms:
|
||||
room_dir = os.path.join(DATA_ROOT, str(room.id))
|
||||
|
||||
# Get all files and folders from database for this room
|
||||
db_files = RoomFile.query.filter_by(room_id=room.id, deleted=False).all()
|
||||
|
||||
for db_file in db_files:
|
||||
file_path = os.path.join(room_dir, db_file.path, db_file.name) if db_file.path else os.path.join(room_dir, db_file.name)
|
||||
|
||||
# If file doesn't exist in filesystem, mark it as deleted in database
|
||||
if not os.path.exists(file_path):
|
||||
db_file.deleted = True
|
||||
cleaned_records.append({
|
||||
'room_id': room.id,
|
||||
'room_name': room.name,
|
||||
'path': db_file.path,
|
||||
'name': db_file.name,
|
||||
'type': db_file.type
|
||||
})
|
||||
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': f'Cleaned up {len(cleaned_records)} orphaned records',
|
||||
'cleaned_records': cleaned_records
|
||||
})
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return jsonify({'error': str(e)}), 500
|
||||
Reference in New Issue
Block a user