Upload files to "/"
This commit is contained in:
93
app.py
Normal file
93
app.py
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
from flask import Flask, render_template
|
||||||
|
from flask_socketio import SocketIO, emit
|
||||||
|
import ssl
|
||||||
|
import os
|
||||||
|
|
||||||
|
app = Flask(__name__, static_folder='static', template_folder='templates')
|
||||||
|
app.config['SECRET_KEY'] = 'your-secret-key-change-this-in-production'
|
||||||
|
socketio = SocketIO(app, cors_allowed_origins="*")
|
||||||
|
|
||||||
|
# Store connected clients with their usernames
|
||||||
|
connected_clients = {} # Format: {session_id: {'username': 'name', 'connected_at': timestamp}}
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
return render_template('index.html')
|
||||||
|
|
||||||
|
@socketio.on('connect')
|
||||||
|
def handle_connect(auth):
|
||||||
|
from flask import request
|
||||||
|
print(f'Client connected: {request.sid}') # type: ignore
|
||||||
|
connected_clients[request.sid] = {'username': None, 'connected_at': None} # type: ignore
|
||||||
|
|
||||||
|
@socketio.on('disconnect')
|
||||||
|
def handle_disconnect():
|
||||||
|
from flask import request
|
||||||
|
print(f'Client disconnected: {request.sid}') # type: ignore
|
||||||
|
if request.sid in connected_clients: # type: ignore
|
||||||
|
del connected_clients[request.sid] # type: ignore
|
||||||
|
# Notify other clients about disconnection
|
||||||
|
emit('user_disconnected', {'id': request.sid}, broadcast=True, include_self=False) # type: ignore
|
||||||
|
|
||||||
|
@socketio.on('offer')
|
||||||
|
def handle_offer(data):
|
||||||
|
from flask import request
|
||||||
|
print(f'Received offer from {request.sid}') # type: ignore
|
||||||
|
# Broadcast offer to all other clients
|
||||||
|
data['id'] = request.sid # type: ignore
|
||||||
|
emit('offer', data, broadcast=True, include_self=False)
|
||||||
|
|
||||||
|
@socketio.on('answer')
|
||||||
|
def handle_answer(data):
|
||||||
|
from flask import request
|
||||||
|
print(f'Received answer from {request.sid}') # type: ignore
|
||||||
|
# Send answer to specific client
|
||||||
|
emit('answer', data, to=data['id'])
|
||||||
|
|
||||||
|
@socketio.on('ice_candidate')
|
||||||
|
def handle_ice_candidate(data):
|
||||||
|
from flask import request
|
||||||
|
print(f'Received ICE candidate from {request.sid}') # type: ignore
|
||||||
|
# Broadcast ICE candidate to all other clients or specific client
|
||||||
|
if 'target_id' in data:
|
||||||
|
emit('ice_candidate', data, to=data['target_id'])
|
||||||
|
else:
|
||||||
|
emit('ice_candidate', data, broadcast=True, include_self=False)
|
||||||
|
|
||||||
|
@socketio.on('join_room')
|
||||||
|
def handle_join_room(data=None):
|
||||||
|
from flask import request
|
||||||
|
username = data.get('username', 'Anonymous') if data else 'Anonymous'
|
||||||
|
print(f'Client {request.sid} ({username}) joining room') # type: ignore
|
||||||
|
|
||||||
|
# Update client info with username
|
||||||
|
if request.sid in connected_clients: # type: ignore
|
||||||
|
connected_clients[request.sid]['username'] = username # type: ignore
|
||||||
|
connected_clients[request.sid]['connected_at'] = __import__('time').time() # type: ignore
|
||||||
|
|
||||||
|
# Get list of existing users with usernames (excluding the new user)
|
||||||
|
existing_users = []
|
||||||
|
for user_id, user_info in connected_clients.items():
|
||||||
|
if user_id != request.sid and user_info['username']: # type: ignore
|
||||||
|
existing_users.append({
|
||||||
|
'id': user_id,
|
||||||
|
'username': user_info['username']
|
||||||
|
})
|
||||||
|
|
||||||
|
# Send existing users list to the new user
|
||||||
|
if existing_users:
|
||||||
|
emit('existing_users', {'users': existing_users})
|
||||||
|
|
||||||
|
# Notify existing clients about new user
|
||||||
|
emit('user_joined', {
|
||||||
|
'id': request.sid, # type: ignore
|
||||||
|
'username': username
|
||||||
|
}, broadcast=True, include_self=False)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# Set up SSL context
|
||||||
|
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
||||||
|
context.load_cert_chain('cert.pem', 'key.pem')
|
||||||
|
|
||||||
|
print("Starting Flask-SocketIO server on https://localhost:3000")
|
||||||
|
socketio.run(app, host='localhost', port=3000, ssl_context=context, debug=True)
|
||||||
31
cert.pem
Normal file
31
cert.pem
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
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
|
||||||
|
-----END CERTIFICATE-----
|
||||||
52
key.pem
Normal file
52
key.pem
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
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
|
||||||
|
kVJ7PW1aIDSJnFsDWmsotAyutuoDSk4=
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
4
requirements.txt
Normal file
4
requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
Flask==2.3.3
|
||||||
|
Flask-SocketIO==5.3.6
|
||||||
|
python-socketio==5.9.0
|
||||||
|
eventlet==0.33.3
|
||||||
27
setup.sh
Normal file
27
setup.sh
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Setting up Python Flask Video Chat Application..."
|
||||||
|
|
||||||
|
# Create virtual environment if it doesn't exist
|
||||||
|
if [ ! -d "venv" ]; then
|
||||||
|
echo "Creating virtual environment..."
|
||||||
|
python3 -m venv venv
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Activate virtual environment
|
||||||
|
echo "Activating virtual environment..."
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
echo "Installing dependencies..."
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Setup complete!"
|
||||||
|
echo ""
|
||||||
|
echo "To run the application:"
|
||||||
|
echo "1. Activate the virtual environment: source venv/bin/activate"
|
||||||
|
echo "2. Run the Flask app: python app.py"
|
||||||
|
echo "3. Open https://localhost:2000 in your browser"
|
||||||
|
echo ""
|
||||||
|
echo "Note: You may need to accept the self-signed certificate in your browser."
|
||||||
Reference in New Issue
Block a user