File size: 3,571 Bytes
16a9a79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22d703d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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")  
    if room in ROOMS:  
        emit("chat", {"msg": msg}, 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 = []

    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.add(sid1)
                used.add(sid2)
                break

    # Remove matched from waiting, make 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}, room=sid1)
        emit("matched", {"room": room}, room=sid2)
  
if __name__ == "__main__":  
    socketio.run(app, host="0.0.0.0", port=7860)