20251009
This commit is contained in:
115
anb_python_components/classes/directory.py
Normal file
115
anb_python_components/classes/directory.py
Normal 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
|
@@ -2,8 +2,6 @@
|
|||||||
import glob
|
import glob
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import platform
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from anb_python_components.classes.action_state import ActionState
|
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_SIZE_ERROR_MESSAGES: dict[str, str] = {
|
||||||
'file_not_exist': 'Файл не существует!',
|
'file_not_exist': 'Файл не существует!',
|
||||||
@@ -30,7 +21,7 @@ class File:
|
|||||||
FILE_SIZE_UNITS: list[str] = ['байт', 'КБ', 'МБ', 'ГБ', 'ТБ']
|
FILE_SIZE_UNITS: list[str] = ['байт', 'КБ', 'МБ', 'ГБ', 'ТБ']
|
||||||
|
|
||||||
@staticmethod
|
@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: Директория, в которой производится поиск.
|
:param directory: Директория, в которой производится поиск.
|
||||||
@@ -105,104 +96,7 @@ class File:
|
|||||||
return full_path[len(base_path):] if base_path.lower() in full_path.lower() else False
|
return full_path[len(base_path):] if base_path.lower() in full_path.lower() else False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def remove_dir (directory: str, error_messages: dict[str, str] | None = None) -> ActionState[bool]:
|
def size (file_name: str, error_localization: dict[str, str] | None = None) -> ActionState[int]:
|
||||||
"""
|
|
||||||
Рекурсивно удаляет директорию с соответствующим результатом.
|
|
||||||
|
|
||||||
: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]:
|
|
||||||
"""
|
"""
|
||||||
Получает размер файла и формирует результат с возможными ошибками.
|
Получает размер файла и формирует результат с возможными ошибками.
|
||||||
|
|
||||||
@@ -245,7 +139,7 @@ class File:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def file_size_to_string (
|
def size_to_string (
|
||||||
file_size: int, localize_file_size: dict[str, str] | None = None, decimal_separator: str = '.'
|
file_size: int, localize_file_size: dict[str, str] | None = None, decimal_separator: str = '.'
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
|
Reference in New Issue
Block a user