Spaces:
Running
Running
File size: 4,737 Bytes
16a9a79 a10cb30 16a9a79 2d37f90 22d703d 2d37f90 22d703d 2d37f90 22d703d 2d37f90 22d703d 2d37f90 ef64087 bd548c2 ef64087 bd548c2 2d37f90 16a9a79 cda539a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
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)
@app.route("/", methods=["GET"])
def index():
return render_template("index.html")
@app.route("/chat", methods=["GET"])
def chat():
return render_template("chat.html")
@socketio.on("find")
def handle_find(profile):
sid = request.sid
PROFILES[sid] = profile
WAITING.append(sid)
emit("status", {"msg": "Finding partner..."}, room=sid)
try_match()
@socketio.on("disconnect")
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)
@socketio.on("subscribe")
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)
@socketio.on("chat")
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)
@socketio.on("leave")
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) |