| 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) |
|
|
| |
| 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/[email protected]/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/[email protected]/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) |
|
|
|
|