From 6e7b8dfd3accbcb6b2095d6c7747f1bd495d5d1b Mon Sep 17 00:00:00 2001 From: InviteMe Developer Date: Mon, 31 Aug 2026 17:18:43 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=B3=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0?= =?UTF-8?q?=20=D0=BA=20=D0=BF=D1=83=D0=B1=D0=BB=D0=B8=D0=BA=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8:=20Docker,=20=D1=87=D0=B8=D1=81=D1=82=D0=B0=D1=8F?= =?UTF-8?q?=20=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B0,=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BF=D0=B0=D0=BF=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Убраны приватные URL и данные из README и docker-compose.yml - Добавлен .env.example с примером переменных окружения - Улучшен Dockerfile: добавлен libcairo2-dev для rlPyCairo - Убраны fallbacks на общие папки: фото, QR, билеты, логотипы строго внутри event_{id} - Папка скрин/ и *.txt исключены из git - Пасхалка о создателе mycloud24.ru сохранена --- .dockerignore | 2 -- .env.example | 31 +++++++++++++++++++++++++++++++ .gitignore | 5 +++++ Dockerfile | 1 + README.md | 5 +++-- app/models.py | 10 +++++----- app/services/email_service.py | 2 -- app/services/ticket_service.py | 6 ------ docker-compose.yml | 2 +- 9 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 .env.example diff --git a/.dockerignore b/.dockerignore index f65d582..468de38 100644 --- a/.dockerignore +++ b/.dockerignore @@ -13,5 +13,3 @@ __pycache__/ *.sqlite3 app/static/uploads/* !app/static/uploads/.gitkeep -111.txt -inviteme_logo.png diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..ba7b43e --- /dev/null +++ b/.env.example @@ -0,0 +1,31 @@ +# Скопируйте в .env и замените значения перед запуском + +# Обязательно: сильный случайный секретный ключ +# Пример генерации: openssl rand -hex 32 +SECRET_KEY=change-me-in-production + +# Базовый URL приложения (без слэша в конце), используется в QR-кодах +BASE_URL=https://your-domain.example.com + +# Часовой пояс для отображения дат +TIMEZONE=Europe/Moscow + +# URI базы данных. По умолчанию SQLite в папке instance/ +# DATABASE_URL=sqlite:///app/instance/inviteme.db + +# Настройки SMTP (заполняются также через веб-интерфейс) +# MAIL_SERVER=smtp.example.com +# MAIL_PORT=465 +# MAIL_USE_SSL=true +# MAIL_USERNAME=noreply@example.com +# MAIL_PASSWORD=your-app-password +# MAIL_DEFAULT_SENDER=InviteMe + +# Настройки IMAP для сохранения копий отправленных писем +# IMAP_SERVER=imap.example.com +# IMAP_PORT=993 +# IMAP_USE_SSL=true +# IMAP_USERNAME=noreply@example.com +# IMAP_PASSWORD=your-app-password +# IMAP_FOLDER=Sent +# IMAP_SAVE_COPY=false diff --git a/.gitignore b/.gitignore index 5c203a5..4063341 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .env .env.* +!.env.example venv/ __pycache__/ *.pyc @@ -17,3 +18,7 @@ app/static/uploads/* *.log .DS_Store Thumbs.db + +# Локальные данные и скриншоты +скрин/ +*.txt diff --git a/Dockerfile b/Dockerfile index ab9364d..a59559e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libffi-dev \ libxml2-dev \ libxslt1-dev \ + libcairo2-dev \ fonts-dejavu-core \ fonts-liberation \ && rm -rf /var/lib/apt/lists/* diff --git a/README.md b/README.md index 6e9cf06..ca367b9 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Требования: установленный Docker и Docker Compose. ```bash -git clone ssh://git@192.168.1.101:2222/insight/inviteme.git +git clone cd inviteme # Собрать и запустить @@ -37,7 +37,7 @@ docker compose up -d --build Требования: Python 3.12. ```bash -git clone ssh://git@192.168.1.101:2222/insight/inviteme.git +git clone cd inviteme python -m venv venv @@ -72,6 +72,7 @@ venv\Scripts\python run_waitress.py - Сразу после первого запуска задайте сильный `SECRET_KEY` через переменную окружения. - Не храните реальные пароли в репозитории — используйте `.env` файл или переменные окружения. - Папка `instance/` (SQLite) и `app/static/uploads/` не попадают в git. +- Пример переменных окружения — в файле `.env.example`. ## Переменные окружения diff --git a/app/models.py b/app/models.py index 83df0eb..a566847 100644 --- a/app/models.py +++ b/app/models.py @@ -118,16 +118,16 @@ class Guest(db.Model): return " ".join(parts) if parts else self.full_name def _photo_paths(self): - """Возвращает возможные пути к фото: сначала папка мероприятия, потом корень.""" + """Возвращает путь к фото гостя в папке мероприятия.""" if not self.photo_filename: return [] from pathlib import Path from flask import current_app - base = Path(current_app.config["PHOTO_FOLDER"]) - paths = [base / self.photo_filename] + from app.utils.paths import event_photo_folder if self.event_id: - paths.insert(0, base / f"event_{self.event_id}" / self.photo_filename) - return paths + return [event_photo_folder(self.event_id) / self.photo_filename] + # fallback только если мероприятие ещё не назначено + return [Path(current_app.config["PHOTO_FOLDER"]) / self.photo_filename] @property def has_photo_file(self): diff --git a/app/services/email_service.py b/app/services/email_service.py index 7b1fb0d..a5a09b4 100644 --- a/app/services/email_service.py +++ b/app/services/email_service.py @@ -234,8 +234,6 @@ def send_invitation(guest, event_name=None, additional_text=""): # QR-код qr_path = event_qr_folder(guest.event_id) / guest.qr_filename - if not qr_path.exists(): - qr_path = Path(config["QR_FOLDER"]) / guest.qr_filename if qr_path.exists(): attachments.append({"path": qr_path, "cid": "qr_code_image", "filename": guest.qr_filename}) diff --git a/app/services/ticket_service.py b/app/services/ticket_service.py index 3c077c4..703acc2 100644 --- a/app/services/ticket_service.py +++ b/app/services/ticket_service.py @@ -306,9 +306,6 @@ def generate_ticket_image(guest, event, output_path=None): if event.ticket_show_qr: y += 15 qr_path = event_qr_folder(guest.event_id) / guest.qr_filename - if not qr_path.exists(): - # fallback на старую корневую папку - qr_path = Path(current_app.config["QR_FOLDER"]) / guest.qr_filename if qr_path.exists(): qr_size = 200 qr_img = Image.open(str(qr_path)).convert("RGB") @@ -321,9 +318,6 @@ def generate_ticket_image(guest, event, output_path=None): # Фото гостя if event.ticket_show_photo and guest.photo_filename: photo_path = event_photo_folder(guest.event_id) / guest.photo_filename - if not photo_path.exists(): - # fallback на старую корневую папку - photo_path = Path(current_app.config["PHOTO_FOLDER"]) / guest.photo_filename if photo_path.exists(): photo_img = Image.open(str(photo_path)).convert("RGB") photo_img.thumbnail((130, 130)) diff --git a/docker-compose.yml b/docker-compose.yml index 6439b38..897bc74 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,8 +9,8 @@ services: - "8888:8888" environment: # Замени на сильный случайный ключ перед запуском в продакшене + # Пример генерации: openssl rand -hex 32 - SECRET_KEY=change-me-in-production - - BASE_URL=https://ai.mycloud24.ru - TIMEZONE=Europe/Moscow volumes: # База SQLite и загруженные файлы хранятся вне контейнера