20251009
This commit is contained in:
17
.run/Тест Directory.run.xml
Normal file
17
.run/Тест Directory.run.xml
Normal 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="""" />
|
||||
<option name="_new_target" value=""$PROJECT_DIR$/tests/classes/directory_test.py"" />
|
||||
<option name="_new_targetType" value=""PATH"" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
17
.run/Тест File.run.xml
Normal file
17
.run/Тест File.run.xml
Normal 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="""" />
|
||||
<option name="_new_target" value=""$PROJECT_DIR$/tests/classes/file_test.py"" />
|
||||
<option name="_new_targetType" value=""PATH"" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
@@ -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()
|
85
help/class_desc/classes/directory.md
Normal file
85
help/class_desc/classes/directory.md
Normal 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)
|
242
help/class_desc/classes/file.md
Normal file
242
help/class_desc/classes/file.md
Normal 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)
|
19
tests/classes/directory_test.py
Normal file
19
tests/classes/directory_test.py
Normal 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()
|
79
tests/classes/file_test.py
Normal file
79
tests/classes/file_test.py
Normal 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()
|
Reference in New Issue
Block a user