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): """ Инициализирует PMSIntegrationManager с объектом отеля. :param hotel: Объект отеля, связанный с PMS. """ self.hotel = hotel self.plugin = None def load_hotel(self): """ Проверяет, что у отеля есть связанная PMS конфигурация. """ if not self.hotel.pms: raise ValueError(f"Отель {self.hotel.name} не имеет связанной PMS конфигурации.") def load_plugin(self): """ Загружает плагин, соответствующий PMS конфигурации отеля. """ pms_name = self.hotel.pms.plugin_name.lower() # Приводим название плагина к нижнему регистру # Формируем имя модуля и класса плагина plugin_module_name = f"pms_integration.plugins.{pms_name}_pms" plugin_class_name = f"{pms_name.capitalize()}PMSPlugin" try: # Динамически импортируем модуль плагина plugin_module = importlib.import_module(plugin_module_name) # Динамически получаем класс плагина plugin_class = getattr(plugin_module, plugin_class_name, None) if not plugin_class or not issubclass(plugin_class, BasePMSPlugin): raise ImportError(f"Класс {plugin_class_name} не найден или не является наследником BasePMSPlugin.") # Инициализируем плагин self.plugin = plugin_class(self.hotel) except ImportError as e: raise ValueError(f"Ошибка загрузки плагина для PMS {pms_name}: {e}") 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, )