From 9a9c58afc08703fe984dad4cc62d09ef38c7dd4c Mon Sep 17 00:00:00 2001 From: eka Date: Sun, 1 Mar 2026 08:36:02 +0500 Subject: [PATCH] =?UTF-8?q?Initial=20commit:=20Flask=20quiz=20game=20'?= =?UTF-8?q?=D0=A3=D1=80=D0=BE=D0=BA=D0=B8=20=D1=84=D1=80=D0=B0=D0=BD=D1=86?= =?UTF-8?q?=D1=83=D0=B7=D1=81=D0=BA=D0=BE=D0=B3=D0=BE'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 29 ++ AGENTS.md | 164 ++++++++ SPEC.md | 90 +++++ app.py | 73 ++++ data/questions.json | 359 +++++++++++++++++ templates/admin.html | 40 ++ templates/edit.html | 55 +++ templates/index.html | 931 +++++++++++++++++++++++++++++++++++++++++++ templates/login.html | 28 ++ 9 files changed, 1769 insertions(+) create mode 100644 .gitignore create mode 100644 AGENTS.md create mode 100644 SPEC.md create mode 100644 app.py create mode 100644 data/questions.json create mode 100644 templates/admin.html create mode 100644 templates/edit.html create mode 100644 templates/index.html create mode 100644 templates/login.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..764d38b --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +venv/ +venv/ +env/ +.env +.venv + +# Flask +instance/ +.webassets-cache + +# IDEs +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Logs +*.log diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e16bcfa --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,164 @@ +# AGENTS.md - Guidelines for Agentic Coding + +## Project Overview + +This is a simple Flask web application - a "Jeopardy-style" quiz game about the Russian short story "Уроки французского" by Valentin Rasputin. The project uses: +- **Backend**: Python 3.13 with Flask +- **Frontend**: HTML, CSS, JavaScript (vanilla) +- **Data Storage**: JSON file (`data/questions.json`) +- **State**: Browser localStorage (client-side) + +## Build/Test Commands + +### Running the Application + +```bash +# Activate virtual environment +source venv/bin/activate + +# Run Flask app (default port 5000) +python app.py + +# Run on specific port +python -c "from app import app; app.run(port=5002)" +``` + +### No Formal Tests + +This project does not have a formal test suite. For manual testing: +- Use `curl` to test API endpoints +- Test in browser at http://localhost:5000 (or configured port) + +### Linting/Type Checking + +No formal linter is configured. The codebase uses basic Python and JavaScript. + +## Code Style Guidelines + +### Python (app.py) + +**Imports** +- Standard library first, then third-party +- Use absolute imports +- Example: + ```python + import json + from flask import Flask, render_template, request, redirect, url_for, make_response + ``` + +**Formatting** +- Use 4 spaces for indentation +- Maximum line length: 100 characters +- Blank lines: 2 between top-level definitions, 1 between function definitions + +**Naming Conventions** +- `snake_case` for variables, functions +- `PascalCase` for classes +- `UPPER_SNAKE_CASE` for constants + +**Error Handling** +- Use try/except for file operations (JSON loading/saving) +- Return proper HTTP error codes (400, 404, 500) +- Log errors to console + +**Flask-Specific** +- Use `app.secret_key` for sessions +- Always use `ensure_ascii=False` with JSON for Cyrillic support +- Use `context_processor` for global template variables + +### JavaScript (templates/*.html) + +**General** +- Use vanilla JavaScript (no frameworks) +- Prefer `var` over `let/const` for compatibility +- Use `function` keyword instead of arrow functions where possible + +**Event Handling** +- Use `onclick` directly in HTML or `element.onclick = function()` +- Avoid `addEventListener` for simplicity + +**DOM Manipulation** +- Use `document.getElementById` and `document.querySelector` +- Template literals for dynamic content: `` `string ${variable}` `` +- Use `JSON.parse()` and `JSON.stringify()` for localStorage + +**Naming** +- camelCase for variables and functions +- Descriptive names (e.g., `currentTeam`, `selectAnswer`) + +### HTML/CSS (templates/*.html) + +**Template Syntax (Jinja2)** +- Use `{% for %}` loops with `enumerate()` for indexed iteration +- Pass data via `{{ variable }}` syntax +- Use `|tojson` filter for JavaScript data + +**CSS** +- Use CSS custom properties (variables) for colors +- Follow BEM-like naming for classes +- Keep responsive design in mind + +**Structure** +- Inline CSS in ` + + +

Админка - Редактирование вопросов

+ Выйти + + + + + + + + {% for cat_idx, category in enumerate(questions.categories) %} + {% for q_idx, q in enumerate(category.questions) %} + + + + + + + {% endfor %} + {% endfor %} +
КатегорияВопросСтоимостьДействия
{{ category.name }}{{ q.question }}{{ q.cost }}Редактировать
+ Назад к игре + + diff --git a/templates/edit.html b/templates/edit.html new file mode 100644 index 0000000..e381e5a --- /dev/null +++ b/templates/edit.html @@ -0,0 +1,55 @@ + + + + + Редактирование вопроса + + + +

Редактирование вопроса

+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +

Текущий правильный: {{ question.options[question.answer] }}

+
+ +
+ Назад + + diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..8e6cae0 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,931 @@ + + + + + + Уроки французского - Своя игра + + + + + + +
+

Своя игра

+

Рассказ В.Г. Распутина «Уроки французского»

+
+ +
+ +
+
+
+
Вопросов: 0/30
+ +
+
+ +
+
+ {% for cat_idx, category in enumerate(questions.categories) %} +
+
{{ category.name }}
+ {% for q_idx, q in enumerate(category.questions) %} +
+ {{ q.cost }} +
+ {% endfor %} +
+ {% endfor %} +
+
+ + + +
+

Игра окончена!

+
+ +
+ + + + diff --git a/templates/login.html b/templates/login.html new file mode 100644 index 0000000..78beb69 --- /dev/null +++ b/templates/login.html @@ -0,0 +1,28 @@ + + + + + Вход в админку + + + +
+

Вход в админку

+
+ + +
+ {% if error %} +

{{ error }}

+ {% endif %} +
+ +