1
0
Fork 0
mirror of https://github.com/EDeev/web-dev.git synced 2026-10-07 20:49:38 +03:00

Compare commits

...

4 commits

Author SHA1 Message Date
9a23fc52e0 README на русском и английском, скриншот экзамена
Отдельный ex/README.md со ссылкой на сайт и тестовыми аккаунтами объединён с общим README.
2026-10-02 21:29:26 +00:00
bc087c9e7c CI: синтаксис (ruff), тесты домашних заданий, импорт всех лабораторных и экзамена 2026-10-02 21:29:26 +00:00
69ced80d88 Режим отладки и SECRET_KEY из окружения, зависимости lab-4/5 закреплены
- app.run(debug=True) во всех лабораторных и экзамене заменён на FLASK_DEBUG=1 из
  окружения: отладчик Werkzeug позволяет выполнять код на сервере;
- secret_key — из SECRET_KEY, прежние значения остались только как запасные;
- lab-4/5: Flask-SQLAlchemy 2.5 + SQLAlchemy 1.4 (со свежим SQLAlchemy 2 не импортировались);
- неиспользуемые импорты и переменные удалены (ruff).
2026-10-02 21:27:00 +00:00
950154e23d Базы SQLite и загруженные картинки убраны из git
ex/db/library.db, ex/library.db, instance/*.db лабораторных, загрузки экзамена и lab-6 —
это данные, которые приложения создают сами (db_seed.py, create_all); папки для загрузок
остаются (.gitkeep), .gitignore добавлен.
2026-10-02 21:27:00 +00:00
63 changed files with 175 additions and 158 deletions

42
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,42 @@
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
lint-and-homework:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install ruff==0.14.0 pytest==8.4.2
- name: Ruff (синтаксис и ошибки)
run: ruff check --select E9,F .
- name: Тесты домашних заданий
run: |
cd hws/hw-1 && pytest -q test.py && cd ../..
cd hws/hw-2 && pytest -q test.py
apps:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
app: [labs/lab-1/app, labs/lab-2/app, labs/lab-3/app, labs/lab-4/app, labs/lab-5/app, labs/lab-6/app, ex]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Зависимости
run: |
req=$(dirname ${{ matrix.app }})/requirements.txt
[ -f ${{ matrix.app }}/requirements.txt ] && req=${{ matrix.app }}/requirements.txt
pip install -r $req
- name: Приложение импортируется
working-directory: ${{ matrix.app }}
run: python -c "import app"

12
.gitignore vendored Normal file
View file

@ -0,0 +1,12 @@
__pycache__/
*.py[cod]
.venv/
venv/
.env
*.db
instance/
ex/app/static/uploads/*
!ex/app/static/uploads/.gitkeep
labs/lab-6/app/media/images/*
!labs/lab-6/app/media/images/.gitkeep
.pytest_cache/

56
README.en.md Normal file
View file

@ -0,0 +1,56 @@
# Web Development
[Русский](README.md) · **English**
[![CI](https://github.com/EDeev/web-dev/actions/workflows/ci.yml/badge.svg)](https://github.com/EDeev/web-dev/actions/workflows/ci.yml)
Labs, homework and the exam project for the "Web Development" course at Moscow Polytechnic University:
six Flask apps, 37 Python exercises with tests, and an online library.
**Status:** coursework (Moscow Polytech, group 241-327, 2025/26), completed, archived ·
labs at [web-dev.deev.space](https://web-dev.deev.space), exam at [ex-web.deev.su](https://ex-web.deev.su)
![Exam: online library](docs/screenshots/exam.png)
**Stack:** Python · Flask · Jinja2 · Flask-Login · Flask-SQLAlchemy · Flask-Migrate · SQLite/MySQL · Bootstrap 5 · pytest
| Folder | Contents |
|---|---|
| `labs/lab-1` | blog post template with Flask and Jinja2 |
| `labs/lab-2` | request data: parameters, headers, cookies, forms, phone number validation |
| `labs/lab-3` | sign-in with Flask-Login, protected pages, sessions |
| `labs/lab-4` | user accounts CRUD: database, validation, password hashing |
| `labs/lab-5` | roles and permissions, visit log, reports with CSV export |
| `labs/lab-6` | education portal: course reviews, ratings, pagination, filters |
| `hws/hw-1`, `hws/hw-2` | 37 Python exercises (algorithms, files, decorators, generators, OOP) and 241 tests |
| `ex` | exam: book catalog with search, reviews and roles (admin, moderator, user) |
## Running
```bash
cd labs/lab-3 && pip install -r requirements.txt
cd app && FLASK_DEBUG=1 python app.py
cd ex && pip install -r requirements.txt
python db/db_seed.py # database, roles and test users (passwords are printed)
python run.py
```
`SECRET_KEY` and `FLASK_DEBUG` come from environment variables. Homework tests:
`cd hws/hw-1 && pytest test.py`.
## License
Coursework (Web Development, Moscow Polytechnic University, 2025/26). The code is open for study; there
is no separate license.
## Author
**Egor Deev** — [GitHub](https://github.com/EDeev) · [Telegram](https://t.me/DeevEgor) · [egor@deev.space](mailto:egor@deev.space)
---
<div align="center">
<sub>⭐ If you find this project useful, give it a star on GitHub!</sub>
<p><sub>Made with ❤️ — <a href="https://deev.space">deev.space</a></sub></p>
</div>

106
README.md
View file

@ -1,90 +1,56 @@
# Курс Веб-разработки # Веб-разработка
[![Python](https://img.shields.io/badge/Python-3776AB?style=flat&logo=python&logoColor=white)](https://www.python.org/)
[![Flask](https://img.shields.io/badge/Flask-000000?style=flat&logo=flask&logoColor=white)](https://flask.palletsprojects.com/)
[![SQLite](https://img.shields.io/badge/SQLite-003B57?style=flat&logo=sqlite&logoColor=white)](https://www.sqlite.org/)
[![Bootstrap](https://img.shields.io/badge/Bootstrap-7952B3?style=flat&logo=bootstrap&logoColor=white)](https://getbootstrap.com/)
Репозиторий содержит выполненные лабораторные работы и домашние задания по курсу "Веб-разработка" в Московском Политехническом университете. **Русский** · [English](README.en.md)
**Веб-сайт проекта:** [web-dev.deev.space](https://web-dev.deev.space) [![CI](https://github.com/EDeev/web-dev/actions/workflows/ci.yml/badge.svg)](https://github.com/EDeev/web-dev/actions/workflows/ci.yml)
**Автор:** Деев Егор Викторович, группа 241-327 Лабораторные, домашние задания и экзаменационный проект по курсу «Веб-разработка» в Московском
Политехе: шесть Flask-приложений, 37 задач на Python с тестами и электронная библиотека.
## Структура репозитория **Статус:** учебный проект (Московский Политех, группа 241-327, 2025/26), завершён, в архиве ·
лабораторные — [web-dev.deev.space](https://web-dev.deev.space), экзамен — [ex-web.deev.su](https://ex-web.deev.su)
### Лабораторные работы ![Экзамен: электронная библиотека](docs/screenshots/exam.png)
#### [Лабораторная работа №1](https://web-dev.deev.space/lab1) **Стек:** Python · Flask · Jinja2 · Flask-Login · Flask-SQLAlchemy · Flask-Migrate · SQLite/MySQL · Bootstrap 5 · pytest
Создание шаблона для отображения записи блога с использованием Flask и Jinja2. Реализация базовой структуры приложения, шаблонов для отображения постов и комментариев.
**Стек:** Flask, Jinja2, Bootstrap 5 | Папка | Что внутри |
|---|---|
| `labs/lab-1` | шаблон записи блога на Flask и Jinja2 |
| `labs/lab-2` | данные запроса: параметры, заголовки, cookies, формы, проверка телефона |
| `labs/lab-3` | вход через Flask-Login, защищённые страницы, сессии |
| `labs/lab-4` | CRUD учётных записей: база, валидация, хеширование паролей |
| `labs/lab-5` | роли и права, журнал посещений, отчёты с экспортом в CSV |
| `labs/lab-6` | образовательный портал: отзывы к курсам, рейтинг, пагинация, фильтры |
| `hws/hw-1`, `hws/hw-2` | 37 задач на Python (алгоритмы, файлы, декораторы, генераторы, ООП) и 241 тест |
| `ex` | экзамен: каталог книг с поиском, рецензиями и ролями (администратор, модератор, пользователь) |
#### [Лабораторная работа №2](https://web-dev.deev.space/lab2) ## Запуск
Работа с данными запроса. Реализация обработки параметров URL, заголовков, cookies и форм. Валидация номера телефона на стороне сервера.
**Стек:** Flask, регулярные выражения ```bash
cd labs/lab-3 && pip install -r requirements.txt
cd app && FLASK_DEBUG=1 python app.py
#### [Лабораторная работа №3](https://web-dev.deev.space/lab3) cd ex && pip install -r requirements.txt
Реализация аутентификации пользователей с использованием Flask-Login. Создание системы входа, защищенных страниц и управления сессиями. python db/db_seed.py # база, роли и тестовые пользователи (пароли выводятся в консоль)
python run.py
```
**Стек:** Flask, Flask-Login, session management `SECRET_KEY` и `FLASK_DEBUG` задаются переменными окружения. Тесты домашних заданий:
`cd hws/hw-1 && pytest test.py`.
#### [Лабораторная работа №4](https://web-dev.deev.space/lab4) ## Лицензия
Разработка CRUD-приложения для управления учетными записями пользователей. Работа с базой данных, валидация данных, хеширование паролей.
**Стек:** Flask, Flask-SQLAlchemy, MySQL, bcrypt Учебный проект (Веб-разработка, Московский Политех, 2025/26). Код открыт для изучения, отдельной
лицензии нет.
#### [Лабораторная работа №5](https://web-dev.deev.space/lab5) ## Автор
Авторизация пользователей и формирование статистических отчетов. Реализация системы ролей, декораторов проверки прав, журнала посещений и экспорта в CSV.
**Стек:** Flask, Flask-Login, Blueprints, CSV export **Деев Егор Викторович** — [GitHub](https://github.com/EDeev) · [Telegram](https://t.me/DeevEgor) · [egor@deev.space](mailto:egor@deev.space)
#### [Лабораторная работа №6](https://web-dev.deev.space/lab6)
Доработка образовательного портала: добавление системы отзывов к курсам, рейтинговой системы, пагинации и фильтрации.
**Стек:** Flask, Flask-SQLAlchemy, Flask-Migrate, MySQL
### Домашние задания
#### [Домашнее задание №1](https://github.com/EDeev/web-dev/tree/main/hws/hw-1)
Решение 20 задач на Python: базовые алгоритмы, работа с файлами, регулярные выражения, структуры данных. Покрытие тестами с использованием pytest (60+ тестов).
**Темы:** базовый синтаксис Python, работа с файлами, алгоритмы, структуры данных
#### [Домашнее задание №2](https://github.com/EDeev/web-dev/tree/main/hws/hw-2)
Решение 17 задач на Python: функции, декораторы, генераторы, ООП, работа с файловой системой. Покрытие тестами с использованием pytest (60+ тестов).
**Темы:** функции, декораторы, генераторы, ООП, аргументы командной строки, работа с файлами
## План развития
- Развертывание всех лабораторных работ на хостинге
- Добавление CI/CD pipeline для автоматического тестирования
- Документирование API endpoints
- Рефакторинг кода с применением паттернов проектирования
- Добавление Docker-контейнеризации для упрощения развертывания
## Технологический стек
- **Backend:** Python, Flask, Flask-Login, Flask-SQLAlchemy, Flask-Migrate
- **Frontend:** HTML5, CSS3, Bootstrap 5, Jinja2
- **База данных:** MySQL, SQLite
- **Тестирование:** pytest
- **Деплой:** NGINX, Unit
## Контакты
- Email: egor@deev.space
- Telegram: @Egor_Deev
- GitHub: @EDeev
## Лицензия и использование
Данный репозиторий создан в образовательных целях. Код доступен для изучения и адаптации без указания авторства.
--- ---
<div align="center"> <div align="center">
<sub>⭐ Если проект оказался полезным, поставьте звездочку на GitHub!</sub> <sub>⭐ Если проект оказался полезным, поставьте звёздочку на GitHub!</sub>
<p><sub>Создано с ❤️ от вашего дорогого - <a href="https://deev.space">deev.space</a> ©</sub></p> <p><sub>Сделано с ❤️ — <a href="https://deev.space">deev.space</a></sub></p>
</div> </div>

BIN
docs/screenshots/exam.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

BIN
docs/screenshots/labs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

View file

@ -1,2 +0,0 @@
## Сайт развёрнут на домене https://ex-web.deev.su
Тестовые аккаунты (администратор, модератор, пользователь) создаёт `ex/db/db_seed.py`; пароли задаются переменными `SEED_ADMIN_PASSWORD`, `SEED_MODER_PASSWORD`, `SEED_USER_PASSWORD` или генерируются при запуске и выводятся в консоль.

View file

@ -9,7 +9,7 @@ import bleach
import markdown import markdown
app = Flask(__name__) app = Flask(__name__)
app.secret_key = 'exam-secret-key-2026' app.secret_key = os.environ.get('SECRET_KEY', 'exam-secret-key-2026')
_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) _ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
app.config['UPLOAD_FOLDER'] = os.path.join(os.path.dirname(__file__), 'static', 'uploads') app.config['UPLOAD_FOLDER'] = os.path.join(os.path.dirname(__file__), 'static', 'uploads')

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#1cc88a"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">КР</text>
</svg>

Before

Width:  |  Height:  |  Size: 254 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#858796"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">ГР</text>
</svg>

Before

Width:  |  Height:  |  Size: 254 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#e74a3b"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">ВО</text>
</svg>

Before

Width:  |  Height:  |  Size: 254 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#f6c23e"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">АВ</text>
</svg>

Before

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 648 KiB

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#e74a3b"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">МА</text>
</svg>

Before

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 863 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#f6c23e"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">19</text>
</svg>

Before

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#4e73df"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">ПР</text>
</svg>

Before

Width:  |  Height:  |  Size: 254 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#1cc88a"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">ДЮ</text>
</svg>

Before

Width:  |  Height:  |  Size: 254 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#f6c23e"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">ГА</text>
</svg>

Before

Width:  |  Height:  |  Size: 254 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#e74a3b"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">ТР</text>
</svg>

Before

Width:  |  Height:  |  Size: 254 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#e74a3b"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">ШЕ</text>
</svg>

Before

Width:  |  Height:  |  Size: 254 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="280">
<rect width="200" height="280" fill="#4e73df"/>
<text x="100" y="155" font-family="Arial" font-size="48" font-weight="bold"
fill="white" text-anchor="middle">ВЛ</text>
</svg>

Before

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

View file

@ -8,4 +8,4 @@ if __name__ == '__main__':
with app.app_context(): with app.app_context():
if not os.path.exists(app.config['DATABASE']): if not os.path.exists(app.config['DATABASE']):
init_db() init_db()
app.run(debug=True) app.run(debug=os.environ.get('FLASK_DEBUG') == '1')

View file

@ -1,5 +1,4 @@
import random import random
import math
def circle_square_mk(r, n): def circle_square_mk(r, n):
inside = 0 inside = 0

View file

@ -1,4 +1,3 @@
import operator
def person_lister(f): def person_lister(f):
def inner(people): def inner(people):

View file

@ -2,7 +2,6 @@ import pytest
import math import math
import os import os
import subprocess import subprocess
import tempfile
from fact import fact_it, fact_rec from fact import fact_it, fact_rec
from show_employee import show_employee from show_employee import show_employee
from sum_and_sub import sum_and_sub from sum_and_sub import sum_and_sub
@ -11,7 +10,7 @@ from my_sum import my_sum
from email_validation import fun from email_validation import fun
from fibonacci import fibonacci from fibonacci import fibonacci
from average_scores import compute_average_scores from average_scores import compute_average_scores
from plane_angle import Point, plane_angle from plane_angle import Point
from complex_numbers import Complex from complex_numbers import Complex
from circle_square_mk import circle_square_mk from circle_square_mk import circle_square_mk
from log_decorator import function_logger from log_decorator import function_logger

View file

@ -1,3 +1,4 @@
import os
import random import random
from flask import Flask, render_template from flask import Flask, render_template
from faker import Faker from faker import Faker
@ -48,4 +49,4 @@ def about():
return render_template('about.html', title='Об авторе') return render_template('about.html', title='Об авторе')
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True) app.run(debug=os.environ.get('FLASK_DEBUG') == '1')

View file

@ -1,3 +1,4 @@
import os
import re import re
import random import random
from flask import Flask, render_template, request from flask import Flask, render_template, request
@ -104,4 +105,4 @@ def phone():
) )
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True) app.run(debug=os.environ.get('FLASK_DEBUG') == '1')

View file

@ -1,3 +1,4 @@
import os
import re import re
import random import random
from flask import Flask, render_template, request, session, redirect, url_for, flash from flask import Flask, render_template, request, session, redirect, url_for, flash
@ -8,7 +9,7 @@ fake = Faker('ru_RU')
app = Flask(__name__) app = Flask(__name__)
application = app application = app
app.secret_key = '1234567890secret' app.secret_key = os.environ.get('SECRET_KEY', '1234567890secret')
login_manager = LoginManager() login_manager = LoginManager()
login_manager.init_app(app) login_manager.init_app(app)
@ -166,4 +167,4 @@ def phone():
) )
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True) app.run(debug=os.environ.get('FLASK_DEBUG') == '1')

View file

@ -1,7 +1,8 @@
import os
import re import re
import random import random
from datetime import datetime from datetime import datetime
from flask import Flask, render_template, request, session, redirect, url_for, flash, abort from flask import Flask, render_template, request, session, redirect, url_for, flash
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt from flask_bcrypt import Bcrypt
@ -11,7 +12,7 @@ fake = Faker('ru_RU')
app = Flask(__name__) app = Flask(__name__)
application = app application = app
app.secret_key = '1234567890secret' app.secret_key = os.environ.get('SECRET_KEY', '1234567890secret')
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
@ -447,4 +448,4 @@ def change_password():
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True) app.run(debug=os.environ.get('FLASK_DEBUG') == '1')

Binary file not shown.

View file

@ -7,6 +7,7 @@ MarkupSafe==2.1.1
python-dateutil==2.8.2 python-dateutil==2.8.2
six==1.16.0 six==1.16.0
Werkzeug==2.0.3 Werkzeug==2.0.3
Flask-Login Flask-Login==0.6.3
Flask-SQLAlchemy Flask-SQLAlchemy==2.5.1
Flask-Bcrypt SQLAlchemy==1.4.54
Flask-Bcrypt==1.0.1

View file

@ -1,8 +1,9 @@
import os
import re import re
import random import random
from functools import wraps from functools import wraps
from datetime import datetime from datetime import datetime
from flask import Flask, render_template, request, session, redirect, url_for, flash, abort from flask import Flask, render_template, request, session, redirect, url_for, flash
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt from flask_bcrypt import Bcrypt
@ -12,7 +13,7 @@ fake = Faker('ru_RU')
app = Flask(__name__) app = Flask(__name__)
application = app application = app
app.secret_key = '1234567890secret' app.secret_key = os.environ.get('SECRET_KEY', '1234567890secret')
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
@ -515,4 +516,4 @@ with app.app_context():
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True) app.run(debug=os.environ.get('FLASK_DEBUG') == '1')

Binary file not shown.

View file

@ -51,7 +51,7 @@ def index():
return redirect(url_for('index')) return redirect(url_for('index'))
m = _get_app_module() m = _get_app_module()
db, VisitLog = m.db, m.VisitLog VisitLog = m.VisitLog
page = request.args.get('page', 1, type=int) page = request.args.get('page', 1, type=int)
per_page = 10 per_page = 10

View file

@ -7,6 +7,7 @@ MarkupSafe==2.1.1
python-dateutil==2.8.2 python-dateutil==2.8.2
six==1.16.0 six==1.16.0
Werkzeug==2.0.3 Werkzeug==2.0.3
Flask-Login Flask-Login==0.6.3
Flask-SQLAlchemy Flask-SQLAlchemy==2.5.1
Flask-Bcrypt SQLAlchemy==1.4.54
Flask-Bcrypt==1.0.1

View file

@ -1,6 +1,6 @@
import os import os
SECRET_KEY = 'secret-key' SECRET_KEY = os.environ.get('SECRET_KEY', 'secret-key')
SQLALCHEMY_DATABASE_URI = 'sqlite:///project.db' SQLALCHEMY_DATABASE_URI = 'sqlite:///project.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_TRACK_MODIFICATIONS = False

Binary file not shown.

View file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 483 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 970 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

View file

@ -1,7 +1,6 @@
import os import os
from typing import Optional, Union, List from typing import Optional, List
from datetime import datetime from datetime import datetime
import sqlalchemy as sa
from werkzeug.security import check_password_hash, generate_password_hash from werkzeug.security import check_password_hash, generate_password_hash
from flask_login import UserMixin from flask_login import UserMixin
from flask import url_for from flask import url_for