import importlib import os from pathlib import Path from django.conf import settings from .plugins.base_plugin import BasePMSPlugin from asgiref.sync import sync_to_async class PluginLoader: PLUGIN_PATH = Path(__file__).parent / "plugins" @staticmethod def load_plugins(): plugins = {} if not PluginLoader.PLUGIN_PATH.exists(): print("Папка с плагинами не существует:", PluginLoader.PLUGIN_PATH) return plugins print("Загрузка плагинов:") for file in os.listdir(PluginLoader.PLUGIN_PATH): if file.endswith("_pms.py") and not file.startswith("__"): # print(f" Plugin {file}") module_name = f"pms_integration.plugins.{file[:-3]}" try: module = importlib.import_module(module_name) for attr in dir(module): cls = getattr(module, attr) if isinstance(cls, type) and issubclass(cls, BasePMSPlugin) and cls is not BasePMSPlugin: plugin_name = file[:-7] # Убираем `_pms` из имени файла # print(f" Загружен плагин {plugin_name}: {cls.__name__}") plugins[plugin_name] = cls except Exception as e: print(f" Ошибка загрузки плагина {module_name}: {e}") return plugins class PMSIntegrationManager: def __init__(self, hotel_id): self.hotel_id = hotel_id self.hotel = None self.pms_config = None self.plugin = None async def load_hotel(self): """ Загружает данные отеля и PMS конфигурацию. """ from hotels.models import Hotel self.hotel = await sync_to_async(Hotel.objects.select_related("pms").get)(id=self.hotel_id) self.pms_config = self.hotel.pms if not self.pms_config: raise ValueError(f"Отель {self.hotel.name} не имеет связанной PMS конфигурации.") def load_plugin(self): """ Загружает плагин для PMS на основе конфигурации отеля. """ plugins = PluginLoader.load_plugins() if not self.hotel: raise ValueError("Отель не загружен. Пожалуйста, вызовите load_hotel перед загрузкой плагина.") if not self.hotel.pms: raise ValueError(f"Отель {self.hotel.name} не связан с PMS конфигурацией.") if self.hotel.pms.plugin_name not in plugins: raise ValueError(f"Плагин для PMS {self.hotel.pms.plugin_name} не найден.") # Передача объекта Hotel в плагин self.plugin = plugins[self.hotel.pms.plugin_name](self.hotel) def fetch_data(self): """ Получает данные из PMS с использованием загруженного плагина. """ if not self.plugin: self.load_plugin() return self.plugin.fetch_data() async def save_log(self, status, message): """ Сохраняет запись в лог интеграции. """ from .models import PMSIntegrationLog await sync_to_async(PMSIntegrationLog.objects.create)( hotel=self.hotel, status=status, message=message, )