Update app.py
Browse files
app.py
CHANGED
@@ -14,10 +14,18 @@ from PIL import Image
|
|
14 |
import requests
|
15 |
import random
|
16 |
import string
|
|
|
|
|
17 |
|
18 |
app = Flask(__name__)
|
19 |
CORS(app)
|
20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
# In-memory storage
|
22 |
SECRETS = {} # { id: { data, file_data, file_type, expire_at, view_once, theme, analytics, etc. } }
|
23 |
SHORT_LINKS = {} # { short_id: full_id }
|
@@ -519,6 +527,168 @@ def cleanup_expired():
|
|
519 |
except Exception as e:
|
520 |
return jsonify({"error": str(e)}), 500
|
521 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
522 |
# Error handlers
|
523 |
@app.errorhandler(404)
|
524 |
def not_found(error):
|
@@ -540,6 +710,7 @@ if __name__ == "__main__":
|
|
540 |
print(" β
Multiple themes")
|
541 |
print(" β
Password hints")
|
542 |
print(" β
verify_only parameter support")
|
|
|
543 |
print("π Server running on http://0.0.0.0:7860")
|
544 |
|
545 |
-
|
|
|
14 |
import requests
|
15 |
import random
|
16 |
import string
|
17 |
+
from flask_socketio import SocketIO, emit, join_room, leave_room
|
18 |
+
import threading
|
19 |
|
20 |
app = Flask(__name__)
|
21 |
CORS(app)
|
22 |
|
23 |
+
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='threading')
|
24 |
+
|
25 |
+
# ADD THIS new storage for chat rooms:
|
26 |
+
CHAT_ROOMS = {} # { room_id: { admin_session, active_sessions, settings, created_at, expires_at } }
|
27 |
+
CHAT_MESSAGES = {}
|
28 |
+
|
29 |
# In-memory storage
|
30 |
SECRETS = {} # { id: { data, file_data, file_type, expire_at, view_once, theme, analytics, etc. } }
|
31 |
SHORT_LINKS = {} # { short_id: full_id }
|
|
|
527 |
except Exception as e:
|
528 |
return jsonify({"error": str(e)}), 500
|
529 |
|
530 |
+
# ADD THESE CHAT ENDPOINTS:
|
531 |
+
|
532 |
+
@app.route("/api/chat/create", methods=["POST"])
|
533 |
+
def create_chat_room():
|
534 |
+
try:
|
535 |
+
form = request.form
|
536 |
+
ttl = int(form.get("ttl", 3600)) # Default 1 hour
|
537 |
+
max_receivers = int(form.get("max_receivers", 5))
|
538 |
+
password = form.get("password", "")
|
539 |
+
allow_files = form.get("allow_files", "true").lower() == "true"
|
540 |
+
|
541 |
+
room_id = str(uuid.uuid4())
|
542 |
+
admin_session = str(uuid.uuid4()) # Generate admin session
|
543 |
+
|
544 |
+
CHAT_ROOMS[room_id] = {
|
545 |
+
"admin_session": admin_session,
|
546 |
+
"created_at": time.time(),
|
547 |
+
"expires_at": time.time() + ttl,
|
548 |
+
"settings": {
|
549 |
+
"max_receivers": max_receivers,
|
550 |
+
"password": password,
|
551 |
+
"allow_files": allow_files,
|
552 |
+
"burn_on_admin_exit": True
|
553 |
+
},
|
554 |
+
"active_sessions": {},
|
555 |
+
"receiver_counter": 0
|
556 |
+
}
|
557 |
+
|
558 |
+
CHAT_MESSAGES[room_id] = []
|
559 |
+
|
560 |
+
base_url = request.host_url.rstrip('/')
|
561 |
+
chat_url = f"{base_url}/tools/sharelock?chat={room_id}&admin={admin_session}"
|
562 |
+
|
563 |
+
return jsonify({
|
564 |
+
"room_id": room_id,
|
565 |
+
"admin_session": admin_session,
|
566 |
+
"chat_url": chat_url,
|
567 |
+
"expires_at": CHAT_ROOMS[room_id]["expires_at"]
|
568 |
+
})
|
569 |
+
|
570 |
+
except Exception as e:
|
571 |
+
return jsonify({"error": str(e)}), 500
|
572 |
+
|
573 |
+
@app.route("/api/chat/join/<room_id>")
|
574 |
+
def join_chat_room(room_id):
|
575 |
+
try:
|
576 |
+
password = request.args.get("password", "")
|
577 |
+
admin_session = request.args.get("admin", "")
|
578 |
+
|
579 |
+
if room_id not in CHAT_ROOMS:
|
580 |
+
return jsonify({"error": "Chat room not found"}), 404
|
581 |
+
|
582 |
+
room = CHAT_ROOMS[room_id]
|
583 |
+
|
584 |
+
# Check if expired
|
585 |
+
if time.time() > room["expires_at"]:
|
586 |
+
return jsonify({"error": "Chat room has expired"}), 410
|
587 |
+
|
588 |
+
# Check password
|
589 |
+
if room["settings"]["password"] and password != room["settings"]["password"]:
|
590 |
+
return jsonify({"error": "Wrong password"}), 403
|
591 |
+
|
592 |
+
# Determine role
|
593 |
+
if admin_session == room["admin_session"]:
|
594 |
+
role = "admin"
|
595 |
+
session_id = admin_session
|
596 |
+
else:
|
597 |
+
# Check max receivers
|
598 |
+
active_receivers = sum(1 for s in room["active_sessions"].values() if s["role"] == "receiver")
|
599 |
+
if active_receivers >= room["settings"]["max_receivers"]:
|
600 |
+
return jsonify({"error": "Chat room is full"}), 403
|
601 |
+
|
602 |
+
role = "receiver"
|
603 |
+
session_id = str(uuid.uuid4())
|
604 |
+
room["receiver_counter"] += 1
|
605 |
+
|
606 |
+
return jsonify({
|
607 |
+
"session_id": session_id,
|
608 |
+
"role": role,
|
609 |
+
"receiver_number": room["receiver_counter"] if role == "receiver" else None,
|
610 |
+
"room_settings": room["settings"],
|
611 |
+
"expires_at": room["expires_at"]
|
612 |
+
})
|
613 |
+
|
614 |
+
except Exception as e:
|
615 |
+
return jsonify({"error": str(e)}), 500
|
616 |
+
|
617 |
+
# ADD WEBSOCKET EVENTS:
|
618 |
+
@socketio.on('join_chat')
|
619 |
+
def handle_join_chat(data):
|
620 |
+
room_id = data['room_id']
|
621 |
+
session_id = data['session_id']
|
622 |
+
role = data['role']
|
623 |
+
|
624 |
+
if room_id not in CHAT_ROOMS:
|
625 |
+
return
|
626 |
+
|
627 |
+
join_room(room_id)
|
628 |
+
|
629 |
+
# Add to active sessions
|
630 |
+
CHAT_ROOMS[room_id]["active_sessions"][session_id] = {
|
631 |
+
"role": role,
|
632 |
+
"receiver_number": data.get('receiver_number'),
|
633 |
+
"joined_at": time.time(),
|
634 |
+
"last_seen": time.time()
|
635 |
+
}
|
636 |
+
|
637 |
+
# Notify others
|
638 |
+
emit('user_joined', {
|
639 |
+
'role': role,
|
640 |
+
'receiver_number': data.get('receiver_number'),
|
641 |
+
'active_count': len(CHAT_ROOMS[room_id]["active_sessions"])
|
642 |
+
}, room=room_id, include_self=False)
|
643 |
+
|
644 |
+
@socketio.on('send_chat_message')
|
645 |
+
def handle_chat_message(data):
|
646 |
+
room_id = data['room_id']
|
647 |
+
session_id = data['session_id']
|
648 |
+
|
649 |
+
if room_id not in CHAT_ROOMS or session_id not in CHAT_ROOMS[room_id]["active_sessions"]:
|
650 |
+
return
|
651 |
+
|
652 |
+
session = CHAT_ROOMS[room_id]["active_sessions"][session_id]
|
653 |
+
|
654 |
+
message = {
|
655 |
+
"id": str(uuid.uuid4()),
|
656 |
+
"sender_role": session["role"],
|
657 |
+
"sender_number": session.get("receiver_number"),
|
658 |
+
"content": data['content'],
|
659 |
+
"timestamp": time.time(),
|
660 |
+
"type": "text"
|
661 |
+
}
|
662 |
+
|
663 |
+
CHAT_MESSAGES[room_id].append(message)
|
664 |
+
|
665 |
+
# Broadcast to room
|
666 |
+
emit('new_message', message, room=room_id)
|
667 |
+
|
668 |
+
@socketio.on('leave_chat')
|
669 |
+
def handle_leave_chat(data):
|
670 |
+
room_id = data['room_id']
|
671 |
+
session_id = data['session_id']
|
672 |
+
|
673 |
+
if room_id in CHAT_ROOMS and session_id in CHAT_ROOMS[room_id]["active_sessions"]:
|
674 |
+
session = CHAT_ROOMS[room_id]["active_sessions"][session_id]
|
675 |
+
del CHAT_ROOMS[room_id]["active_sessions"][session_id]
|
676 |
+
|
677 |
+
# If admin left and burn_on_admin_exit is true
|
678 |
+
if session["role"] == "admin" and CHAT_ROOMS[room_id]["settings"]["burn_on_admin_exit"]:
|
679 |
+
emit('room_closing', {'reason': 'Admin left the room'}, room=room_id)
|
680 |
+
del CHAT_ROOMS[room_id]
|
681 |
+
if room_id in CHAT_MESSAGES:
|
682 |
+
del CHAT_MESSAGES[room_id]
|
683 |
+
else:
|
684 |
+
emit('user_left', {
|
685 |
+
'role': session["role"],
|
686 |
+
'receiver_number': session.get("receiver_number"),
|
687 |
+
'active_count': len(CHAT_ROOMS[room_id]["active_sessions"])
|
688 |
+
}, room=room_id)
|
689 |
+
|
690 |
+
leave_room(room_id)
|
691 |
+
|
692 |
# Error handlers
|
693 |
@app.errorhandler(404)
|
694 |
def not_found(error):
|
|
|
710 |
print(" β
Multiple themes")
|
711 |
print(" β
Password hints")
|
712 |
print(" β
verify_only parameter support")
|
713 |
+
print(" β
Real-time chat rooms") # ADD THIS LINE
|
714 |
print("π Server running on http://0.0.0.0:7860")
|
715 |
|
716 |
+
socketio.run(app, host="0.0.0.0", port=7860, debug=True) # CHANGE THIS LINE
|