docker environ removed. Rollback to development

This commit is contained in:
2024-12-23 10:25:52 +09:00
parent 091db21cf8
commit 31e4a50ad8
28 changed files with 126 additions and 391 deletions

3
.gitignore vendored
View File

@@ -13,4 +13,5 @@ old_bot
*.mmdb
*.log
db.sqlite3
# Ignore files
# Ignore files
.fake

View File

@@ -4,3 +4,4 @@ from django.apps import AppConfig
class AntifroudConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'antifroud'
verbose_name="Анти-Fraud"

View File

@@ -1,12 +1,12 @@
# settings.py
from .models import LocalDatabase
from decouple import config
from django.conf import settings
from .models import LocalDatabase
from django.apps import apps
def load_database_settings():
# Загружаем настройки из базы данных
LocalDatabase = apps.get_model('app_settings', 'LocalDatabase')
local_db_settings = LocalDatabase.objects.all()
for db in local_db_settings:

View File

@@ -3,4 +3,5 @@ from django.apps import AppConfig
class SettingsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'settings'
name = 'app_settings'
verbose_name="Настройки системы"

File diff suppressed because one or more lines are too long

View File

@@ -6,7 +6,7 @@ from django.core.management.base import BaseCommand
from telegram.ext import Application
from bot.utils.bot_setup import setup_bot
from scheduler.tasks import load_tasks_to_scheduler
from settings.models import TelegramSettings
from app_settings.models import TelegramSettings
from touchh.utils.log import CustomLogger
class Command(BaseCommand):

View File

@@ -1,92 +0,0 @@
import os
import json
from datetime import datetime, timedelta
import requests
from django.db import models
from asgiref.sync import sync_to_async
class APIDataLogger:
"""Класс для работы с API, сохранения и обработки данных."""
def __init__(self, name, url, token=None, username=None, password=None):
self.name = name
self.url = url
self.token = token
self.username = username
self.password = password
self.output_dir = "modules"
def ensure_directory_exists(self, path):
"""Создать директорию, если она не существует."""
if not os.path.exists(path):
os.makedirs(path)
def fetch_data(self, additional_data=None):
"""Получить данные из API."""
headers = {"Content-Type": "application/json"}
data = additional_data or {}
if self.token:
data["token"] = self.token
response = requests.post(self.url, headers=headers, json=data, auth=(self.username, self.password) if self.username and self.password else None)
if response.status_code != 200:
print(f'{self.name}: API запрос не удался. Код статуса: {response.status_code}')
return []
return response.json()
def save_data(self, data, suffix):
"""Сохранить данные в файл JSON."""
now = datetime.now()
current_date = now.strftime('%Y-%m-%d')
directory = os.path.join(self.output_dir, current_date, self.name)
self.ensure_directory_exists(directory)
filename = f"{self.name} {suffix}.json"
filepath = os.path.join(directory, filename)
with open(filepath, 'w') as file:
json.dump(data, file)
return filepath
def load_previous_data(self, suffixes):
"""Загрузить данные из файлов за текущий и предыдущий интервалы."""
now = datetime.now()
current_date = now.strftime('%Y-%m-%d')
yesterday_date = (now - timedelta(days=1)).strftime('%Y-%m-%d')
directories = [(yesterday_date, "21"), (current_date, "9")] if 9 <= now.hour < 21 else [(current_date, "9"), (current_date, "21")]
data_combined = []
for date, suffix in directories:
filepath = os.path.join(self.output_dir, date, self.name, f"{self.name} {suffix}.json")
try:
with open(filepath, 'r') as file:
data_combined.extend(json.load(file))
except FileNotFoundError:
pass
return data_combined
def filter_data(self, data, filter_function):
"""Фильтрация данных с использованием переданной функции."""
return filter_function(data)
def process_and_save(self, additional_data=None, filter_function=None):
"""Основной процесс: запрос, сохранение, чтение, фильтрация."""
now = datetime.now()
suffix = "9" if 9 <= now.hour < 21 else "21"
# Шаг 1: Получить данные
raw_data = self.fetch_data(additional_data)
self.save_data(raw_data, suffix)
# Шаг 2: Загрузить данные за текущий и предыдущий интервал
combined_data = self.load_previous_data(["9", "21"])
# Шаг 3: Фильтрация
if filter_function:
combined_data = self.filter_data(combined_data, filter_function)
return combined_data

View File

@@ -1,53 +0,0 @@
import json
from datetime import datetime
def parse_pms_data(data, parser_settings):
date_format = parser_settings["date_format"]
fields_mapping = parser_settings["fields_mapping"]
conditions = parser_settings.get("conditions", {})
parsed_data = []
for record in data:
# Применение условий фильтрации
if conditions:
for condition_field, expected_value in conditions.items():
if record.get(condition_field) != expected_value:
break
else:
# Условие выполнено
pass
else:
# Условие отсутствует
pass
# Разбор полей
parsed_record = {}
for internal_field, external_field in fields_mapping.items():
if "." in external_field: # Например, "guests[0].lastName"
keys = external_field.split(".")
value = record
try:
for key in keys:
if key.endswith("]"): # Обработка индексов, например, "guests[0]"
key, index = key[:-1].split("[")
value = value[key][int(index)]
else:
value = value[key]
except (KeyError, IndexError, TypeError):
value = None
else:
value = record.get(external_field)
# Преобразование дат
if "date" in internal_field or "time" in internal_field:
try:
value = datetime.strptime(value, date_format)
except (ValueError, TypeError):
value = None
parsed_record[internal_field] = value
parsed_data.append(parsed_record)
return parsed_data

View File

@@ -1,23 +1,11 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
# manage.py
import os
import sys
import logging
# Настройка логирования
logging.basicConfig(
level=logging.ERROR, # Уровень логирования (можно DEBUG для полной информации)
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[
logging.FileHandler("bot.log"), # Логи будут записываться в файл bot.log
logging.StreamHandler() # Логи также будут отображаться в консоли
]
)
def main():
"""Run administrative tasks."""
"""Main routine for managing the Django project."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'touchh.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
@@ -28,6 +16,5 @@ def main():
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
if __name__ == "__main__":
main()

View File

@@ -66,4 +66,5 @@ user-agents==2.2.0
yarl==1.18.3
mysqlclient
chardet
python-decouple
python-decouple
cryptography

View File

@@ -4,3 +4,4 @@ from django.apps import AppConfig
class SchedulerConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'scheduler'
verbose_name="Планировщик заданий"

View File

@@ -1,30 +0,0 @@
# Generated by Django 5.1.4 on 2024-12-14 02:10
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='LocalDatabase',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='Имя базы данных')),
('host', models.CharField(default='localhost', max_length=255, verbose_name='Хост базы данных')),
('port', models.IntegerField(default=5432, verbose_name='Порт базы данных')),
('user', models.CharField(max_length=255, verbose_name='Пользователь базы данных')),
('password', models.CharField(max_length=255, verbose_name='Пароль базы данных')),
('is_active', models.BooleanField(default=True, verbose_name='Активна ли база данных')),
],
options={
'verbose_name': 'Локальная база данных',
'verbose_name_plural': 'Локальные базы данных',
},
),
]

View File

@@ -1,33 +0,0 @@
# Generated by Django 5.1.4 on 2024-12-14 02:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('settings', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='EmailSettings',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('smtp_server', models.CharField(help_text='SMTP сервер для отправки почты', max_length=255)),
('smtp_port', models.IntegerField(default=587, help_text='SMTP порт для почты')),
('smtp_user', models.CharField(help_text='Имя пользователя для SMTP', max_length=255)),
('smtp_password', models.CharField(help_text='Пароль для SMTP', max_length=255)),
('from_email', models.EmailField(help_text='Email для отправки сообщений', max_length=254)),
],
),
migrations.CreateModel(
name='TelegramSettings',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('bot_token', models.CharField(help_text='Токен вашего бота Telegram', max_length=255)),
('chat_id', models.CharField(help_text='ID чата для отправки сообщений', max_length=255)),
('username', models.CharField(blank=True, help_text='Имя пользователя для бота', max_length=255, null=True)),
],
),
]

View File

@@ -1,19 +0,0 @@
# Generated by Django 5.1.4 on 2024-12-14 02:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('settings', '0002_emailsettings_telegramsettings'),
]
operations = [
migrations.AddField(
model_name='localdatabase',
name='database',
field=models.CharField(default=1, max_length=255, verbose_name='Название базы данных'),
preserve_default=False,
),
]

View File

@@ -1,35 +0,0 @@
# Generated by Django 5.1.4 on 2024-12-14 02:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('settings', '0003_localdatabase_database'),
]
operations = [
migrations.CreateModel(
name='GlobalHotelSettings',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('check_in_time', models.TimeField(help_text='Время заезда')),
('check_out_time', models.TimeField(help_text='Время выезда')),
('currency', models.CharField(help_text='Валюта', max_length=3)),
('timezone', models.CharField(help_text='Часовой пояс', max_length=255)),
],
options={
'verbose_name': 'Глобальные настройки отеля',
'verbose_name_plural': 'Глобальные настройки отеля',
},
),
migrations.AlterModelOptions(
name='emailsettings',
options={'verbose_name': 'Настройки почты', 'verbose_name_plural': 'Настройки почты'},
),
migrations.AlterModelOptions(
name='telegramsettings',
options={'verbose_name': 'Настройки Telegram', 'verbose_name_plural': 'Настройки Telegram'},
),
]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,33 +0,0 @@
# Generated by Django 5.1.4 on 2024-12-17 11:21
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('settings', '0006_remove_globalhotelsettings_timezone_and_more'),
]
operations = [
migrations.AlterModelOptions(
name='emailsettings',
options={'verbose_name': 'E-mail', 'verbose_name_plural': 'E-mails'},
),
migrations.AlterModelOptions(
name='globalhotelsettings',
options={'verbose_name': 'Настройки отеля', 'verbose_name_plural': 'Настройки отеля'},
),
migrations.AlterModelOptions(
name='globalsystemsettings',
options={'verbose_name': 'Настройки системы', 'verbose_name_plural': 'Настройки системы'},
),
migrations.AlterModelOptions(
name='localdatabase',
options={'verbose_name': 'База данных', 'verbose_name_plural': 'Базы данных'},
),
migrations.AlterModelOptions(
name='telegramsettings',
options={'verbose_name': 'Telegram', 'verbose_name_plural': 'Telegram'},
),
]

View File

@@ -13,4 +13,5 @@ from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'touchh.settings')
application = get_asgi_application()

View File

@@ -57,7 +57,7 @@ INSTALLED_APPS = [
'health_check',
'health_check.db',
'health_check.cache',
'settings',
'app_settings',
]
@@ -99,13 +99,14 @@ DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.getenv('DB_NAME'), # Имя базы данных
'USER': os.getenv('DB_USER'), # Имя пользователя базы данных
'USER': os.getenv('DB_ROOT_USER'), # Имя пользователя базы данных
'PASSWORD': os.getenv('DB_PASSWORD'), # Пароль пользователя
'HOST': os.getenv('DB_HOST', default='127.0.0.1'), # Хост (по умолчанию localhost)
'PORT': os.getenv('DB_PORT', default=3306), # Порт (по умолчанию 3306)
'HOST': os.getenv('DB_HOST', default='0.0.0.0'), # Хост (по умолчанию localhost)
'PORT': os.getenv('DB_PORT', default=3308), # Порт (по умолчанию 3306)
},
}
# Password validation
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators
@@ -188,7 +189,8 @@ JAZZMIN_SETTINGS = {
"welcome_sign": "Welcome to TOUCHH Hotel Management System",
"show_sidebar": True,
"navigation_expanded": False,
"hide_models": ["auth.Users", "guests"],
"hide_models": ["auth", "guests"],
"order_with_respect_to": ["users", "hotels"],
"site_logo": None, # Путь к логотипу, например "static/images/logo.png"
"site_logo_classes": "img-circle", # Классы CSS для логотипа
"site_icon": None, # Иконка сайта (favicon), например "static/images/favicon.ico"
@@ -198,6 +200,16 @@ JAZZMIN_SETTINGS = {
"auth": "fas fa-users-cog",
"users": "fas fa-user-circle",
"hotels": "fas fa-hotel",
"hotels.hotel": "fas fa-hotel",
"hotels.room":"fas fa-bed",
"hotels.reservation":"fas fa-calendar-week",
"hotels.userhotel":"fas fa-user-shield",
"app_settings": "fas fa-wrench",
"scheduler": "fas fa-clock",
"pms_integration": "fas fa-sync",
"antifroud": "fas fa-shield-alt",
},
"theme": "sandstone",
"dark_mode_theme": "darkly",
@@ -210,26 +222,11 @@ JAZZMIN_SETTINGS = {
{"name": "Smartsoltech", "url": "https://smartsoltech.kr", "new_window": True}
],
"custom_links": { # Кастомные ссылки в боковом меню
"auth": [{
"name": "Сбросить пароль",
"url": "reset_password",
"icon": "fas fa-key",
"permissions": ["auth.change_user"],
}],
},
# Пользовательский интерфейс
"show_sidebar": True, # Отображать боковую панель
"navigation_expanded": True, # Раскрывать меню по умолчанию
"hide_apps": [], # Список приложений, которые нужно скрыть
"hide_models": [], # Список моделей, которые нужно скрыть
"order_with_respect_to": ["auth", "users", "hotels"], # Порядок приложений
"icons": { # Иконки для приложений и моделей
"auth": "fas fa-users-cog",
"users": "fas fa-users",
"bot": "fas fa-robot",
"hotels": "fas fa-hotel",
},
"show_ui_builder": True,
"show_ui_builder_breadcrumbs": True,
"show_ui_builder_tabs": True,
"show_ui_builder_tabs_breadcrumbs": True,
}

View File

@@ -13,4 +13,5 @@ from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'touchh.settings')
application = get_wsgi_application()

View File

@@ -4,3 +4,4 @@ from django.apps import AppConfig
class UsersConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'users'
verbose_name="Пользователи"