diff --git a/__pycache__/server.cpython-313.pyc b/__pycache__/server.cpython-313.pyc index cdecac7..2ffedc6 100644 Binary files a/__pycache__/server.cpython-313.pyc and b/__pycache__/server.cpython-313.pyc differ diff --git a/server.py b/server.py index 1d38122..b35babd 100644 --- a/server.py +++ b/server.py @@ -1,53 +1,150 @@ -from flask import Flask, request, jsonify +from flask import Flask, request, jsonify, session, render_template from pymongo import MongoClient +from datetime import datetime +import os app = Flask(__name__) application = app +app.secret_key = os.urandom(24) -try: - from local_settings import * -except ImportError: - print("Can't import from localsettings, terminating") - exit() +#try: +# from local_settings import * +#except ImportError: +# print("Can't import from localsettings, terminating") +# exit() -EXPECTED_PASSWORD = APPLICATION_PASSWORD -uri = MONGO_URI +EXPECTED_PASSWORD = "8V33zfvkImxBZcigtQ" +#APPLICATION_PASSWORD +uri = "mongodb://zpdai.rkg.lv/submit" +#MONGO_URI +TEACHER_PASSWORD = "teacher_password_123" mongo_client = MongoClient(uri) db = mongo_client["user_interactions"] -collection = db["user_events"] +events_col = db["user_events"] +sessions_col = db["monitoring_sessions"] + +current_session = { + 'active': False, + 'class_name': None, + 'start_time': None, + 'session_id': None +} def validate_event(event): required_keys = ["@version", "type", "TimeStamp", "data", "@timestamp"] return all(key in event for key in required_keys) +@app.after_request +def add_cors_headers(response): + response.headers['Access-Control-Allow-Origin'] = '*' + response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS' + response.headers['Access-Control-Allow-Headers'] = 'Content-Type, X-Password' + return response + +@app.route('/api/session_status', methods=['OPTIONS']) +@app.route('/teacher/control', methods=['OPTIONS']) +def handle_options(): + return jsonify(), 200, { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type' + } + @app.route('/submit', methods=['POST', 'OPTIONS']) def submit_event(): if request.method == 'OPTIONS': - resp = jsonify() - resp.headers['Access-Control-Allow-Origin'] = '*' - resp.headers['Access-Control-Allow-Methods'] = 'POST, OPTIONS' - resp.headers['Access-Control-Allow-Headers'] = 'Content-Type, X-Password' - return resp + return jsonify(), 204 + try: - password = request.headers.get('X-Password') if password != EXPECTED_PASSWORD: return jsonify({"error": "Неверный пароль"}), 403 event = request.get_json() - if not event or not validate_event(event): - resp = jsonify({"error": "Неверный формат"}) - resp.headers['Access-Control-Allow-Origin'] = '*' - return resp, 400 + return jsonify({"error": "Неверный формат"}), 400 - collection.insert_one(event) + if current_session['active']: + event['session_id'] = current_session['session_id'] + events_col.insert_one(event) + return jsonify({"message": "Действие сохранено"}), 200 + else: + return jsonify({"error": "Сессия не активна"}), 400 - resp = jsonify({"message": "Действие успешно сохранено"}) - resp.headers['Access-Control-Allow-Origin'] = '*' - return resp, 200 except Exception as e: - resp = jsonify({"error": str(e)}) - resp.headers['Access-Control-Allow-Origin'] = '*' - return resp, 500 + return jsonify({"error": str(e)}), 500 + +@app.route('/api/session_status', methods=['GET', 'OPTIONS']) +def session_status(): + if request.method == 'OPTIONS': + return jsonify(), 204 + + return jsonify({ + 'active': current_session['active'], + 'class_name': current_session['class_name'], + 'session_id': current_session['session_id'] + }), 200 + + +@app.route('/teacher', methods=['GET']) +def teacher_panel(): + if not session.get('teacher_logged_in'): + return render_template('login.html') + return render_template('teacher_panel.html') + +@app.route('/teacher/login', methods=['POST', 'OPTIONS']) +def teacher_login(): + if request.method == 'OPTIONS': + return jsonify(), 204 + + password = request.json.get('password') + if password == TEACHER_PASSWORD: + session['teacher_logged_in'] = True + return jsonify({'status': 'success'}), 200 + return jsonify({'error': 'Invalid password'}), 401 + +@app.route('/teacher/control', methods=['POST', 'OPTIONS']) +def session_control(): + if request.method == 'OPTIONS': + return jsonify(), 200 + + if not session.get('teacher_logged_in'): + return jsonify({'error': 'Unauthorized'}), 401 + + action = request.json.get('action') + class_name = request.json.get('class_name') + + if action == 'start' and class_name: + current_session.update({ + 'active': True, + 'class_name': class_name, + 'start_time': datetime.now(), + 'session_id': os.urandom(16).hex() + }) + sessions_col.insert_one({ + 'session_id': current_session['session_id'], + 'class': class_name, + 'start_time': current_session['start_time'], + 'end_time': None, + 'active': True + }) + return jsonify({'status': 'session_started'}), 200 + + elif action == 'stop': + sessions_col.update_one( + {'session_id': current_session['session_id']}, + {'$set': {'active': False, 'end_time': datetime.now()}} + ) + current_session.update({ + 'active': False, + 'class_name': None, + 'start_time': None, + 'session_id': None + }) + return jsonify({'status': 'session_stopped'}), 200 + + return jsonify({'error': 'Invalid request'}), 400 + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) \ No newline at end of file diff --git a/templates/login.html b/templates/login.html new file mode 100644 index 0000000..c70aa03 --- /dev/null +++ b/templates/login.html @@ -0,0 +1,47 @@ + + + + Авторизация учителя + + + +
+

Вход для учителя

+ + +

+
+ + + + \ No newline at end of file diff --git a/templates/teacher_panel.html b/templates/teacher_panel.html new file mode 100644 index 0000000..3d730cc --- /dev/null +++ b/templates/teacher_panel.html @@ -0,0 +1,72 @@ + + + + Панель учителя + + + +
+ + + + + + + \ No newline at end of file