Spaces:
Running
Running
import uuid | |
time | |
from flask import Flask, render_template, request, redirect, url_for, session | |
from flask_socketio import SocketIO, join_room, leave_room, emit | |
import time | |
app = Flask(__name__) | |
app.secret_key = 'replace-with-secure-key' | |
socketio = SocketIO(app, cors_allowed_origins='*') | |
# In-memory storage (reset when container restarts) | |
PEOPLE = {} # sid -> {id, gender, age, interests:list} | |
WAITING = [] # list of sids waiting for match | |
ROOMS = {} # room_id -> (sid1, sid2) | |
def index(): | |
if request.method == 'POST': | |
# Create profile | |
profile = { | |
'id': request.form['id'], | |
'gender': request.form['gender'], | |
'age': request.form['age'], | |
'interests': request.form.getlist('interests') | |
} | |
session['profile'] = profile | |
return render_template('index.html', waiting=True) | |
return render_template('index.html', waiting=False) | |
def on_connect(): | |
# assign user sid | |
if 'profile' not in session: | |
return False | |
sid = request.sid | |
PEOPLE[sid] = session['profile'] | |
WAITING.append(sid) | |
emit('status', {'msg': 'Finding partner...'}, room=sid) | |
try_match() | |
def on_disconnect(): | |
sid = request.sid | |
# remove from waiting | |
if sid in WAITING: | |
WAITING.remove(sid) | |
# remove from PEOPLE | |
PEOPLE.pop(sid, None) | |
# tear down any room | |
for room, pair in list(ROOMS.items()): | |
if sid in pair: | |
other = pair[1] if pair[0]==sid else pair[0] | |
emit('status', {'msg': 'Partner left.'}, room=other) | |
leave_room(room) | |
ROOMS.pop(room) | |
def on_chat(data): | |
room = data['room'] | |
text = data['msg'] | |
emit('chat', {'msg': text}, room=room) | |
def on_leave(data): | |
room = data['room'] | |
sid = request.sid | |
# confirm leave | |
emit('left', {}, room=sid) | |
# notify partner | |
other = [s for s in ROOMS[room] if s != sid][0] | |
emit('status', {'msg': 'Partner left.'}, room=other) | |
leave_room(room) | |
ROOMS.pop(room, None) | |
def try_match(): | |
# match waiting users | |
while len(WAITING) >= 2: | |
s1 = WAITING.pop(0) | |
# find interest match | |
prefs1 = set(PEOPLE[s1]['interests']) | |
# scan for s2 | |
idx = 0; found = None | |
for i, s2 in enumerate(WAITING): | |
if prefs1 & set(PEOPLE[s2]['interests']): | |
found = i; break | |
if found is None: | |
# no common interest: pick random | |
idx = 0; s2 = WAITING.pop(0) | |
else: | |
idx = found; s2 = WAITING.pop(found) | |
room = str(uuid.uuid4()) | |
ROOMS[room] = (s1, s2) | |
join_room(room, sid=s1) | |
join_room(room, sid=s2) | |
# notify both | |
emit('matched', {'room': room}, room=s1) | |
emit('matched', {'room': room}, room=s2) | |
if __name__ == '__main__': | |
socketio.run(app, host='0.0.0.0', port=7860) |