Check / app.py
sigyllly's picture
Update app.py
8d49074 verified
from flask import Flask, request, jsonify, render_template
from flask_socketio import SocketIO, emit
import json
import uuid
import os
from datetime import datetime
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
socketio = SocketIO(app)
# Job storage with unique IDs and status
jobs = []
connected_clients = {}
def save_jobs():
"""Save jobs to JSON file"""
try:
with open('jobs.json', 'w') as f:
json.dump(jobs, f)
except Exception as e:
print(f"Error saving jobs: {e}")
def load_jobs():
"""Load jobs from JSON file"""
try:
if os.path.exists('jobs.json') and os.path.getsize('jobs.json') > 0:
with open('jobs.json', 'r') as f:
return json.load(f)
except Exception as e:
print(f"Error loading jobs: {e}")
return []
@app.route('/')
def index():
return render_template('index.html')
@app.route('/submit_job', methods=['POST'])
def submit_job():
youtube_url = request.form.get("youtube_url")
exit_time = int(request.form.get("exit_time", 10))
mode = request.form.get("mode", "once")
job_id = str(uuid.uuid4())
job = {
"job_id": job_id,
"youtube_url": youtube_url,
"exit_time": exit_time,
"mode": mode,
"status": "pending"
}
jobs.append(job)
save_jobs()
return jsonify({"message": "Job submitted successfully", "job_id": job_id})
@socketio.on('client_info')
def handle_client_info(data):
client_id = request.sid
connected_clients[client_id] = {
'ip': data.get('ip', 'Unknown'),
'country': data.get('country', 'Unknown'),
'city': data.get('city', 'Unknown'),
'connected_at': datetime.now().isoformat()
}
emit('client_connected', {
'client_id': client_id,
'ip': data.get('ip', 'Unknown'),
'country': data.get('country', 'Unknown'),
'city': data.get('city', 'Unknown')
}, broadcast=True)
@socketio.on('disconnect')
def handle_disconnect():
client_id = request.sid
if client_id in connected_clients:
del connected_clients[client_id]
emit('client_disconnected', client_id, broadcast=True)
@app.route('/get_job', methods=['GET'])
def get_job():
for job in jobs:
if job["status"] == "pending":
return jsonify(job)
return jsonify({"message": "No pending jobs"})
@app.route('/update_job_status', methods=['POST'])
def update_job_status():
data = request.get_json()
job_id = data.get("job_id")
status = data.get("status", "done")
for job in jobs:
if job["job_id"] == job_id:
job["status"] = status
break
save_jobs()
return jsonify({"message": f"Job {job_id} marked as {status}"})
if __name__ == "__main__":
jobs = load_jobs()
if not os.path.exists('templates'):
os.makedirs('templates')
template_path = os.path.join('templates', 'index.html')
if not os.path.exists(template_path):
with open(template_path, 'w') as f:
f.write('''<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>YouTube Job Manager</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { padding: 20px; }
.connection-status { margin-bottom: 20px; }
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 offset-md-2">
<h1 class="mb-4">YouTube Job Manager</h1>
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">Connected Clients</h5>
</div>
<div class="card-body">
<table class="table" id="clientsTable">
<thead>
<tr>
<th>IP Address</th>
<th>Country</th>
<th>City</th>
<th>Status</th>
</tr>
</thead>
<tbody id="clientsTableBody">
</tbody>
</table>
</div>
</div>
<div class="card">
<div class="card-header">
<h5 class="mb-0">Submit New Job</h5>
</div>
<div class="card-body">
<form action="/submit_job" method="post" class="needs-validation" novalidate>
<div class="mb-3">
<label for="youtube_url" class="form-label">YouTube URL:</label>
<input type="text" class="form-control" id="youtube_url" name="youtube_url" required>
</div>
<div class="mb-3">
<label for="exit_time" class="form-label">Exit Time (seconds):</label>
<input type="number" class="form-control" id="exit_time" name="exit_time" value="10" required>
</div>
<div class="mb-3">
<label for="mode" class="form-label">Mode:</label>
<select class="form-select" id="mode" name="mode">
<option value="once">Once</option>
<option value="again">Again</option>
<option value="continuous">Continuous</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Submit Job</button>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
<script>
const socket = io();
socket.on('connect', () => {
console.log('Connected to server');
});
socket.on('client_connected', (data) => {
const tableBody = document.getElementById('clientsTableBody');
const row = document.createElement('tr');
row.setAttribute('data-client-id', data.client_id);
row.innerHTML = `
<td>${data.ip}</td>
<td>${data.country}</td>
<td>${data.city}</td>
<td><span class="badge bg-success">Connected</span></td>
`;
tableBody.appendChild(row);
});
socket.on('client_disconnected', (clientId) => {
const row = document.querySelector(`tr[data-client-id="${clientId}"]`);
if (row) {
row.querySelector('.badge').className = 'badge bg-danger';
row.querySelector('.badge').textContent = 'Disconnected';
}
});
</script>
</body>
</html>
''')
socketio.run(app, host="0.0.0.0", port=7860, debug=False, allow_unsafe_werkzeug=True)