feature complete. "sorry for the convenience"

modified:   app.py
	new file:   migrations/versions/1ac5a8e0f577_user_session_table.py
This commit is contained in:
Russell Ballestrini 2024-11-23 11:32:49 -05:00
parent 6f1c7def7b
commit 0f82305087
2 changed files with 71 additions and 9 deletions

48
app.py
View file

@ -25,7 +25,7 @@ from flask import (
Response,
)
from flask_socketio import SocketIO, emit, join_room
from flask_socketio import SocketIO, emit, join_room, leave_room
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.exc import InvalidRequestError
@ -187,6 +187,14 @@ class Room(db.Model):
return self.active_users.split(",") if self.active_users else []
class UserSession(db.Model):
id = db.Column(db.Integer, primary_key=True)
session_id = db.Column(db.String(128), unique=True, nullable=False)
username = db.Column(db.String(128))
room_name = db.Column(db.String(128))
room_id = db.Column(db.Integer)
class Message(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(128), nullable=False)
@ -442,12 +450,20 @@ def search_messages(keywords):
return search_results_list
# Handle user joining a room
@socketio.on("join")
def on_join(data):
room_name = data["room_name"]
username = data["username"]
room = get_room(room_name)
room.add_user(data["username"])
room.add_user(username)
# Store session data in the database
user_session = UserSession(
session_id=request.sid, username=username, room_name=room_name, room_id=room.id
)
db.session.add(user_session)
# Emit the active users list to the new joiner
emit("active_users", {"users": room.get_active_users()}, room=request.sid)
@ -473,9 +489,6 @@ def on_join(data):
total_token_count = 0
# Send the history of messages only to the newly connected client.
# The reason for using `request.sid` here is to target the specific session (or client) that
# just connected, so only they receive the backlog of messages, rather than broadcasting
# this information to all clients in the room.
for message in previous_messages:
if not message.is_base64_image():
total_token_count += message.token_count
@ -494,18 +507,17 @@ def on_join(data):
room.title = gpt_generate_room_title(previous_messages)
db.session.add(room)
socketio.emit("update_room_title", {"title": room.title}, room=room.name)
# Emit an event to update this rooms title in the sidebar for all users.
# Emit an event to update this room's title in the sidebar for all users.
updated_room_data = {"id": room.id, "name": room.name, "title": room.title}
socketio.emit("update_room_list", updated_room_data, room=None)
# commit the active user list and title to database.
# commit session & active user list and title to database.
db.session.commit()
# Broadcast to all clients in the room that a new user has joined.
# Here, `room=room` ensures the message is sent to everyone in that specific room.
emit(
"chat_message",
{"id": None, "content": f"{data['username']} has joined the room."},
{"id": None, "content": f"{username} has joined the room."},
room=room.name,
)
emit(
@ -518,6 +530,24 @@ def on_join(data):
)
# Handle user leaving a room
@socketio.on("disconnect")
def on_disconnect():
sid = request.sid
user_session = UserSession.query.filter_by(session_id=sid).first()
if user_session:
room_name = user_session.room_name
username = user_session.username
room = Room.query.filter_by(name=room_name).first()
room.remove_user(username)
leave_room(room_name)
emit("active_users", {"users": room.get_active_users()}, room=room_name)
# Remove session data from the database
db.session.delete(user_session)
db.session.commit()
@socketio.on("chat_message")
def handle_message(data):
room_name = data["room_name"]

View file

@ -0,0 +1,32 @@
"""user session table
Revision ID: 1ac5a8e0f577
Revises: 38a330686a17
Create Date: 2024-11-23 11:25:01.723169
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import sqlite
# revision identifiers, used by Alembic.
revision = '1ac5a8e0f577'
down_revision = '38a330686a17'
branch_labels = None
depends_on = None
def upgrade():
op.create_table('user_session',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('session_id', sa.String(length=128), nullable=False),
sa.Column('username', sa.String(length=128), nullable=True),
sa.Column('room_name', sa.String(length=128), nullable=True),
sa.Column('room_id', sa.Integer(), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('session_id')
)
def downgrade():
op.drop_table('user_session')