This commit is contained in:
2025-10-09 13:14:59 +03:00
parent 681093d48f
commit 5aeaaf5575
2 changed files with 118 additions and 109 deletions

View File

@@ -0,0 +1,115 @@
# anb_python_components/classes/directory.py
import os
import platform
import subprocess
from anb_python_components.classes.action_state import ActionState
class Directory:
"""
Класс для работы с директориями.
"""
# Словарь сообщений об ошибках для удаления директории
REMOVE_DIRECTORY_ERROR_MESSAGES: dict[str, str] = {
'directory_not_exist': "Директория не существует или нет доступа на запись!",
'error_deleting_directory': 'Ошибка удаления каталога: %s. Код возврата: %d!',
'unhandled_error': 'Ошибка удаления директории %s: %s!'
}
@staticmethod
def remove (directory: str, error_messages: dict[str, str] | None = None) -> ActionState[bool]:
"""
Рекурсивно удаляет директорию с соответствующим результатом.
:param directory: Путь к директории.
:param error_messages: Слова для отображения ошибок. По умолчанию используются сообщения из REMOVE_DIRECTORY_ERROR_MESSAGES.
:return: Объект ActionState с информацией о результате.
"""
# Создаем объект ActionState для хранения результата
result = ActionState[bool](False)
# Если не заданы сообщения об ошибках
if error_messages is None:
# - устанавливаем сообщения по умолчанию
error_messages = Directory.REMOVE_DIRECTORY_ERROR_MESSAGES
try:
# Проверяем существование директории
if not Directory.is_exists(directory):
# - если директория не существует, добавляем ошибку
result.add_error(error_messages['directory_not_exist'])
# - возвращаем результат
return result
# Определяем текущую операционную систему
system_os = platform.system().lower()
# Проверяем операционную систему. Если это Windows
if system_os == 'windows':
# - задаем команду для Windows
command = ['cmd.exe', '/C', 'rd', '/S', '/Q', directory]
else:
# - иначе задаем команду для Unix-подобных систем
command = ['rm', '-rf', directory]
# Запуск команды с безопасностью (используется subprocess.run)
process = subprocess.run(command, capture_output = True, text = True)
# Анализируем код возврата процесса и если он не равен 0
if process.returncode != 0:
# - добавляем ошибку
result.add_error(error_messages['error_deleting_directory'] % (directory, process.returncode))
# - возвращаем результат
return result
# Установка успешного результата
result.value = True
# Возвращаем результат
return result
except Exception as ex:
# Обработка необработанных исключений
result.add_error(error_messages['unhandled_error'] % (directory, str(ex)))
return result
@staticmethod
def is_exists (directory: str, check_access_level: str = '') -> bool:
"""
Проверяет существование директории и доступность по правам доступа.
:param directory: Путь к директории.
:param check_access_level: Строка, содержащая символы 'r', 'w' и 'x', которые указывают на необходимость проверки прав доступа на чтение, запись и исполнение соответственно. Если строка пустая, проверка прав доступа не выполняется. Если нет какого-либо символа, проверка прав доступа не выполняется для этого типа прав. По умолчанию: ''.
:return: True, если директория существует и доступна, иначе False.
"""
# Проверяем существование директории
if not os.path.exists(directory):
# - и если директория не существует, возвращаем False
return False
# Проверяем, что это именно директория, а не файл
if not os.path.isdir(directory):
# - если это не директория, возвращаем False
return False
# Задаем флаги проверки прав доступа
access_level_check = check_access_level.lower()
# Проверяем права на чтение, если это требуется
if 'r' in access_level_check and not os.access(directory, os.R_OK):
# - если нет прав на чтение, возвращаем False
return False
# Проверяем права на запись, если это требуется
if 'w' in access_level_check and not os.access(directory, os.W_OK):
# - если нет прав на запись, возвращаем False
return False
# Проверяем права на исполнение, если это требуется
if 'x' in access_level_check and not os.access(directory, os.X_OK):
# - если нет прав на запись, возвращаем False
return False
# Если все проверки успешны, возвращаем True
return True

View File

@@ -2,8 +2,6 @@
import glob
import math
import os
import platform
import subprocess
from anb_python_components.classes.action_state import ActionState
@@ -12,13 +10,6 @@ class File:
Класс для работы с файлами.
"""
# Словарь сообщений об ошибках для удаления директории
REMOVE_DIRECTORY_ERROR_MESSAGES: dict[str, str] = {
'directory_not_exist': "Директория не существует или нет доступа на запись!",
'error_deleting_directory': 'Ошибка удаления каталога: %s. Код возврата: %d!',
'unhandled_error': 'Ошибка удаления директории %s: %s!'
}
# Словарь сообщений об ошибках для получения размера файла
FILE_SIZE_ERROR_MESSAGES: dict[str, str] = {
'file_not_exist': 'Файл не существует!',
@@ -30,7 +21,7 @@ class File:
FILE_SIZE_UNITS: list[str] = ['байт', 'КБ', 'МБ', 'ГБ', 'ТБ']
@staticmethod
def find_files (directory: str, pattern: str = '*', exclude_list: set[str] = str()) -> list | bool:
def find (directory: str, pattern: str = '*', exclude_list: set[str] = str()) -> list | bool:
"""
Ищет файлы, удовлетворяющие заданному паттерну, рекурсивно проходя по указанным директориям.
:param directory: Директория, в которой производится поиск.
@@ -105,104 +96,7 @@ class File:
return full_path[len(base_path):] if base_path.lower() in full_path.lower() else False
@staticmethod
def remove_dir (directory: str, error_messages: dict[str, str] | None = None) -> ActionState[bool]:
"""
Рекурсивно удаляет директорию с соответствующим результатом.
:param directory: Путь к директории.
:param error_messages: Слова для отображения ошибок. По умолчанию используются сообщения из REMOVE_DIRECTORY_ERROR_MESSAGES.
:return: Объект ActionState с информацией о результате.
"""
# Создаем объект ActionState для хранения результата
result = ActionState[bool](False)
# Если не заданы сообщения об ошибках
if error_messages is None:
# - устанавливаем сообщения по умолчанию
error_messages = File.REMOVE_DIRECTORY_ERROR_MESSAGES
try:
# Проверяем существование директории
if not File.directory_exists(directory):
# - если директория не существует, добавляем ошибку
result.add_error(error_messages['directory_not_exist'])
# - возвращаем результат
return result
# Определяем текущую операционную систему
system_os = platform.system().lower()
# Проверяем операционную систему. Если это Windows
if system_os == 'windows':
# - задаем команду для Windows
command = ['cmd.exe', '/C', 'rd', '/S', '/Q', directory]
else:
# - иначе задаем команду для Unix-подобных систем
command = ['rm', '-rf', directory]
# Запуск команды с безопасностью (используется subprocess.run)
process = subprocess.run(command, capture_output = True, text = True)
# Анализируем код возврата процесса и если он не равен 0
if process.returncode != 0:
# - добавляем ошибку
result.add_error(error_messages['error_deleting_directory'] % (directory, process.returncode))
# - возвращаем результат
return result
# Установка успешного результата
result.value = True
# Возвращаем результат
return result
except Exception as ex:
# Обработка необработанных исключений
result.add_error(error_messages['unhandled_error'] % (directory, str(ex)))
return result
@staticmethod
def directory_exists (directory: str, check_access_level: str = '') -> bool:
"""
Проверяет существование директории и доступность по правам доступа.
:param directory: Путь к директории.
:param check_access_level: Строка, содержащая символы 'r', 'w' и 'x', которые указывают на необходимость проверки прав доступа на чтение, запись и исполнение соответственно. Если строка пустая, проверка прав доступа не выполняется. Если нет какого-либо символа, проверка прав доступа не выполняется для этого типа прав. По умолчанию: ''.
:return: True, если директория существует и доступна, иначе False.
"""
# Проверяем существование директории
if not os.path.exists(directory):
# - и если директория не существует, возвращаем False
return False
# Проверяем, что это именно директория, а не файл
if not os.path.isdir(directory):
# - если это не директория, возвращаем False
return False
# Задаем флаги проверки прав доступа
access_level_check = check_access_level.lower()
# Проверяем права на чтение, если это требуется
if 'r' in access_level_check and not os.access(directory, os.R_OK):
# - если нет прав на чтение, возвращаем False
return False
# Проверяем права на запись, если это требуется
if 'w' in access_level_check and not os.access(directory, os.W_OK):
# - если нет прав на запись, возвращаем False
return False
# Проверяем права на исполнение, если это требуется
if 'x' in access_level_check and not os.access(directory, os.X_OK):
# - если нет прав на запись, возвращаем False
return False
# Если все проверки успешны, возвращаем True
return True
@staticmethod
def file_size (file_name: str, error_localization: dict[str, str] | None = None) -> ActionState[int]:
def size (file_name: str, error_localization: dict[str, str] | None = None) -> ActionState[int]:
"""
Получает размер файла и формирует результат с возможными ошибками.
@@ -245,7 +139,7 @@ class File:
return result
@staticmethod
def file_size_to_string (
def size_to_string (
file_size: int, localize_file_size: dict[str, str] | None = None, decimal_separator: str = '.'
) -> str:
"""