From eb6d23bba8c4331ba19f0b0ed2953fe99467ea94 Mon Sep 17 00:00:00 2001 From: Maksim Date: Tue, 2 Sep 2025 11:40:27 +0300 Subject: [PATCH] =?UTF-8?q?=D0=AD=D0=BD=D0=B4=D0=BF=D0=BE=D0=B8=D0=BD?= =?UTF-8?q?=D1=82=D1=8B=20=D1=82=D0=BE=D0=BF=D0=BB=D0=B8=D0=B2=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D1=81=D1=82=D1=8C=D1=8E=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D1=8E=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapters/parsers/monitoring_fuel.py | 103 ++++++++++++++++-- python_parser/app/main.py | 4 +- python_parser/core/services.py | 14 +++ 3 files changed, 110 insertions(+), 11 deletions(-) diff --git a/python_parser/adapters/parsers/monitoring_fuel.py b/python_parser/adapters/parsers/monitoring_fuel.py index 7f41328..528e883 100644 --- a/python_parser/adapters/parsers/monitoring_fuel.py +++ b/python_parser/adapters/parsers/monitoring_fuel.py @@ -39,9 +39,31 @@ class MonitoringFuelParser(ParserPort): columns = validated_params["columns"] - # TODO: Переделать под новую архитектуру - df_means, _ = self.aggregate_by_columns(self.df, columns) - return df_means.to_dict(orient='index') + # Проверяем, есть ли данные в data_dict (из парсинга) или в df (из загрузки) + if hasattr(self, 'data_dict') and self.data_dict is not None: + # Данные из парсинга + data_source = self.data_dict + elif hasattr(self, 'df') and self.df is not None and not self.df.empty: + # Данные из загрузки - преобразуем DataFrame обратно в словарь + data_source = self._df_to_data_dict() + else: + return {} + + # Агрегируем данные по колонкам + df_means, _ = self.aggregate_by_columns(data_source, columns) + + # Преобразуем в JSON-совместимый формат + result = {} + for idx, row in df_means.iterrows(): + result[str(idx)] = {} + for col in columns: + value = row.get(col) + if pd.isna(value) or value == float('inf') or value == float('-inf'): + result[str(idx)][col] = None + else: + result[str(idx)][col] = float(value) if isinstance(value, (int, float)) else value + + return result def _get_month_by_code(self, params: dict): """Получение данных за конкретный месяц""" @@ -50,14 +72,73 @@ class MonitoringFuelParser(ParserPort): month = validated_params["month"] - # TODO: Переделать под новую архитектуру - df_month = self.get_month(self.df, month) - return df_month.to_dict(orient='index') + # Проверяем, есть ли данные в data_dict (из парсинга) или в df (из загрузки) + if hasattr(self, 'data_dict') and self.data_dict is not None: + # Данные из парсинга + data_source = self.data_dict + elif hasattr(self, 'df') and self.df is not None and not self.df.empty: + # Данные из загрузки - преобразуем DataFrame обратно в словарь + data_source = self._df_to_data_dict() + else: + return {} + + # Получаем данные за конкретный месяц + df_month = self.get_month(data_source, month) + + # Преобразуем в JSON-совместимый формат + result = {} + for idx, row in df_month.iterrows(): + result[str(idx)] = {} + for col in df_month.columns: + value = row[col] + if pd.isna(value) or value == float('inf') or value == float('-inf'): + result[str(idx)][col] = None + else: + result[str(idx)][col] = float(value) if isinstance(value, (int, float)) else value + + return result + + def _df_to_data_dict(self): + """Преобразование DataFrame обратно в словарь данных""" + if not hasattr(self, 'df') or self.df is None or self.df.empty: + return {} + + data_dict = {} + + # Группируем данные по месяцам + for _, row in self.df.iterrows(): + month = row.get('month') + data = row.get('data') + + if month and data is not None: + data_dict[month] = data + + return data_dict def parse(self, file_path: str, params: dict) -> pd.DataFrame: """Парсинг файла и возврат DataFrame""" - # Сохраняем DataFrame для использования в геттерах - self.df = self.parse_monitoring_fuel_files(file_path, params) + # Парсим данные и сохраняем словарь для использования в геттерах + self.data_dict = self.parse_monitoring_fuel_files(file_path, params) + + # Преобразуем словарь в DataFrame для совместимости с services.py + if self.data_dict: + # Создаем DataFrame с информацией о месяцах и данных + data_rows = [] + for month, df_data in self.data_dict.items(): + if df_data is not None and not df_data.empty: + data_rows.append({ + 'month': month, + 'rows_count': len(df_data), + 'data': df_data + }) + + if data_rows: + df = pd.DataFrame(data_rows) + self.df = df + return df + + # Если данных нет, возвращаем пустой DataFrame + self.df = pd.DataFrame() return self.df def parse_monitoring_fuel_files(self, zip_path: str, params: dict) -> Dict[str, pd.DataFrame]: @@ -148,7 +229,11 @@ class MonitoringFuelParser(ParserPort): if 'name' in df_full.columns: # Применяем функцию get_id_by_name к каждой строке в колонке 'name' # df_full['id'] = df_full['name'].apply(get_object_by_name) # This line was removed as per new_code - pass # Placeholder for new_code + # Временно используем name как id + df_full['id'] = df_full['name'] + else: + # Если нет колонки name, создаем id из индекса + df_full['id'] = df_full.index # Устанавливаем id как индекс df_full.set_index('id', inplace=True) diff --git a/python_parser/app/main.py b/python_parser/app/main.py index 578d06a..302eaed 100644 --- a/python_parser/app/main.py +++ b/python_parser/app/main.py @@ -804,7 +804,7 @@ async def get_monitoring_fuel_total_by_columns( try: # Создаем запрос request_dict = request_data.model_dump() - request_dict['mode'] = 'total' + request_dict['mode'] = 'total_by_columns' request = DataRequest( report_type='monitoring_fuel', get_params=request_dict @@ -849,7 +849,7 @@ async def get_monitoring_fuel_month_by_code( try: # Создаем запрос request_dict = request_data.model_dump() - request_dict['mode'] = 'month' + request_dict['mode'] = 'month_by_code' request = DataRequest( report_type='monitoring_fuel', get_params=request_dict diff --git a/python_parser/core/services.py b/python_parser/core/services.py index d66d1bc..e2d1146 100644 --- a/python_parser/core/services.py +++ b/python_parser/core/services.py @@ -124,6 +124,20 @@ class ReportService: if request.report_type == 'svodka_ca': # Для svodka_ca используем геттер get_ca_data getter_name = 'get_ca_data' + elif request.report_type == 'monitoring_fuel': + # Для monitoring_fuel определяем геттер из параметра mode + getter_name = get_params.pop("mode", None) + if not getter_name: + # Если режим не указан, берем первый доступный + available_getters = list(parser.getters.keys()) + if available_getters: + getter_name = available_getters[0] + print(f"⚠️ Режим не указан, используем первый доступный: {getter_name}") + else: + return DataResult( + success=False, + message="Парсер не имеет доступных геттеров" + ) else: # Для других парсеров определяем из параметра mode getter_name = get_params.pop("mode", None)