Spaces:
Paused
Paused
| import uuid | |
| from flask import Flask, render_template, request | |
| from flask_socketio import SocketIO, join_room, leave_room, emit | |
| app = Flask(__name__) | |
| socketio = SocketIO(app, cors_allowed_origins="*") | |
| # In-memory matchmaking state | |
| PROFILES = {} # sid -> profile dict | |
| WAITING = [] # list of sids waiting | |
| ROOMS = {} # room_id -> (sid1, sid2) | |
| def index(): | |
| return render_template("index.html") | |
| def chat(): | |
| return render_template("chat.html") | |
| def handle_find(profile): | |
| sid = request.sid | |
| PROFILES[sid] = profile | |
| WAITING.append(sid) | |
| emit("status", {"msg": "Finding partner..."}, room=sid) | |
| try_match() | |
| def handle_disconnect(sid): | |
| # `sid` is passed in by Socket.IO on disconnect | |
| if sid in WAITING: | |
| WAITING.remove(sid) | |
| PROFILES.pop(sid, None) | |
| # Remove from 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, sid=other) | |
| ROOMS.pop(room) | |
| def handle_subscribe(data): | |
| room = data.get("room") | |
| sid = request.sid | |
| if room in ROOMS and sid in ROOMS[room]: | |
| join_room(room) | |
| emit("status", {"msg": f"Joined room {room}!"}, room=sid) | |
| else: | |
| emit("status", {"msg": "Invalid room or not in this room."}, room=sid) | |
| def handle_chat(data): | |
| room = data.get("room") | |
| msg = data.get("msg") | |
| sid = data.get("sid") or request.sid | |
| if room in ROOMS: | |
| emit("chat", {"msg": msg, "sid": sid}, room=room) | |
| def handle_leave(data): | |
| room = data.get("room") | |
| sid = request.sid | |
| emit("left", {}, room=sid) | |
| if room in ROOMS: | |
| other = next(s for s in ROOMS[room] if s != sid) | |
| emit("status", {"msg": "Partner left."}, room=other) | |
| leave_room(room, sid=other) | |
| ROOMS.pop(room) | |
| def try_match(): | |
| import random | |
| random.shuffle(WAITING) # To ensure fairness | |
| used = set() | |
| pairs = [] | |
| # === FIRST: Try matching by interest === | |
| for i, sid1 in enumerate(WAITING): | |
| if sid1 in used: continue | |
| p1 = PROFILES.get(sid1) | |
| if not p1: continue | |
| for j in range(i + 1, len(WAITING)): | |
| sid2 = WAITING[j] | |
| if sid2 in used: continue | |
| p2 = PROFILES.get(sid2) | |
| if not p2: continue | |
| # Gender filtering | |
| if p1['looking'] != 'any' and p2['gender'].lower() != p1['looking'].lower(): | |
| continue | |
| if p2['looking'] != 'any' and p1['gender'].lower() != p2['looking'].lower(): | |
| continue | |
| # Interests matching | |
| if set(p1['interests']) & set(p2['interests']): | |
| pairs.append((sid1, sid2)) | |
| used.update([sid1, sid2]) | |
| break | |
| # === SECOND: Fallback to random match (respect gender) === | |
| for i, sid1 in enumerate(WAITING): | |
| if sid1 in used: continue | |
| p1 = PROFILES.get(sid1) | |
| if not p1: continue | |
| for j in range(i + 1, len(WAITING)): | |
| sid2 = WAITING[j] | |
| if sid2 in used: continue | |
| p2 = PROFILES.get(sid2) | |
| if not p2: continue | |
| # Gender filtering only | |
| if p1['looking'] != 'any' and p2['gender'].lower() != p1['looking'].lower(): | |
| continue | |
| if p2['looking'] != 'any' and p1['gender'].lower() != p2['looking'].lower(): | |
| continue | |
| pairs.append((sid1, sid2)) | |
| used.update([sid1, sid2]) | |
| break | |
| # === Finalize pairs and assign rooms === | |
| for sid1, sid2 in pairs: | |
| for sid in (sid1, sid2): | |
| if sid in WAITING: | |
| WAITING.remove(sid) | |
| room = str(uuid.uuid4()) | |
| ROOMS[room] = (sid1, sid2) | |
| join_room(room, sid=sid1) | |
| join_room(room, sid=sid2) | |
| emit("matched", { | |
| "room": room, | |
| "my_id": PROFILES[sid1]["id"], | |
| "my_sid": sid1, | |
| "partner_id": PROFILES[sid2]["id"], | |
| "partner_sid": sid2 | |
| }, room=sid1) | |
| emit("matched", { | |
| "room": room, | |
| "my_id": PROFILES[sid2]["id"], | |
| "my_sid": sid2, | |
| "partner_id": PROFILES[sid1]["id"], | |
| "partner_sid": sid1 | |
| }, room=sid2) | |
| if __name__ == "__main__": | |
| socketio.run(app, host="0.0.0.0", port=7860) |