This commit is contained in:
2025-10-09 23:25:32 +03:00
parent 5aeaaf5575
commit c06f4f7621
7 changed files with 518 additions and 1 deletions

View File

@@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Тест Directory" type="tests" factoryName="Autodetect">
<module name="anb_python_components" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/tests/classes" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;$PROJECT_DIR$/tests/classes/directory_test.py&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
</component>

View File

@@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Тест File" type="tests" factoryName="Autodetect">
<module name="anb_python_components" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/tests/classes" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;$PROJECT_DIR$/tests/classes/file_test.py&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
</component>

View File

@@ -1,5 +1,6 @@
# anb_python_components/classes/action_state.py
import glob
import hashlib
import math
import os
@@ -20,6 +21,15 @@ class File:
# Словарь локализации размеров файлов.
FILE_SIZE_UNITS: list[str] = ['байт', 'КБ', 'МБ', 'ГБ', 'ТБ']
@staticmethod
def is_exist (file_path: str) -> bool:
"""
Проверяет, существует ли файл по указанному пути.
:param file_path: Путь к файлу.
:return: bool: True, если файл существует, False в противном случае.
"""
return True if os.path.exists(file_path) and os.path.isfile(file_path) else False
@staticmethod
def find (directory: str, pattern: str = '*', exclude_list: set[str] = str()) -> list | bool:
"""
@@ -165,4 +175,52 @@ class File:
size = round(file_size / (1024 ** power), 2)
# Возвращаем преобразованное значение вместе с единицей измерения
return f"{size:,.2f} {localize_file_size[power]}".replace('.', decimal_separator)
return f"{size:,.2f} {localize_file_size[power]}".replace('.', decimal_separator)
@staticmethod
def hash (file_name: str, hash_algorithm: str = 'sha256') -> str:
"""
Вычисляет хэш файла.
:param file_name: Имя файла для которого нужно вычислить хэш.
:param hash_algorithm: Алгоритм хэширования. По умолчанию: 'sha256'.
:return: Строка с хэшем.
"""
# Преобразование алгоритма в нижний регистр
hash_algorithm = hash_algorithm.lower()
# Определяем алгоритм хэширования
match hash_algorithm:
# md5
case 'md5':
hasher = hashlib.md5()
# sha1
case 'sha1':
hasher = hashlib.sha1()
# sha256
case 'sha256':
hasher = hashlib.sha256()
# sha512
case 'sha512':
hasher = hashlib.sha512()
# sha3_256
case 'sha3_256':
hasher = hashlib.sha3_256()
# sha3_512
case 'sha3_512':
hasher = hashlib.sha3_512()
# blake2b
case 'blake2':
hasher = hashlib.blake2b()
# по умолчанию
case _:
hasher = hashlib.sha256()
# Открываем файл для чтения
with open(file_name, 'rb') as file:
# - читаем файл по 4096 байт, чтобы сэкономить память
while chunk := file.read(4096):
# - добавляем прочитанные данные в хэш
hasher.update(chunk)
# Возвращаем hex-представление хэша
return hasher.hexdigest()

View File

@@ -0,0 +1,85 @@
# Класс `Directory`
Класс `Directory` предоставляет инструменты для работы с каталогами (директориями) в операционной системе. Основными
функциями класса являются проверка существования директорий и их рекурсивное удаление. Этот класс полезен для
автоматизированных задач по управлению структурой папок в приложениях.
## Основная информация
- **Имя файла**: anb_python_components\classes\directory.py
- **Автор**: Александр Бабаев
- **Версия**: 1.0.0
- **Дата начала поддержки**: с версии 1.0
## Атрибуты и методы класса
### Словарь `REMOVE_DIRECTORY_ERROR_MESSAGES`
Словарь сообщений об ошибках для удаления директории.
```python
REMOVE_DIRECTORY_ERROR_MESSAGES: dict[str, str] = {
'directory_not_exist': "Директория не существует или нет доступа на запись!",
'error_deleting_directory': 'Ошибка удаления каталога: %s. Код возврата: %d!',
'unhandled_error': 'Ошибка удаления директории %s: %s!'
}
```
### Метод `remove`
Удаляет директорию вместе со всеми поддиректориями и файлами.
**Параметры**:
- **`directory: str`**: путь к директории, которую нужно удалить.
- **`error_messages: dict[str, str] | None = None`**: словарь с сообщениями об ошибках (опционально). Если задан как
`None`, то используется словарь `Directory.REMOVE_DIRECTORY_ERROR_MESSAGES`. По умолчанию, `None`.
**Возвращает**:
- Объект `ActionState`, содержащий результат операции и возможные сообщения об ошибках.
Пример использования:
```python
from anb_python_components.classes.directory import Directory
result = Directory.remove("/path/to/folder")
if result.is_success():
print("Директория успешно удалена.")
else:
print("Ошибка:", result.get_string_messages())
```
### Метод `is_exists`
Проверяет существование директории и (при необходимости) права доступа к ней.
**Параметры**:
- **`directory: str`**: путь к директории.
- **`check_access_level: str`**: строка, содержащая комбинации символов 'r', 'w', 'x' для проверки соответствующих прав
доступа (чтение, запись, исполнение). По умолчанию, `""`.
**Возвращает**:
- `True`, если директория существует и доступна по указанным параметрам, иначе `False`.
**Пример использования**:
```python
from anb_python_components.classes.directory import Directory
exists = Directory.is_exists("/path/to/folder", check_access_level = "rw")
if exists:
print("Директория существует и доступна для чтения и записи.")
else:
print("Проблемы с доступом к директории.")
```
## Заключение
Класс `Directory` позволяет упростить управление файловой системой, особенно полезными будут методы удаления и проверки
доступности директорий, которые помогают повысить устойчивость приложений к ошибкам.
[На главную](../../index.md)

View File

@@ -0,0 +1,242 @@
# Класс `File`
Класс `File` предоставляет разнообразные инструменты для работы с файлами в Python, начиная от простых операций, таких
как проверка существования файла, и заканчивая более продвинутыми возможностями, такими как поиск файлов по маске,
вычисление размера файла и его хэша.
## Основная информация
- **Имя файла**: anb_python_components\classes\file.py
- **Автор**: Александр Бабаев
- **Версия**: 1.0.0
- **Дата начала поддержки**: с версии 1.0
## Атрибуты и методы класса
### Словарь сообщений об ошибках (`FILE_SIZE_ERROR_MESSAGES`)
Этот словарь используется для локализованных сообщений об ошибках, которые возникают при попытке получить размер файла.
Каждое сообщение связано с определенным видом ошибки, и его можно настроить индивидуально для нужд приложения.
**Содержимое словаря**:
- `'file_not_exist'`: Сообщение выдается, если файл по указанному пути отсутствует.
- `'not_a_file'`: Сообщение появляется, если путь ведет не к файлу, а к каталогу или другому ресурсу.
- `'cannot_get_size'`: Сообщается, если возникли трудности с определением размера файла (например, из-за отсутствия
разрешения на чтение).
**Пример использования**:
```python
from anb_python_components.classes.file import File
error_msg = File.FILE_SIZE_ERROR_MESSAGES['file_not_exist']
print(error_msg) # Файл не существует!
```
### Словарь локализации размеров файлов (`FILE_SIZE_UNITS`)
Этот список используется для перевода единиц измерения размера файла на человеческий язык. Каждая единица измеряется
следующим образом:
- `'байт'`: Байты.
- `'КБ'`: Килобайты.
- `'МБ'`: Мегабайты.
- `'ГБ'`: Гигабайты.
- `'ТБ'`: Терабайты.
**Пример использования**:
```python
from anb_python_components.classes.file import File
units = File.FILE_SIZE_UNITS
print(units[2]) # МБ
```
### Метод `is_exist`
Проверяет, существует ли файл по указанному пути.
**Параметры**:
- **`file_path: str`**: Путь к файлу.
**Возвращает**:
- `True`, если файл существует, иначе `False`.
**Пример использования**:
```python
from anb_python_components.classes.file import File
if File.is_exist('/path/to/file.txt'):
print("Файл существует.")
```
### Метод `find`
Рекурсивно ищет файлы по указанному шаблону в каталоге.
Параметры:
- **`directory`**: Каталог для поиска.
- **`pattern`**: Маска имени файла (по умолчанию `'*'`).
- **`exclude_list`**: Список директорий, которые нужно исключить из поиска.
Возвращает:
- Список путей к найденным файлам.
Пример использования:
```python
from anb_python_components.classes.file import File
files = File.find('/home/user/', '*.txt')
for file in files:
print(file)
```
### Метод `extract_file_name`
Извлекает имя файла из полного пути.
Параметры:
- **`file_path`**: Полный путь к файлу.
Возвращает:
- Имя файла.
Пример использования:
```python
from anb_python_components.classes.file import File
name = File.extract_file_name('/home/user/document.txt')
print(name) # document.txt
```
### Метод `extract_file_extension`
Извлекает расширение файла из полного пути.
Параметры:
- **`file_path`**: Полный путь к файлу.
- **`with_dot`**: Включать ли точку перед расширением (по умолчанию `True`).
Возвращает:
- Расширение файла.
Пример использования:
```python
from anb_python_components.classes.file import File
extension = File.extract_file_extension('/home/user/image.jpg')
print(extension) # .jpg
```
### Метод `relative_path`
Возвращает относительный путь к файлу относительно заданной директории.
Параметры:
- **`full_path`**: Полный путь к файлу.
- **`base_path`**: Базовая директория.
Возвращает:
- Относительный путь к файлу или **`False`**, если путь не относится к заданной директории.
Пример использования:
```python
from anb_python_components.classes.file import File
rel_path = File.relative_path('/home/user/images/cat.png', '/home/user/')
print(rel_path) # images/cat.png
```
### Метод `size`
Получает размер файла и сохраняет результат в объект `ActionState`.
Параметры:
- **`file_name`**: Путь к файлу.
- **`error_localization`**: Сообщения об ошибках (опционально).
Возвращает:
- Объект `ActionState`, содержащий размер файла или информацию об ошибке.
Пример использования:
```python
from anb_python_components.classes.file import File
result = File.size('/path/to/file.txt')
if result.is_success():
print("Размер файла:", result.value)
else:
print("Ошибка:", result.get_string_messages())
```
### Метод `size_to_string`
Преобразует размер файла в строку с указанием единицы измерения (байты, КБ, МБ и т.д.).
Параметры:
- **`file_size`**: Размер файла в байтах.
- **`localize_file_size`**: Локализация единиц измерения (опционально).
- **`decimal_separator`**: Разделитель десятичной точки (по умолчанию `.`, может быть настроен на региональный формат).
Возвращает:
- Форматированную строку с размером файла.
Пример использования:
```python
from anb_python_components.classes.file import File
formatted_size = File.size_to_string(1024 * 1024)
print(formatted_size) # 1.00 MB
```
### Метод `hash`
Вычисляет хэш файла, используя заданный алгоритм.
Параметры:
- **`file_name`**: Путь к файлу.
- **`hash_algorithm`**: Алгоритм хэширования (по умолчанию SHA-256).
Возвращает:
- Хэш файла в виде шестнадцатеричной строки.
Пример использования:
```python
from anb_python_components.classes.file import File
file_hash = File.hash('/path/to/file.txt', 'sha256')
print(file_hash)
```
## Заключение
Класс `File` предоставляет широкий спектр полезных методов для работы с файлами, облегчая стандартные операции с файлами
и помогая решать задачи, связанные с управлением файлами в приложениях.
[На главную](../../index.md)

View File

@@ -0,0 +1,19 @@
# directory_test.py
import unittest
from anb_python_components.classes.directory import Directory
class DirectoryTest(unittest.TestCase):
def test_is_exists (self):
self.assertTrue(Directory.is_exists(r"C:\Windows", "r"))
self.assertFalse(Directory.is_exists(r"C:\Windows\1", "rw"))
# Создайте поддиректорию 123 в директории теста и заполните ее содержимым
self.assertTrue(Directory.is_exists(r".\123", "rwx"))
def test_remove (self):
# Создайте поддиректорию 123 в директории теста и заполните ее содержимым
self.assertTrue(Directory.remove(r".\123"))
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,79 @@
# file_test.py
import unittest
from anb_python_components.classes.file import File
class FileTest(unittest.TestCase):
def test_is_exists (self):
file_name = r"C:\Windows\explorer.exe"
dir_name = r"C:\Windows"
self.assertTrue(File.is_exist(file_name))
self.assertFalse(File.is_exist(dir_name))
def test_find (self):
find_list = File.find(r"..\classes", "*.py")
result = [
'..\\classes\\action_state_test.py', '..\\classes\\directory_test.py', '..\\classes\\file_test.py',
'..\\classes\\__init__.py'
]
self.assertEqual(result, find_list)
def test_extract_file_name (self):
file_name = r"C:\Windows\explorer.exe"
result = File.extract_file_name(file_name)
expected_result = "explorer.exe"
self.assertEqual(expected_result, result)
def test_extract_file_extension (self):
file_name = r"C:\Windows\explorer.exe"
result = File.extract_file_extension(file_name)
expected_result = ".exe"
self.assertEqual(expected_result, result)
result = File.extract_file_extension(file_name, False)
expected_result = "exe"
self.assertEqual(expected_result, result)
def test_extract_file_name_without_extension (self):
file_name = r"C:\Windows\explorer.exe"
result = File.extract_file_name_without_extension(file_name)
expected_result = "explorer"
self.assertEqual(expected_result, result)
def test_relative_path (self):
file_name = r"C:\Windows\explorer.exe"
result = File.relative_path(file_name, r"C:\Windows")
expected_result = r"\explorer.exe"
self.assertEqual(expected_result, result)
def test_size (self):
file_name = r"C:\Windows\explorer.exe"
result = File.size(file_name).value
expected_result = 2774080
self.assertEqual(expected_result, result)
def test_size_to_string (self):
file_name = r"C:\Windows\explorer.exe"
size = File.size(file_name).value
result = File.size_to_string(size)
expected_result = "2.65 МБ"
self.assertEqual(expected_result, result)
def test_hash (self):
file_name = r"C:\Windows\explorer.exe"
result = File.hash(file_name)
expected_result = "6345f80dd23b51d90bfdedfe03c51c9d85c5233c9fb2f2cfe9e1ac633a4895ca"
self.assertEqual(expected_result, result)
if __name__ == '__main__':
unittest.main()