sqlalchemy-connection 2.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sqlalchemy_connection-2.0.1/MANIFEST.in +1 -0
- sqlalchemy_connection-2.0.1/PKG-INFO +26 -0
- sqlalchemy_connection-2.0.1/README.md +29 -0
- sqlalchemy_connection-2.0.1/setup.cfg +4 -0
- sqlalchemy_connection-2.0.1/setup.py +37 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connection.egg-info/PKG-INFO +26 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connection.egg-info/SOURCES.txt +37 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connection.egg-info/dependency_links.txt +1 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connection.egg-info/entry_points.txt +2 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connection.egg-info/requires.txt +4 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connection.egg-info/top_level.txt +1 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/__init__.py +3 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/_builder.py +425 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/cli.py +200 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/real_generator.py +2908 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/admin_cart_html_template.html +372 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/admin_html_template.html +364 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/admin_users_html_template.html +82 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/app_template.py +434 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/base_html_template.html +100 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/cart_html_template.html +103 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/catalog_html_template.html +98 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/checkout_html_template.html +70 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/dashboard_html_template.html +121 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/index_html_template.html +91 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/login_html_template.html +59 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/models_template.py +65 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/new_request_html_template.html +49 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/orders_html_template.html +65 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/product_form_html_template.html +142 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/product_html_template.html +131 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/profile_html_template.html +104 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/register_html_template.html +183 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/reviews_html_template.html +104 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/service_detail_html_template.html +67 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/service_form_html_template.html +86 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/services_html_template.html +47 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/slider_js_template.js +99 -0
- sqlalchemy_connection-2.0.1/sqlalchemy_connector/templates/style_css_template.css +502 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include sqlalchemy_connector/templates *
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sqlalchemy-connection
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: Утилита для подключения к локальным SQLite базам данных
|
|
5
|
+
Author: SQLAlchemy Tools
|
|
6
|
+
Author-email: support@sqlalchemy-tools.dev
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Topic :: Database :: Front-Ends
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/plain
|
|
13
|
+
Requires-Dist: flask>=2.0.0
|
|
14
|
+
Requires-Dist: flask-sqlalchemy>=3.0.0
|
|
15
|
+
Requires-Dist: werkzeug>=2.0.0
|
|
16
|
+
Requires-Dist: flask-session>=0.5.0
|
|
17
|
+
Dynamic: author
|
|
18
|
+
Dynamic: author-email
|
|
19
|
+
Dynamic: classifier
|
|
20
|
+
Dynamic: description
|
|
21
|
+
Dynamic: description-content-type
|
|
22
|
+
Dynamic: requires-dist
|
|
23
|
+
Dynamic: requires-python
|
|
24
|
+
Dynamic: summary
|
|
25
|
+
|
|
26
|
+
SQLAlchemy Localhost Connector — лёгкая утилита командной строки для быстрого подключения к локальным SQLite/PostgreSQL базам данных. Позволяет просматривать схему, таблицы и записи без необходимости устанавливать тяжёлые GUI-клиенты. Поддерживает SQLAlchemy 2.x, автоматическое определение драйвера и вывод структуры БД в табличном формате.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# SQLAlchemy Localhost Connector
|
|
2
|
+
|
|
3
|
+
Утилита командной строки для подключения к локальным SQLite базам данных.
|
|
4
|
+
|
|
5
|
+
## Установка
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install -e .
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Использование
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
start-sqlalchemy
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
После запуска введите URL базы данных для подключения.
|
|
18
|
+
|
|
19
|
+
## Возможности
|
|
20
|
+
|
|
21
|
+
- Подключение к SQLite и PostgreSQL
|
|
22
|
+
- Просмотр схемы базы данных
|
|
23
|
+
- Вывод таблиц и записей в табличном формате
|
|
24
|
+
- Поддержка SQLAlchemy 2.x
|
|
25
|
+
|
|
26
|
+
## Требования
|
|
27
|
+
|
|
28
|
+
- Python >= 3.8
|
|
29
|
+
- SQLAlchemy >= 2.0
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="sqlalchemy-connection",
|
|
5
|
+
version="2.0.1",
|
|
6
|
+
author="SQLAlchemy Tools",
|
|
7
|
+
author_email="support@sqlalchemy-tools.dev",
|
|
8
|
+
description="Утилита для подключения к локальным SQLite базам данных",
|
|
9
|
+
long_description=(
|
|
10
|
+
"SQLAlchemy Localhost Connector — лёгкая утилита командной строки "
|
|
11
|
+
"для быстрого подключения к локальным SQLite/PostgreSQL базам данных. "
|
|
12
|
+
"Позволяет просматривать схему, таблицы и записи без необходимости "
|
|
13
|
+
"устанавливать тяжёлые GUI-клиенты. Поддерживает SQLAlchemy 2.x, "
|
|
14
|
+
"автоматическое определение драйвера и вывод структуры БД в табличном формате."
|
|
15
|
+
),
|
|
16
|
+
long_description_content_type="text/plain",
|
|
17
|
+
packages=find_packages(),
|
|
18
|
+
include_package_data=True,
|
|
19
|
+
classifiers=[
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
"Topic :: Database :: Front-Ends",
|
|
24
|
+
],
|
|
25
|
+
python_requires=">=3.8",
|
|
26
|
+
install_requires=[
|
|
27
|
+
"flask>=2.0.0",
|
|
28
|
+
"flask-sqlalchemy>=3.0.0",
|
|
29
|
+
"werkzeug>=2.0.0",
|
|
30
|
+
"flask-session>=0.5.0",
|
|
31
|
+
],
|
|
32
|
+
entry_points={
|
|
33
|
+
"console_scripts": [
|
|
34
|
+
"start-sqlalchemy=sqlalchemy_connector.cli:main",
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sqlalchemy-connection
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: Утилита для подключения к локальным SQLite базам данных
|
|
5
|
+
Author: SQLAlchemy Tools
|
|
6
|
+
Author-email: support@sqlalchemy-tools.dev
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Topic :: Database :: Front-Ends
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/plain
|
|
13
|
+
Requires-Dist: flask>=2.0.0
|
|
14
|
+
Requires-Dist: flask-sqlalchemy>=3.0.0
|
|
15
|
+
Requires-Dist: werkzeug>=2.0.0
|
|
16
|
+
Requires-Dist: flask-session>=0.5.0
|
|
17
|
+
Dynamic: author
|
|
18
|
+
Dynamic: author-email
|
|
19
|
+
Dynamic: classifier
|
|
20
|
+
Dynamic: description
|
|
21
|
+
Dynamic: description-content-type
|
|
22
|
+
Dynamic: requires-dist
|
|
23
|
+
Dynamic: requires-python
|
|
24
|
+
Dynamic: summary
|
|
25
|
+
|
|
26
|
+
SQLAlchemy Localhost Connector — лёгкая утилита командной строки для быстрого подключения к локальным SQLite/PostgreSQL базам данных. Позволяет просматривать схему, таблицы и записи без необходимости устанавливать тяжёлые GUI-клиенты. Поддерживает SQLAlchemy 2.x, автоматическое определение драйвера и вывод структуры БД в табличном формате.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
MANIFEST.in
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
sqlalchemy_connection.egg-info/PKG-INFO
|
|
5
|
+
sqlalchemy_connection.egg-info/SOURCES.txt
|
|
6
|
+
sqlalchemy_connection.egg-info/dependency_links.txt
|
|
7
|
+
sqlalchemy_connection.egg-info/entry_points.txt
|
|
8
|
+
sqlalchemy_connection.egg-info/requires.txt
|
|
9
|
+
sqlalchemy_connection.egg-info/top_level.txt
|
|
10
|
+
sqlalchemy_connector/__init__.py
|
|
11
|
+
sqlalchemy_connector/_builder.py
|
|
12
|
+
sqlalchemy_connector/cli.py
|
|
13
|
+
sqlalchemy_connector/real_generator.py
|
|
14
|
+
sqlalchemy_connector/templates/admin_cart_html_template.html
|
|
15
|
+
sqlalchemy_connector/templates/admin_html_template.html
|
|
16
|
+
sqlalchemy_connector/templates/admin_users_html_template.html
|
|
17
|
+
sqlalchemy_connector/templates/app_template.py
|
|
18
|
+
sqlalchemy_connector/templates/base_html_template.html
|
|
19
|
+
sqlalchemy_connector/templates/cart_html_template.html
|
|
20
|
+
sqlalchemy_connector/templates/catalog_html_template.html
|
|
21
|
+
sqlalchemy_connector/templates/checkout_html_template.html
|
|
22
|
+
sqlalchemy_connector/templates/dashboard_html_template.html
|
|
23
|
+
sqlalchemy_connector/templates/index_html_template.html
|
|
24
|
+
sqlalchemy_connector/templates/login_html_template.html
|
|
25
|
+
sqlalchemy_connector/templates/models_template.py
|
|
26
|
+
sqlalchemy_connector/templates/new_request_html_template.html
|
|
27
|
+
sqlalchemy_connector/templates/orders_html_template.html
|
|
28
|
+
sqlalchemy_connector/templates/product_form_html_template.html
|
|
29
|
+
sqlalchemy_connector/templates/product_html_template.html
|
|
30
|
+
sqlalchemy_connector/templates/profile_html_template.html
|
|
31
|
+
sqlalchemy_connector/templates/register_html_template.html
|
|
32
|
+
sqlalchemy_connector/templates/reviews_html_template.html
|
|
33
|
+
sqlalchemy_connector/templates/service_detail_html_template.html
|
|
34
|
+
sqlalchemy_connector/templates/service_form_html_template.html
|
|
35
|
+
sqlalchemy_connector/templates/services_html_template.html
|
|
36
|
+
sqlalchemy_connector/templates/slider_js_template.js
|
|
37
|
+
sqlalchemy_connector/templates/style_css_template.css
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
sqlalchemy_connector
|
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Модуль сбора конфигурации для генератора.
|
|
5
|
+
"""
|
|
6
|
+
import sys
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def ask(prompt, default=None):
|
|
11
|
+
"""Задаёт вопрос и возвращает ответ. Если пустой — возвращает default."""
|
|
12
|
+
if default is not None:
|
|
13
|
+
full_prompt = f"{prompt} [{default}]: "
|
|
14
|
+
else:
|
|
15
|
+
full_prompt = f"{prompt}: "
|
|
16
|
+
answer = input(full_prompt).strip()
|
|
17
|
+
return answer if answer else default
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def ask_yes_no(prompt, default="нет"):
|
|
21
|
+
"""Задаёт вопрос да/нет. Возвращает True/False."""
|
|
22
|
+
hint = " [да/нет]" if default is None else (f" [да/нет, по умолчанию {default}]")
|
|
23
|
+
while True:
|
|
24
|
+
answer = input(prompt + hint + ": ").strip().lower()
|
|
25
|
+
if not answer and default is not None:
|
|
26
|
+
return default in ("да", "yes", "y", "д")
|
|
27
|
+
if answer in ("да", "yes", "y", "д", "+", "1"):
|
|
28
|
+
return True
|
|
29
|
+
if answer in ("нет", "no", "n", "н", "-", "0"):
|
|
30
|
+
return False
|
|
31
|
+
print(" Введите 'да' или 'нет'")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def ask_choice(prompt, choices, default=None):
|
|
35
|
+
"""Предлагает выбор из списка. Возвращает выбранный элемент."""
|
|
36
|
+
print(prompt)
|
|
37
|
+
for i, c in enumerate(choices, 1):
|
|
38
|
+
marker = " (по умолчанию)" if c == default else ""
|
|
39
|
+
print(f" {i}. {c}{marker}")
|
|
40
|
+
while True:
|
|
41
|
+
raw = input("Ваш выбор (номер): ").strip()
|
|
42
|
+
if not raw and default is not None:
|
|
43
|
+
return default
|
|
44
|
+
if raw.isdigit() and 1 <= int(raw) <= len(choices):
|
|
45
|
+
return choices[int(raw) - 1]
|
|
46
|
+
print(f" Введите число от 1 до {len(choices)}")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# ─────────────────────────────────────────────
|
|
50
|
+
# Типы полей для кастомных полей
|
|
51
|
+
# ─────────────────────────────────────────────
|
|
52
|
+
FIELD_TYPES = [
|
|
53
|
+
("text", "Текстовое поле (строка)"),
|
|
54
|
+
("textarea", "Многострочный текст"),
|
|
55
|
+
("email", "Email"),
|
|
56
|
+
("phone", "Телефон"),
|
|
57
|
+
("date", "Дата"),
|
|
58
|
+
("time", "Время"),
|
|
59
|
+
("datetime", "Дата и время"),
|
|
60
|
+
("number", "Число"),
|
|
61
|
+
("select", "Выпадающий список (выбор из вариантов)"),
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def ask_custom_fields(section_name):
|
|
66
|
+
"""Интерактивный ввод произвольных полей. Возвращает список словарей."""
|
|
67
|
+
fields = []
|
|
68
|
+
print(f"\n Добавление полей для: {section_name}")
|
|
69
|
+
print(" (Введите пустое название чтобы закончить)\n")
|
|
70
|
+
|
|
71
|
+
while True:
|
|
72
|
+
label = ask(f" Название поля (отображаемое)")
|
|
73
|
+
if not label:
|
|
74
|
+
break
|
|
75
|
+
|
|
76
|
+
# Предлагаем имя для БД
|
|
77
|
+
suggested_name = label.lower().replace(" ", "_")
|
|
78
|
+
# Транслитерация кириллицы
|
|
79
|
+
translit_map = {
|
|
80
|
+
'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo',
|
|
81
|
+
'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'y', 'к': 'k', 'л': 'l', 'м': 'm',
|
|
82
|
+
'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
|
|
83
|
+
'ф': 'f', 'х': 'kh', 'ц': 'ts', 'ч': 'ch', 'ш': 'sh', 'щ': 'shch',
|
|
84
|
+
'ъ': '', 'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', 'я': 'ya',
|
|
85
|
+
}
|
|
86
|
+
transliterated = ""
|
|
87
|
+
for ch in suggested_name:
|
|
88
|
+
if ch in translit_map:
|
|
89
|
+
transliterated += translit_map[ch]
|
|
90
|
+
elif ch.isascii():
|
|
91
|
+
transliterated += ch
|
|
92
|
+
else:
|
|
93
|
+
transliterated += "_"
|
|
94
|
+
# Убираем двойные подчёркивания
|
|
95
|
+
while "__" in transliterated:
|
|
96
|
+
transliterated = transliterated.replace("__", "_")
|
|
97
|
+
transliterated = transliterated.strip("_")
|
|
98
|
+
|
|
99
|
+
db_name = ask(f" Имя в БД (латиница)", transliterated)
|
|
100
|
+
|
|
101
|
+
# Тип поля
|
|
102
|
+
print(" Тип поля:")
|
|
103
|
+
for i, (code, desc) in enumerate(FIELD_TYPES, 1):
|
|
104
|
+
print(f" {i}. {desc}")
|
|
105
|
+
while True:
|
|
106
|
+
type_raw = input(" Номер типа [1]: ").strip()
|
|
107
|
+
if not type_raw:
|
|
108
|
+
field_type = "text"
|
|
109
|
+
break
|
|
110
|
+
if type_raw.isdigit() and 1 <= int(type_raw) <= len(FIELD_TYPES):
|
|
111
|
+
field_type = FIELD_TYPES[int(type_raw) - 1][0]
|
|
112
|
+
break
|
|
113
|
+
print(f" Введите число от 1 до {len(FIELD_TYPES)}")
|
|
114
|
+
|
|
115
|
+
# Варианты для select
|
|
116
|
+
options = []
|
|
117
|
+
if field_type == "select":
|
|
118
|
+
opts_raw = ask(" Варианты через запятую")
|
|
119
|
+
if opts_raw:
|
|
120
|
+
options = [o.strip() for o in opts_raw.split(",") if o.strip()]
|
|
121
|
+
|
|
122
|
+
required = ask_yes_no(" Обязательное поле?", "нет")
|
|
123
|
+
|
|
124
|
+
fields.append({
|
|
125
|
+
"label": label,
|
|
126
|
+
"name": db_name,
|
|
127
|
+
"type": field_type,
|
|
128
|
+
"required": required,
|
|
129
|
+
"options": options,
|
|
130
|
+
})
|
|
131
|
+
print(f" ✔ Поле «{label}» ({field_type}) добавлено\n")
|
|
132
|
+
|
|
133
|
+
return fields
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def collect_config():
|
|
137
|
+
"""Собирает конфигурацию проекта через диалог с пользователем."""
|
|
138
|
+
print("\n" + "=" * 60)
|
|
139
|
+
print(" 🏗️ Генератор сайтов на Flask")
|
|
140
|
+
print("=" * 60 + "\n")
|
|
141
|
+
|
|
142
|
+
config = {}
|
|
143
|
+
|
|
144
|
+
# ── Основные параметры ──────────────────────────────────────
|
|
145
|
+
config["project_name"] = ask("Название проекта (папка)", "mysite")
|
|
146
|
+
config["output_path"] = ask("Путь для создания проекта", os.getcwd())
|
|
147
|
+
|
|
148
|
+
# ── Авторизация ─────────────────────────────────────────────
|
|
149
|
+
print("\n── Авторизация ──")
|
|
150
|
+
auth_type = ask_choice(
|
|
151
|
+
"Авторизация пользователей по:",
|
|
152
|
+
["Логин + пароль", "Email + пароль"],
|
|
153
|
+
default="Логин + пароль"
|
|
154
|
+
)
|
|
155
|
+
config["auth_by_email"] = ("Email" in auth_type)
|
|
156
|
+
|
|
157
|
+
# ── Поля пользователя ────────────────────────────────────────
|
|
158
|
+
print("\n── Поля пользователя ──")
|
|
159
|
+
print("Стандартные поля (логин/email, пароль, роль) уже включены.")
|
|
160
|
+
print("Добавьте дополнительные поля для профиля пользователя:")
|
|
161
|
+
|
|
162
|
+
# Предлагаем популярные поля
|
|
163
|
+
config["user_full_name"] = ask_yes_no("Добавить поле ФИО", "да")
|
|
164
|
+
if not config["auth_by_email"]:
|
|
165
|
+
config["user_email"] = ask_yes_no("Добавить поле Email", "да")
|
|
166
|
+
else:
|
|
167
|
+
config["user_email"] = True # email уже есть как логин
|
|
168
|
+
config["user_phone"] = ask_yes_no("Добавить поле Телефон", "да")
|
|
169
|
+
config["user_birth_date"] = ask_yes_no("Добавить поле Дата рождения", "да")
|
|
170
|
+
config["user_address"] = ask_yes_no("Добавить поле Адрес", "нет")
|
|
171
|
+
config["user_gender"] = ask_yes_no("Добавить поле Пол", "нет")
|
|
172
|
+
config["user_city"] = ask_yes_no("Добавить поле Город", "нет")
|
|
173
|
+
config["user_workplace"] = ask_yes_no("Добавить поле Место работы/учёбы", "нет")
|
|
174
|
+
config["user_passport"] = ask_yes_no("Добавить поле Паспортные данные (серия/номер)", "нет")
|
|
175
|
+
config["user_inn"] = ask_yes_no("Добавить поле ИНН", "нет")
|
|
176
|
+
config["user_snils"] = ask_yes_no("Добавить поле СНИЛС", "нет")
|
|
177
|
+
config["user_education"] = ask_yes_no("Добавить поле Образование", "нет")
|
|
178
|
+
config["user_position"] = ask_yes_no("Добавить поле Должность", "нет")
|
|
179
|
+
config["user_telegram"] = ask_yes_no("Добавить поле Telegram", "нет")
|
|
180
|
+
|
|
181
|
+
# Кастомные поля пользователя
|
|
182
|
+
print("\n Хотите добавить ещё поля пользователя?")
|
|
183
|
+
print(" (Например: отдел, должность, ИНН, СНИЛС и т.д.)")
|
|
184
|
+
add_custom_user = ask_yes_no(" Добавить дополнительные поля?", "нет")
|
|
185
|
+
if add_custom_user:
|
|
186
|
+
config["custom_user_fields"] = ask_custom_fields("Пользователь")
|
|
187
|
+
else:
|
|
188
|
+
config["custom_user_fields"] = []
|
|
189
|
+
|
|
190
|
+
# ── Корзина и товары ────────────────────────────────────────
|
|
191
|
+
print("\n── Корзина и товары ──")
|
|
192
|
+
print("Если включить корзину — будет создан каталог товаров,")
|
|
193
|
+
print("пользователи смогут добавлять товары в корзину и оформлять заказы.")
|
|
194
|
+
config["cart"] = ask_yes_no("Добавить функционал корзины с товарами?", "нет")
|
|
195
|
+
if config["cart"]:
|
|
196
|
+
config["cart_type"] = "products" # всегда товары
|
|
197
|
+
print("\n Стандартные поля товара: Название, Описание, Цена, Кол-во на складе, Фото.")
|
|
198
|
+
print(" Также будет поле «Активен» (можно снять товар с продажи).\n")
|
|
199
|
+
print(" Хотите добавить дополнительные атрибуты товара?")
|
|
200
|
+
print(" (Например: размер, цвет, материал, вес, бренд и т.д.)")
|
|
201
|
+
add_product_attrs = ask_yes_no(" Добавить доп. атрибуты товара?", "нет")
|
|
202
|
+
if add_product_attrs:
|
|
203
|
+
config["custom_product_fields"] = ask_custom_fields("Товар")
|
|
204
|
+
else:
|
|
205
|
+
config["custom_product_fields"] = []
|
|
206
|
+
else:
|
|
207
|
+
config["cart_type"] = None
|
|
208
|
+
config["custom_product_fields"] = []
|
|
209
|
+
|
|
210
|
+
# ── Если корзина включена — заявки и услуги не нужны ─────────
|
|
211
|
+
if config["cart"]:
|
|
212
|
+
# Корзина заменяет заявки и услуги
|
|
213
|
+
config["custom_request_fields"] = []
|
|
214
|
+
config["services"] = False
|
|
215
|
+
for k in ["svc_name","svc_description","svc_price","svc_duration","svc_category",
|
|
216
|
+
"svc_image","svc_max_clients","svc_location","svc_requirements","svc_is_active"]:
|
|
217
|
+
config[k] = False
|
|
218
|
+
# ── Статусы заказов ───────────────────────────────────────────
|
|
219
|
+
print("\n── Статусы заказов ──")
|
|
220
|
+
print("По умолчанию: Новый, Оплачен, Отправлен, Доставлен, Отменён")
|
|
221
|
+
custom_statuses = ask_yes_no("Изменить статусы?", "нет")
|
|
222
|
+
if custom_statuses:
|
|
223
|
+
raw = ask("Введите статусы через запятую")
|
|
224
|
+
config["statuses"] = [s.strip() for s in raw.split(",") if s.strip()]
|
|
225
|
+
else:
|
|
226
|
+
config["statuses"] = ["Новый", "Оплачен", "Отправлен", "Доставлен", "Отменён"]
|
|
227
|
+
|
|
228
|
+
# ── Поля оформления заказа ─────────────────────────────────
|
|
229
|
+
print("\n── Поля оформления заказа ──")
|
|
230
|
+
print("Когда пользователь оформляет заказ из корзины,")
|
|
231
|
+
print("можно запросить дополнительные данные (адрес доставки и т.д.).")
|
|
232
|
+
print("Если не добавить ни одного поля — заказ оформится сразу по кнопке.\n")
|
|
233
|
+
|
|
234
|
+
config["checkout_fields"] = []
|
|
235
|
+
# Предложим стандартные поля
|
|
236
|
+
if ask_yes_no(" Добавить поле 'Адрес доставки'?", "да"):
|
|
237
|
+
config["checkout_fields"].append({
|
|
238
|
+
"label": "Адрес доставки", "name": "delivery_address",
|
|
239
|
+
"type": "text", "required": True, "options": []
|
|
240
|
+
})
|
|
241
|
+
if ask_yes_no(" Добавить поле 'Получатель (ФИО)'?", "да"):
|
|
242
|
+
config["checkout_fields"].append({
|
|
243
|
+
"label": "Получатель (ФИО)", "name": "recipient_name",
|
|
244
|
+
"type": "text", "required": True, "options": []
|
|
245
|
+
})
|
|
246
|
+
if ask_yes_no(" Добавить поле 'Телефон для связи'?", "да"):
|
|
247
|
+
config["checkout_fields"].append({
|
|
248
|
+
"label": "Телефон для связи", "name": "contact_phone",
|
|
249
|
+
"type": "phone", "required": True, "options": []
|
|
250
|
+
})
|
|
251
|
+
if ask_yes_no(" Добавить поле 'Комментарий к заказу'?", "нет"):
|
|
252
|
+
config["checkout_fields"].append({
|
|
253
|
+
"label": "Комментарий к заказу", "name": "comment",
|
|
254
|
+
"type": "textarea", "required": False, "options": []
|
|
255
|
+
})
|
|
256
|
+
if ask_yes_no(" Добавить поле 'Способ доставки'?", "нет"):
|
|
257
|
+
config["checkout_fields"].append({
|
|
258
|
+
"label": "Способ доставки", "name": "delivery_method",
|
|
259
|
+
"type": "select", "required": True,
|
|
260
|
+
"options": ["Самовывоз", "Курьер", "Почта"]
|
|
261
|
+
})
|
|
262
|
+
if ask_yes_no(" Добавить поле 'Желаемая дата доставки'?", "нет"):
|
|
263
|
+
config["checkout_fields"].append({
|
|
264
|
+
"label": "Желаемая дата доставки", "name": "delivery_date",
|
|
265
|
+
"type": "date", "required": False, "options": []
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
# Кастомные поля оформления
|
|
269
|
+
add_custom_checkout = ask_yes_no(" Добавить другие поля оформления?", "нет")
|
|
270
|
+
if add_custom_checkout:
|
|
271
|
+
config["checkout_fields"].extend(ask_custom_fields("Оформление заказа"))
|
|
272
|
+
|
|
273
|
+
else:
|
|
274
|
+
# ── Поля заявки ──────────────────────────────────────────────
|
|
275
|
+
print("\n── Поля заявки ──")
|
|
276
|
+
print("Стандартные поля (ID, пользователь, статус, дата) уже включены.")
|
|
277
|
+
print("Добавьте поля, которые пользователь заполняет при создании заявки:")
|
|
278
|
+
print("(Например: категория проблемы, описание, автомобиль, дата бронирования...)\n")
|
|
279
|
+
|
|
280
|
+
config["custom_request_fields"] = ask_custom_fields("Заявка")
|
|
281
|
+
|
|
282
|
+
if not config["custom_request_fields"]:
|
|
283
|
+
# Если ничего не добавили — предложим базовые
|
|
284
|
+
print("\n Вы не добавили ни одного поля. Добавить стандартные?")
|
|
285
|
+
if ask_yes_no(" Добавить поле 'Описание'?", "да"):
|
|
286
|
+
config["custom_request_fields"].append({
|
|
287
|
+
"label": "Описание",
|
|
288
|
+
"name": "description",
|
|
289
|
+
"type": "textarea",
|
|
290
|
+
"required": True,
|
|
291
|
+
"options": [],
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
# ── Модуль услуг ─────────────────────────────────────────────
|
|
295
|
+
print("\n── Модуль услуг ──")
|
|
296
|
+
print("Услуги — это позиции, которые создаёт администратор.")
|
|
297
|
+
print("Пользователи могут просматривать услуги и подавать на них заявки.")
|
|
298
|
+
config["services"] = ask_yes_no("Добавить модуль услуг?", "нет")
|
|
299
|
+
if config["services"]:
|
|
300
|
+
print("\n Поля услуги (администратор заполняет при создании):")
|
|
301
|
+
config["svc_name"] = True # название — всегда
|
|
302
|
+
config["svc_description"] = ask_yes_no(" Добавить поле 'Описание'", "да")
|
|
303
|
+
config["svc_price"] = ask_yes_no(" Добавить поле 'Цена'", "да")
|
|
304
|
+
config["svc_duration"] = ask_yes_no(" Добавить поле 'Продолжительность'", "нет")
|
|
305
|
+
config["svc_category"] = ask_yes_no(" Добавить поле 'Категория'", "нет")
|
|
306
|
+
config["svc_image"] = ask_yes_no(" Добавить фотографию услуги (физический файл)?", "да")
|
|
307
|
+
config["svc_max_clients"] = ask_yes_no(" Добавить поле 'Макс. кол-во клиентов'", "нет")
|
|
308
|
+
config["svc_location"] = ask_yes_no(" Добавить поле 'Место проведения'", "нет")
|
|
309
|
+
config["svc_requirements"]= ask_yes_no(" Добавить поле 'Требования к клиенту'", "нет")
|
|
310
|
+
config["svc_is_active"] = ask_yes_no(" Добавить поле 'Активна (вкл/выкл)'", "да")
|
|
311
|
+
else:
|
|
312
|
+
# Заполняем дефолтами чтобы generator не падал
|
|
313
|
+
for k in ["svc_name","svc_description","svc_price","svc_duration","svc_category",
|
|
314
|
+
"svc_image","svc_max_clients","svc_location","svc_requirements","svc_is_active"]:
|
|
315
|
+
config[k] = False
|
|
316
|
+
|
|
317
|
+
# ── Статусы заявок ───────────────────────────────────────────
|
|
318
|
+
print("\n── Статусы заявок ──")
|
|
319
|
+
print("По умолчанию: Новая, В работе, Завершена")
|
|
320
|
+
custom = ask_yes_no("Изменить статусы?", "нет")
|
|
321
|
+
if custom:
|
|
322
|
+
raw = ask("Введите статусы через запятую")
|
|
323
|
+
config["statuses"] = [s.strip() for s in raw.split(",") if s.strip()]
|
|
324
|
+
else:
|
|
325
|
+
config["statuses"] = ["Новая", "В работе", "Завершена"]
|
|
326
|
+
|
|
327
|
+
# ── Администратор ────────────────────────────────────────────
|
|
328
|
+
print("\n── Администратор ──")
|
|
329
|
+
print("Введите данные администратора:")
|
|
330
|
+
if config["auth_by_email"]:
|
|
331
|
+
config["admin_login"] = ask("Email администратора", "admin@example.com")
|
|
332
|
+
else:
|
|
333
|
+
config["admin_login"] = ask("Логин администратора", "admin")
|
|
334
|
+
config["admin_password"] = ask("Пароль администратора", "admin123")
|
|
335
|
+
# Заполняем поля админа теми же полями что и у пользователя
|
|
336
|
+
config["admin_extra"] = {}
|
|
337
|
+
if config.get("user_full_name"):
|
|
338
|
+
config["admin_extra"]["full_name"] = ask(" ФИО администратора", "Администратор")
|
|
339
|
+
if config.get("user_email") and not config["auth_by_email"]:
|
|
340
|
+
config["admin_extra"]["email"] = ask(" Email администратора", "admin@example.com")
|
|
341
|
+
if config.get("user_phone"):
|
|
342
|
+
config["admin_extra"]["phone"] = ask(" Телефон администратора", "+7 (999) 000-00-00")
|
|
343
|
+
if config.get("user_birth_date"):
|
|
344
|
+
config["admin_extra"]["birth_date"] = ask(" Дата рождения администратора", "")
|
|
345
|
+
if config.get("user_address"):
|
|
346
|
+
config["admin_extra"]["address"] = ask(" Адрес администратора", "")
|
|
347
|
+
if config.get("user_city"):
|
|
348
|
+
config["admin_extra"]["city"] = ask(" Город администратора", "")
|
|
349
|
+
if config.get("user_telegram"):
|
|
350
|
+
config["admin_extra"]["telegram"] = ask(" Telegram администратора", "")
|
|
351
|
+
|
|
352
|
+
# ── Отзывы ───────────────────────────────────────────────────
|
|
353
|
+
print("\n── Отзывы ──")
|
|
354
|
+
config["reviews"] = ask_yes_no("Добавить отзывы на товары/услуги?", "нет")
|
|
355
|
+
|
|
356
|
+
# ── Фото до/после ────────────────────────────────────────────
|
|
357
|
+
print("\n── Фото «до/после» для заявок ──")
|
|
358
|
+
config["photo_before_after"] = ask_yes_no("Добавить фото «до/после» для заявок?", "нет")
|
|
359
|
+
|
|
360
|
+
# ── Анимации ─────────────────────────────────────────────────
|
|
361
|
+
print("\n── Анимации ──")
|
|
362
|
+
config["animations"] = ask_yes_no("Добавить анимации на сайт?", "да")
|
|
363
|
+
|
|
364
|
+
# ── Демо-данные ──────────────────────────────────────────────
|
|
365
|
+
print("\n── Демонстрационные данные ──")
|
|
366
|
+
config["demo_data"] = ask_yes_no("Создать скрипт с демонстрационными данными?", "нет")
|
|
367
|
+
|
|
368
|
+
return config
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def print_summary(config):
|
|
372
|
+
"""Выводит итоговую конфигурацию перед генерацией."""
|
|
373
|
+
print("\n" + "=" * 60)
|
|
374
|
+
print(" 📋 Итоговая конфигурация")
|
|
375
|
+
print("=" * 60)
|
|
376
|
+
print(f" Проект: {config['project_name']}")
|
|
377
|
+
print(f" Путь: {config['output_path']}")
|
|
378
|
+
auth_mode = "Email + пароль" if config.get("auth_by_email") else "Логин + пароль"
|
|
379
|
+
print(f" Авторизация: {auth_mode}")
|
|
380
|
+
|
|
381
|
+
# Поля пользователя
|
|
382
|
+
user_fields_str = []
|
|
383
|
+
if config.get("user_full_name"):
|
|
384
|
+
user_fields_str.append("ФИО")
|
|
385
|
+
if config.get("user_email"):
|
|
386
|
+
user_fields_str.append("Email")
|
|
387
|
+
if config.get("user_phone"):
|
|
388
|
+
user_fields_str.append("Телефон")
|
|
389
|
+
if config.get("user_birth_date"):
|
|
390
|
+
user_fields_str.append("Дата рождения")
|
|
391
|
+
if config.get("user_address"):
|
|
392
|
+
user_fields_str.append("Адрес")
|
|
393
|
+
if config.get("user_gender"):
|
|
394
|
+
user_fields_str.append("Пол")
|
|
395
|
+
if config.get("user_city"):
|
|
396
|
+
user_fields_str.append("Город")
|
|
397
|
+
if config.get("user_workplace"):
|
|
398
|
+
user_fields_str.append("Место работы/учёбы")
|
|
399
|
+
if config.get("user_passport"):
|
|
400
|
+
user_fields_str.append("Паспортные данные")
|
|
401
|
+
for f in config.get("custom_user_fields", []):
|
|
402
|
+
user_fields_str.append(f["label"])
|
|
403
|
+
print(f" Поля User: {', '.join(user_fields_str) if user_fields_str else '(нет доп. полей)'}")
|
|
404
|
+
|
|
405
|
+
# Поля заявки
|
|
406
|
+
req_fields_str = []
|
|
407
|
+
for f in config.get("custom_request_fields", []):
|
|
408
|
+
req_fields_str.append(f"{f['label']} ({f['type']})")
|
|
409
|
+
print(f" Поля заявки: {', '.join(req_fields_str) if req_fields_str else '(нет доп. полей)'}")
|
|
410
|
+
|
|
411
|
+
print(f" Статусы: {', '.join(config['statuses'])}")
|
|
412
|
+
print(f" Администратор: {config['admin_login']}")
|
|
413
|
+
svc_info = "да" if config.get("services") else "нет"
|
|
414
|
+
print(f" Модуль услуг: {svc_info}")
|
|
415
|
+
cart_info = "нет"
|
|
416
|
+
if config.get("cart"):
|
|
417
|
+
cart_info = f"да ({config.get('cart_type', '')})"
|
|
418
|
+
print(f" Корзина: {cart_info}")
|
|
419
|
+
print(f" Отзывы: {config['reviews']}")
|
|
420
|
+
print(f" Фото до/после: {config['photo_before_after']}")
|
|
421
|
+
print(f" Анимации: {config['animations']}")
|
|
422
|
+
print(f" Демо-данные: {config['demo_data']}")
|
|
423
|
+
print("=" * 60)
|
|
424
|
+
|
|
425
|
+
|