sMerge branch 'zorn-dev'
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,3 +15,4 @@ old_bot
|
|||||||
db.sqlite3
|
db.sqlite3
|
||||||
# Ignore files
|
# Ignore files
|
||||||
.fake
|
.fake
|
||||||
|
docker-compose.override.yaml
|
||||||
|
|||||||
11
Dockerfile
Normal file
11
Dockerfile
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
FROM python:3.12-alpine
|
||||||
|
|
||||||
|
COPY requirements.txt /
|
||||||
|
|
||||||
|
RUN set -ex ;\
|
||||||
|
apk add --no-cache musl-dev mariadb-connector-c-dev gcc ;\
|
||||||
|
pip3 install -r /requirements.txt ;\
|
||||||
|
pip3 cache purge ;\
|
||||||
|
apk del --rdepends --purge musl-dev gcc
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
3
bin/cli
Executable file
3
bin/cli
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
docker compose exec web python3 manage.py "$@"
|
||||||
3
bin/pip3
Executable file
3
bin/pip3
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
docker compose exec web pip3 "$@"
|
||||||
12
bin/update
Executable file
12
bin/update
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
cd `dirname $0`/..
|
||||||
|
|
||||||
|
git pull
|
||||||
|
|
||||||
|
docker compose down
|
||||||
|
docker compose build
|
||||||
|
docker compose up -d web
|
||||||
|
sleep 1
|
||||||
|
./bin/cli migrate
|
||||||
|
docker compose up -d
|
||||||
29
docker-compose.yaml
Normal file
29
docker-compose.yaml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: mariadb:11.6
|
||||||
|
restart: on-failure
|
||||||
|
environment:
|
||||||
|
- MYSQL_RANDOM_ROOT_PASSWORD=1
|
||||||
|
- MYSQL_DATABASE=touchh
|
||||||
|
- MYSQL_USER=touchh
|
||||||
|
- MYSQL_PASSWORD=${MYSQL_PASSWORD:-touchh}
|
||||||
|
volumes:
|
||||||
|
- ./var/mysql:/var/lib/mysql
|
||||||
|
bot:
|
||||||
|
&py_service
|
||||||
|
build: .
|
||||||
|
image: touchh-py
|
||||||
|
restart: on-failure
|
||||||
|
command: ['python3', 'manage.py', 'run_bot']
|
||||||
|
depends_on: ['db']
|
||||||
|
stop_signal: SIGINT
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
scheduler:
|
||||||
|
<<: *py_service
|
||||||
|
command: ['python3', 'manage.py', 'start_scheduler']
|
||||||
|
web:
|
||||||
|
<<: *py_service
|
||||||
|
command: ['python3', 'manage.py', 'runserver', '0.0.0.0:8000']
|
||||||
|
ports:
|
||||||
|
- "${DOCKER_HTTP_BIND:-8000}:8000"
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
# Generated by Django 5.1.4 on 2024-12-25 07:00
|
# Generated by Django 5.1.4 on 2024-12-25 07:00
|
||||||
|
=======
|
||||||
|
# Generated by Django 5.1.4 on 2024-12-28 00:49
|
||||||
|
>>>>>>> zorn-dev
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
|
|||||||
@@ -422,8 +422,8 @@ logging.basicConfig(
|
|||||||
level=logging.WARNING,
|
level=logging.WARNING,
|
||||||
format='%(asctime)s [%(levelname)s] %(message)s',
|
format='%(asctime)s [%(levelname)s] %(message)s',
|
||||||
handlers=[
|
handlers=[
|
||||||
logging.FileHandler("bnovo_plugin.log"),
|
logging.FileHandler("var/log/bnovo_plugin.log"), # Логи пишутся в файл
|
||||||
logging.StreamHandler()
|
logging.StreamHandler() # Логи выводятся в консоль
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -569,7 +569,10 @@ class BnovoPMSPlugin(BasePMSPlugin):
|
|||||||
data = response.json()
|
data = response.json()
|
||||||
logger.debug(f"Полученный ответ API: {json.dumps(data, indent=2, ensure_ascii=False)}")
|
logger.debug(f"Полученный ответ API: {json.dumps(data, indent=2, ensure_ascii=False)}")
|
||||||
bookings = data.get("bookings", [])
|
bookings = data.get("bookings", [])
|
||||||
logger.info(f"Получено бронирований: {len(bookings)}")
|
rooms = data.get("rooms", [])
|
||||||
|
|
||||||
|
|
||||||
|
logger.debug(f'bookings: {bookings}\n rooms: {rooms}')
|
||||||
all_bookings.extend(bookings)
|
all_bookings.extend(bookings)
|
||||||
|
|
||||||
pages_info = data.get("pages", {})
|
pages_info = data.get("pages", {})
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class EcviPMSPlugin(BasePMSPlugin):
|
|||||||
# Настройка логгера
|
# Настройка логгера
|
||||||
self.logger = logging.getLogger(self.__class__.__name__)
|
self.logger = logging.getLogger(self.__class__.__name__)
|
||||||
handler_console = logging.StreamHandler()
|
handler_console = logging.StreamHandler()
|
||||||
handler_file = logging.FileHandler('ecvi_pms_plugin.log')
|
handler_file = logging.FileHandler('var/log/ecvi_pms_plugin.log')
|
||||||
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
||||||
handler_console.setFormatter(formatter)
|
handler_console.setFormatter(formatter)
|
||||||
handler_file.setFormatter(formatter)
|
handler_file.setFormatter(formatter)
|
||||||
|
|||||||
@@ -64,73 +64,3 @@ ua-parser-builtins==0.18.0.post1
|
|||||||
urllib3==2.2.3
|
urllib3==2.2.3
|
||||||
user-agents==2.2.0
|
user-agents==2.2.0
|
||||||
yarl==1.18.3
|
yarl==1.18.3
|
||||||
mysqlclient
|
|
||||||
chardet
|
|
||||||
python-decouple
|
|
||||||
cryptography
|
|
||||||
mysqlclientace_tools==0.0
|
|
||||||
aiohappyeyeballs==2.4.4
|
|
||||||
aiohttp==3.11.10
|
|
||||||
aiosignal==1.3.1
|
|
||||||
anyio==4.6.2.post1
|
|
||||||
APScheduler==3.11.0
|
|
||||||
asgiref==3.8.1
|
|
||||||
async-timeout==5.0.1
|
|
||||||
attrs==24.2.0
|
|
||||||
certifi==2024.8.30
|
|
||||||
cffi==1.17.1
|
|
||||||
chardet==5.2.0
|
|
||||||
charset-normalizer==3.4.0
|
|
||||||
cryptography==44.0.0
|
|
||||||
defusedxml==0.7.1
|
|
||||||
Django==5.1.4
|
|
||||||
django-environ==0.11.2
|
|
||||||
django-filter==24.3
|
|
||||||
django-health-check==3.18.3
|
|
||||||
django-jazzmin==3.0.1
|
|
||||||
django-jet==1.0.8
|
|
||||||
et_xmlfile==2.0.0
|
|
||||||
exceptiongroup==1.2.2
|
|
||||||
fonttools==4.55.3
|
|
||||||
fpdf2==2.8.2
|
|
||||||
frozenlist==1.5.0
|
|
||||||
geoip2==4.8.1
|
|
||||||
git-filter-repo==2.47.0
|
|
||||||
h11==0.14.0
|
|
||||||
httpcore==1.0.7
|
|
||||||
httpx==0.28.0
|
|
||||||
idna==3.10
|
|
||||||
jsonschema==4.23.0
|
|
||||||
jsonschema-specifications==2024.10.1
|
|
||||||
maxminddb==2.6.2
|
|
||||||
multidict==6.1.0
|
|
||||||
mysqlclient==2.2.6
|
|
||||||
numpy==2.1.3
|
|
||||||
openpyxl==3.1.5
|
|
||||||
pandas==2.2.3
|
|
||||||
pathspec==0.12.1
|
|
||||||
pillow==11.0.0
|
|
||||||
propcache==0.2.1
|
|
||||||
psycopg==3.2.3
|
|
||||||
pycparser==2.22
|
|
||||||
PyMySQL==1.1.1
|
|
||||||
python-dateutil==2.9.0.post0
|
|
||||||
python-decouple==3.8
|
|
||||||
python-dotenv==1.0.1
|
|
||||||
python-telegram-bot==21.8
|
|
||||||
pytz==2024.2
|
|
||||||
PyYAML==6.0.2
|
|
||||||
referencing==0.35.1
|
|
||||||
requests==2.32.3
|
|
||||||
rpds-py==0.22.3
|
|
||||||
six==1.17.0
|
|
||||||
sniffio==1.3.1
|
|
||||||
sqlparse==0.5.2
|
|
||||||
typing_extensions==4.12.2
|
|
||||||
tzdata==2024.2
|
|
||||||
tzlocal==5.2
|
|
||||||
ua-parser==1.0.0
|
|
||||||
ua-parser-builtins==0.18.0.post1
|
|
||||||
urllib3==2.2.3
|
|
||||||
user-agents==2.2.0
|
|
||||||
yarl==1.18.3
|
|
||||||
|
|||||||
17
scheduler/migrations/0002_alter_scheduledtask_options.py
Normal file
17
scheduler/migrations/0002_alter_scheduledtask_options.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Generated by Django 5.1.4 on 2024-12-28 00:49
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('scheduler', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='scheduledtask',
|
||||||
|
options={'verbose_name': 'Запланированная задача', 'verbose_name_plural': 'Запланированные задачи'},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -5,28 +5,6 @@ import logging
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logger.info("Загрузка модели ScheduledTask")
|
logger.info("Загрузка модели ScheduledTask")
|
||||||
|
|
||||||
class ScheduledTask(models.Model):
|
|
||||||
task_name = models.CharField(max_length=255)
|
|
||||||
function_path = models.CharField(max_length=255)
|
|
||||||
minutes = models.CharField(max_length=255)
|
|
||||||
hours = models.CharField(max_length=255)
|
|
||||||
months = models.CharField(max_length=255)
|
|
||||||
weekdays = models.CharField(max_length=100, blank=True, default="")
|
|
||||||
active = models.BooleanField(default=True)
|
|
||||||
last_run = models.DateTimeField(null=True, blank=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
def clean_weekdays(self):
|
|
||||||
"""Приводим список в строку при сохранении."""
|
|
||||||
if isinstance(self.weekdays, list):
|
|
||||||
self.weekdays = ",".join(map(str, self.weekdays))
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = "Запланированная задача"
|
|
||||||
verbose_name_plural = "Запланированные задачи"
|
|
||||||
|
|
||||||
def get_available_functions():
|
def get_available_functions():
|
||||||
from scheduler.utils import get_project_functions
|
from scheduler.utils import get_project_functions
|
||||||
return [(path, name) for path, name in get_project_functions()]
|
return [(path, name) for path, name in get_project_functions()]
|
||||||
@@ -48,3 +26,12 @@ class ScheduledTask(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.task_name
|
return self.task_name
|
||||||
|
|
||||||
|
def clean_weekdays(self):
|
||||||
|
"""Приводим список в строку при сохранении."""
|
||||||
|
if isinstance(self.weekdays, list):
|
||||||
|
self.weekdays = ",".join(map(str, self.weekdays))
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = "Запланированная задача"
|
||||||
|
verbose_name_plural = "Запланированные задачи"
|
||||||
@@ -5,3 +5,14 @@
|
|||||||
.ml-6 {
|
.ml-6 {
|
||||||
margin-left: 1.5rem !important;
|
margin-left: 1.5rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-sidebar ul.nav-treeview .nav-link {
|
||||||
|
padding-left: 2rem;
|
||||||
|
}
|
||||||
|
.nav-sidebar .nav-link {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.nav-sidebar .nav-link .nav-icon {
|
||||||
|
margin-top: .2rem;
|
||||||
|
margin-right: .3rem;
|
||||||
|
}
|
||||||
|
|||||||
@@ -101,11 +101,11 @@ GEOIP_PATH = os.path.join(BASE_DIR, 'geoip')
|
|||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
'NAME': os.getenv('DB_NAME'), # Имя базы данных
|
'NAME': os.getenv('DB_NAME', default='touchh'), # Имя базы данных
|
||||||
'USER': os.getenv('DB_ROOT_USER'), # Имя пользователя базы данных
|
'USER': os.getenv('DB_ROOT_USER', default='touchh'), # Имя пользователя базы данных
|
||||||
'PASSWORD': os.getenv('DB_PASSWORD'), # Пароль пользователя
|
'PASSWORD': os.getenv('DB_PASSWORD', default='touchh'), # Пароль пользователя
|
||||||
'HOST': os.getenv('DB_HOST', default='0.0.0.0'), # Хост (по умолчанию localhost)
|
'HOST': os.getenv('DB_HOST', default='db'), # Хост (по умолчанию localhost)
|
||||||
'PORT': os.getenv('DB_PORT', default=3308), # Порт (по умолчанию 3306)
|
'PORT': os.getenv('DB_PORT', default=3306), # Порт (по умолчанию 3306)
|
||||||
'ATOMIC_REQUESTS': True,
|
'ATOMIC_REQUESTS': True,
|
||||||
|
|
||||||
},
|
},
|
||||||
@@ -139,7 +139,7 @@ LOGGING = {
|
|||||||
'file': {
|
'file': {
|
||||||
'level': os.getenv("LOG_LEVEL"),
|
'level': os.getenv("LOG_LEVEL"),
|
||||||
'class': 'logging.FileHandler',
|
'class': 'logging.FileHandler',
|
||||||
'filename': 'import_hotels.log', # Лог будет записываться в этот файл
|
'filename': 'var/log/import_hotels.log', # Лог будет записываться в этот файл
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'loggers': {
|
'loggers': {
|
||||||
@@ -283,4 +283,3 @@ JAZZMIN_SETTINGS = {
|
|||||||
"show_ui_builder_tabs_breadcrumbs": False,
|
"show_ui_builder_tabs_breadcrumbs": False,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class CustomLogger:
|
|||||||
self.logger.handlers.clear()
|
self.logger.handlers.clear()
|
||||||
|
|
||||||
# Добавляем обработчик для файла
|
# Добавляем обработчик для файла
|
||||||
file_handler = logging.FileHandler("project.log")
|
file_handler = logging.FileHandler("var/log/project.log")
|
||||||
file_handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
|
file_handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
|
||||||
file_handler.setLevel(self.log_level)
|
file_handler.setLevel(self.log_level)
|
||||||
|
|
||||||
|
|||||||
2
var/.gitignore
vendored
Normal file
2
var/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
2
var/log/.gitignore
vendored
Normal file
2
var/log/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
Reference in New Issue
Block a user