#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Работа с JSON
"""
# ######################################################################################################################
# Импорт необходимых инструментов
# ######################################################################################################################
import os # Работа с файловой системой
import json # Кодирование и декодирование данные в удобном формате
import importlib.resources as pkg_resources # Работа с ресурсами внутри пакетов
from dataclasses import dataclass # Класс данных
from typing import Dict, Union # Типы данных
from types import ModuleType
# Персональные
from openav.modules.file_manager.download import Download # Загрузка файлов
# ######################################################################################################################
# Сообщения
# ######################################################################################################################
[документация]@dataclass
class JsonMessages(Download):
"""Класс для сообщений
Args:
path_to_logs (str): Смотреть :attr:`~openav.modules.core.logging.Logging.path_to_logs`
lang (str): Смотреть :attr:`~openav.modules.core.language.Language.lang`
"""
# ------------------------------------------------------------------------------------------------------------------
# Конструктор
# ------------------------------------------------------------------------------------------------------------------
def __post_init__(self):
super().__post_init__() # Выполнение конструктора из суперкласса
self._load_data: str = self._('Загрузка данных из файла "{}"') + self._em
self._invalid_file: str = self._("Данные не загружены") + self._em
self._config_empty: str = self._("Файл пуст") + self._em
self._load_data_resources: str = self._('Загрузка данных из ресурсов "{}"') + self._em
self._load_data_resources_not_found: str = self._("Ресурс не найден") + self._em
# ######################################################################################################################
# Работа с JSON
# ######################################################################################################################
[документация]@dataclass
class Json(JsonMessages):
"""Класс для работы с JSON
Args:
path_to_logs (str): Смотреть :attr:`~openav.modules.core.logging.Logging.path_to_logs`
lang (str): Смотреть :attr:`~openav.modules.core.language.Language.lang`
"""
# ------------------------------------------------------------------------------------------------------------------
# Конструктор
# ------------------------------------------------------------------------------------------------------------------
def __post_init__(self):
super().__post_init__() # Выполнение конструктора из суперкласса
# ------------------------------------------------------------------------------------------------------------------
# Внешние методы
# ------------------------------------------------------------------------------------------------------------------
[документация] def load_json(
self, path_to_file: str, create: bool = False, out: bool = True
) -> Dict[str, Union[str, bool, int, float,],]:
"""Загрузка JSON файла
Args:
path_to_file (str): Путь к файлу JSON
create (bool): Создание файла JSON в случае его отсутствия
out (bool): Печатать процесс выполнения
Returns:
Dict[str, Union[str, bool, int, float]]: Словарь из json файла
"""
# Проверка аргументов
if type(path_to_file) is not str or not path_to_file or type(create) is not bool or type(out) is not bool:
self.inv_args(__class__.__name__, self.load_json.__name__, out=out)
return {}
# Поиск JSON файла не удался
if self.search_file(path_to_file, "json", create, out) is False:
return {}
path_to_file = os.path.normpath(path_to_file)
# Вывод сообщения
self.message_info(
self._load_data.format(self.message_line(os.path.basename(path_to_file))), space=self._space, out=out
)
# Открытие файла
with open(path_to_file, mode="r", encoding="utf-8") as json_data_file:
try:
config = json.load(json_data_file)
except json.JSONDecodeError:
self.message_error(self._invalid_file, space=self._space, out=out)
return {}
# Файл пуст
if not config:
self.message_error(self._config_empty, space=self._space, out=out)
return {}
return config # Результат
[документация] def load_json_resources(
self, module: ModuleType, path_to_file: str, out: bool = True
) -> Dict[str, Union[str, bool, int, float]]:
"""Загрузка JSON файла из ресурсов модуля
Args:
module (ModuleType): Модуль
path_to_file (str): Путь к файлу JSON
out (bool): Печатать процесс выполнения
Returns:
Dict[str, Union[str, bool, int, float]]: Словарь из json файла
"""
# Проверка аргументов
if (
isinstance(module, ModuleType) is False
or type(path_to_file) is not str
or not path_to_file
or type(out) is not bool
):
self.inv_args(__class__.__name__, self.load_json_resources.__name__, out=out)
return {}
# Вывод сообщения
self.message_info(self._load_data_resources.format(self.message_line(module.__name__)), out=out)
# Ресурс с JSON файлом не найден
if pkg_resources.is_resource(module, path_to_file) is False:
self.message_error(self._load_data_resources_not_found, space=self._space, out=out)
return {}
# Открытие файла
with pkg_resources.open_text(module, path_to_file, encoding="utf-8", errors="strict") as json_data_file:
try:
config = json.load(json_data_file)
except json.JSONDecodeError:
self.message_error(self._invalid_file, space=self._space, out=out)
return {}
# Файл пуст
if not config:
self.message_error(self._config_empty, space=self._space, out=out)
return {}
return config # Результат