from flask import Flask, render_template, request, jsonify, session, send_file from questions import QUESTION_POOL import random import uuid import qrcode from io import BytesIO import os import json from datetime import datetime app = Flask(__name__) app.secret_key = 'dnr_youth_parliament_secret_key_2024' # Хранилище сессий игроков и результатов active_games = {} saved_results = {} # Сохраняем результаты для QR-кодов class QuizGame: def __init__(self): self.game_id = str(uuid.uuid4())[:8] self.questions_pool = QUESTION_POOL.copy() self.selected_questions = [] self.current_question_index = 0 self.score = 0 self.is_active = True self.user_answers = [] self.start_time = datetime.now() self._select_random_questions() def _select_random_questions(self): """Выбирает 7 случайных вопросов из пула""" if len(self.questions_pool) >= 7: self.selected_questions = random.sample(self.questions_pool, 7) else: self.selected_questions = self.questions_pool.copy() # Добавляем тайминг к каждому вопросу for q in self.selected_questions: q['time_limit'] = 10 def get_current_question(self): """Возвращает текущий вопрос (без правильного ответа)""" if self.current_question_index < len(self.selected_questions): q = self.selected_questions[self.current_question_index] return { 'id': self.current_question_index, 'text': q['text'], 'options': q['options'], 'time_limit': q.get('time_limit', 10) } return None def check_answer(self, answer_index): """Проверяет ответ и обновляет счет""" current_q = self.selected_questions[self.current_question_index] is_correct = (answer_index == current_q['correct']) # Сохраняем ответ пользователя self.user_answers.append({ 'question_text': current_q['text'], 'options': current_q['options'], 'user_answer': answer_index, 'user_answer_text': current_q['options'][answer_index] if answer_index != -1 else 'Время вышло', 'correct_answer': current_q['options'][current_q['correct']], 'correct_index': current_q['correct'], 'is_correct': is_correct, 'explanation': current_q.get('explanation', '') }) if is_correct: self.score += 1 self.current_question_index += 1 return { 'is_correct': is_correct, 'correct_answer': current_q['options'][current_q['correct']], 'explanation': current_q.get('explanation', ''), 'score': self.score, 'is_finished': self.current_question_index >= len(self.selected_questions), 'total_questions': len(self.selected_questions) } def get_result(self): """Возвращает результат теста со всеми вопросами""" total = len(self.selected_questions) percentage = (self.score / total) * 100 # Определение звания/результата if percentage >= 90: grade = "🏆 Депутат высшей категории!" message = "Вы отлично знаете историю и структуру Молодёжного Парламента ДНР!" elif percentage >= 70: grade = "⭐ Активный парламентарий!" message = "Хороший результат! Вы достойно показали свои знания." elif percentage >= 50: grade = "📚 Кандидат в парламент!" message = "Неплохо, но есть куда расти. Рекомендуем изучить материалы о работе Парламента." else: grade = "🌱 Будущий лидер!" message = "Не расстраивайтесь! Участие в викторине - первый шаг к большим достижениям." # Сохраняем результат для QR-кода result_data = { 'game_id': self.game_id, 'score': self.score, 'total': total, 'percentage': round(percentage, 1), 'grade': grade, 'message': message, 'questions_summary': self.user_answers, 'completed_at': self.start_time.isoformat() } saved_results[self.game_id] = result_data return { 'score': self.score, 'total': total, 'percentage': round(percentage, 1), 'grade': grade, 'message': message, 'questions_summary': self.user_answers, 'result_id': self.game_id # Возвращаем ID для QR-кода } @app.route('/') def index(): return render_template('index.html') @app.route('/api/new_game', methods=['POST']) def new_game(): game = QuizGame() active_games[game.game_id] = game return jsonify({ 'game_id': game.game_id, 'question': game.get_current_question(), 'question_number': 1, 'total_questions': len(game.selected_questions) }) @app.route('/api/check_answer', methods=['POST']) def check_answer(): data = request.json game_id = data.get('game_id') answer = data.get('answer') game = active_games.get(game_id) if not game or not game.is_active: return jsonify({'error': 'Игра не найдена'}), 404 result = game.check_answer(answer) if result['is_finished']: # Игра завершена final_result = game.get_result() return jsonify({ 'is_finished': True, 'result': final_result }) else: # Следующий вопрос return jsonify({ 'is_finished': False, 'result': result, 'next_question': game.get_current_question(), 'question_number': game.current_question_index + 1, 'total_questions': len(game.selected_questions) }) @app.route('/api/result/') def get_result_page(result_id): """Страница с результатами по QR-коду""" result = saved_results.get(result_id) if not result: return "Результат не найден", 404 return render_template('result_page.html', result=result) @app.route('/api/qrcode/') def generate_qrcode(result_id): """Генерация QR-кода со ссылкой на результат""" result_url = request.host_url.rstrip('/') + f'/api/result/{result_id}' # Создаём QR-код qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data(result_url) qr.make(fit=True) # Создаём изображение img = qr.make_image(fill_color="black", back_color="white") # Сохраняем в байты img_io = BytesIO() img.save(img_io, 'PNG') img_io.seek(0) return send_file(img_io, mimetype='image/png') if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000)