fixed messaging!
This commit is contained in:
@@ -1,13 +1,11 @@
|
||||
from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify, send_file
|
||||
from flask_login import login_required, current_user
|
||||
from flask_socketio import emit, join_room, leave_room
|
||||
from models import db, Conversation, User, Message, MessageAttachment
|
||||
from forms import ConversationForm
|
||||
from routes.auth import require_password_change
|
||||
import os
|
||||
from werkzeug.utils import secure_filename
|
||||
from datetime import datetime
|
||||
from extensions import socketio
|
||||
|
||||
conversations_bp = Blueprint('conversations', __name__, url_prefix='/conversations')
|
||||
|
||||
@@ -239,30 +237,45 @@ def delete_conversation(conversation_id):
|
||||
flash('Conversation has been deleted successfully.', 'success')
|
||||
return redirect(url_for('conversations.conversations'))
|
||||
|
||||
@socketio.on('join_conversation')
|
||||
@conversations_bp.route('/<int:conversation_id>/messages', methods=['GET'])
|
||||
@login_required
|
||||
def on_join(data):
|
||||
conversation_id = data.get('conversation_id')
|
||||
@require_password_change
|
||||
def get_messages(conversation_id):
|
||||
conversation = Conversation.query.get_or_404(conversation_id)
|
||||
|
||||
# Check if user is a member
|
||||
if not current_user.is_admin and current_user not in conversation.members:
|
||||
return
|
||||
return jsonify({'error': 'Unauthorized'}), 403
|
||||
|
||||
# Join the room
|
||||
join_room(f'conversation_{conversation_id}')
|
||||
|
||||
@socketio.on('leave_conversation')
|
||||
@login_required
|
||||
def on_leave(data):
|
||||
conversation_id = data.get('conversation_id')
|
||||
leave_room(f'conversation_{conversation_id}')
|
||||
|
||||
@socketio.on('heartbeat')
|
||||
@login_required
|
||||
def on_heartbeat(data):
|
||||
# Just acknowledge the heartbeat to keep the connection alive
|
||||
return {'status': 'ok'}
|
||||
# Get the last message ID from the request
|
||||
last_message_id = request.args.get('last_message_id', type=int)
|
||||
|
||||
# Query for new messages
|
||||
query = Message.query.filter_by(conversation_id=conversation_id)
|
||||
if last_message_id:
|
||||
query = query.filter(Message.id > last_message_id)
|
||||
|
||||
messages = query.order_by(Message.created_at.asc()).all()
|
||||
|
||||
# Format messages for response
|
||||
message_data = [{
|
||||
'id': message.id,
|
||||
'content': message.content,
|
||||
'created_at': message.created_at.strftime('%b %d, %Y %H:%M'),
|
||||
'sender_id': str(message.user_id),
|
||||
'sender_name': f"{message.user.username} {message.user.last_name}",
|
||||
'sender_avatar': url_for('profile_pic', filename=message.user.profile_picture) if message.user.profile_picture else url_for('static', filename='default-avatar.png'),
|
||||
'attachments': [{
|
||||
'name': attachment.name,
|
||||
'size': attachment.size,
|
||||
'url': url_for('conversations.download_attachment', message_id=message.id, attachment_index=index)
|
||||
} for index, attachment in enumerate(message.attachments)]
|
||||
} for message in messages]
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'messages': message_data
|
||||
})
|
||||
|
||||
@conversations_bp.route('/<int:conversation_id>/send_message', methods=['POST'])
|
||||
@login_required
|
||||
@@ -272,59 +285,46 @@ def send_message(conversation_id):
|
||||
|
||||
# Check if user is a member
|
||||
if not current_user.is_admin and current_user not in conversation.members:
|
||||
return jsonify({'success': False, 'error': 'You do not have access to this conversation.'}), 403
|
||||
return jsonify({'error': 'Unauthorized'}), 403
|
||||
|
||||
message_content = request.form.get('message', '').strip()
|
||||
file_count = int(request.form.get('file_count', 0))
|
||||
|
||||
if not message_content and file_count == 0:
|
||||
return jsonify({'success': False, 'error': 'Message or file is required.'}), 400
|
||||
return jsonify({'error': 'Message cannot be empty'}), 400
|
||||
|
||||
# Create new message
|
||||
# Create the message
|
||||
message = Message(
|
||||
content=message_content,
|
||||
conversation_id=conversation_id,
|
||||
user_id=current_user.id
|
||||
user_id=current_user.id,
|
||||
conversation_id=conversation_id
|
||||
)
|
||||
|
||||
# Create conversation-specific directory
|
||||
conversation_dir = os.path.join(UPLOAD_FOLDER, str(conversation_id))
|
||||
os.makedirs(conversation_dir, exist_ok=True)
|
||||
db.session.add(message)
|
||||
db.session.flush() # Get the message ID
|
||||
|
||||
# Handle file attachments
|
||||
attachments = []
|
||||
for i in range(file_count):
|
||||
file = request.files.get(f'file_{i}')
|
||||
if file and file.filename:
|
||||
if not allowed_file(file.filename):
|
||||
return jsonify({'success': False, 'error': f'File type not allowed: {file.filename}'}), 400
|
||||
|
||||
if file.content_length and file.content_length > MAX_FILE_SIZE:
|
||||
return jsonify({'success': False, 'error': f'File size exceeds limit: {file.filename}'}), 400
|
||||
|
||||
# Generate unique filename
|
||||
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||
filename = secure_filename(file.filename)
|
||||
unique_filename = f"{timestamp}_{filename}"
|
||||
file_path = os.path.join(conversation_dir, unique_filename)
|
||||
|
||||
# Save file
|
||||
file.save(file_path)
|
||||
|
||||
# Create attachment record
|
||||
attachment = MessageAttachment(
|
||||
name=filename,
|
||||
path=file_path,
|
||||
type=get_file_extension(filename),
|
||||
size=os.path.getsize(file_path)
|
||||
)
|
||||
message.attachments.append(attachment)
|
||||
attachments.append(attachment)
|
||||
file_key = f'file_{i}'
|
||||
if file_key in request.files:
|
||||
file = request.files[file_key]
|
||||
if file and allowed_file(file.filename):
|
||||
filename = secure_filename(file.filename)
|
||||
file_path = os.path.join(UPLOAD_FOLDER, filename)
|
||||
file.save(file_path)
|
||||
|
||||
attachment = MessageAttachment(
|
||||
message_id=message.id,
|
||||
name=filename,
|
||||
path=file_path,
|
||||
size=os.path.getsize(file_path)
|
||||
)
|
||||
db.session.add(attachment)
|
||||
attachments.append(attachment)
|
||||
|
||||
db.session.add(message)
|
||||
db.session.commit()
|
||||
|
||||
# Prepare message data for WebSocket
|
||||
# Prepare message data for response
|
||||
message_data = {
|
||||
'id': message.id,
|
||||
'content': message.content,
|
||||
@@ -339,10 +339,6 @@ def send_message(conversation_id):
|
||||
} for index, attachment in enumerate(attachments)]
|
||||
}
|
||||
|
||||
# Emit the message to all users in the conversation room
|
||||
socketio.emit('new_message', message_data, room=f'conversation_{conversation_id}')
|
||||
|
||||
# Return response with message data
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': message_data
|
||||
@@ -369,43 +365,4 @@ def download_attachment(message_id, attachment_index):
|
||||
)
|
||||
except (IndexError, Exception) as e:
|
||||
flash('File not found.', 'error')
|
||||
return redirect(url_for('conversations.conversation', conversation_id=conversation.id))
|
||||
|
||||
@conversations_bp.route('/<int:conversation_id>/messages')
|
||||
@login_required
|
||||
@require_password_change
|
||||
def get_messages(conversation_id):
|
||||
conversation = Conversation.query.get_or_404(conversation_id)
|
||||
|
||||
# Check if user is a member
|
||||
if not current_user.is_admin and current_user not in conversation.members:
|
||||
return jsonify({'success': False, 'error': 'You do not have access to this conversation.'}), 403
|
||||
|
||||
# Get the last message ID from the request
|
||||
last_message_id = request.args.get('last_message_id', type=int)
|
||||
|
||||
# Query for new messages
|
||||
query = Message.query.filter_by(conversation_id=conversation_id)
|
||||
if last_message_id:
|
||||
query = query.filter(Message.id > last_message_id)
|
||||
|
||||
messages = query.order_by(Message.created_at.asc()).all()
|
||||
|
||||
# Format messages for response
|
||||
formatted_messages = []
|
||||
for message in messages:
|
||||
formatted_messages.append({
|
||||
'id': message.id,
|
||||
'content': message.content,
|
||||
'created_at': message.created_at.strftime('%b %d, %Y %H:%M'),
|
||||
'sender_id': str(message.user.id),
|
||||
'sender_name': f"{message.user.username} {message.user.last_name}",
|
||||
'sender_avatar': url_for('profile_pic', filename=message.user.profile_picture) if message.user.profile_picture else url_for('static', filename='default-avatar.png'),
|
||||
'attachments': [{
|
||||
'name': attachment.name,
|
||||
'size': attachment.size,
|
||||
'url': url_for('conversations.download_attachment', message_id=message.id, attachment_index=index)
|
||||
} for index, attachment in enumerate(message.attachments)]
|
||||
})
|
||||
|
||||
return jsonify({'success': True, 'messages': formatted_messages})
|
||||
return redirect(url_for('conversations.conversation', conversation_id=conversation.id))
|
||||
Reference in New Issue
Block a user