добавил удаление таймлапсов
All checks were successful
Deploy timelaps / deploy (push) Successful in 5s

This commit is contained in:
ack
2026-04-19 23:21:07 +03:00
parent 587cb0bcb4
commit ae15bee2d1
9 changed files with 180 additions and 6 deletions

View File

@@ -1,3 +1,5 @@
"""Сервисы для работы с камерами и storage: превью, автообнаружение, утилиты."""
import logging
from pathlib import Path
@@ -11,6 +13,7 @@ logger = logging.getLogger('camlaps')
def _storage_root() -> Path:
"""Возвращает корень storage, в который смонтированы фото камер."""
storage_path = getattr(settings, 'STORAGE_PATH', None)
if storage_path is None:
return Path('/app/storage')
@@ -18,6 +21,7 @@ def _storage_root() -> Path:
def generate_unique_camera_slug(directory_name: str, storage_path: str) -> str:
"""Генерирует уникальный slug камеры для новых записей, избегая конфликтов."""
base_slug = (slugify(directory_name) or f'camera-{directory_name.lower()}')[:70]
slug = base_slug
suffix = 1
@@ -31,6 +35,7 @@ def generate_unique_camera_slug(directory_name: str, storage_path: str) -> str:
def is_storage_available() -> bool:
"""Проверяет, что storage примонтирован и доступен как директория."""
logger.info('cameras:storage_available:start')
try:
root = _storage_root()
@@ -43,6 +48,7 @@ def is_storage_available() -> bool:
def list_active_cameras() -> list[Camera]:
"""Возвращает список активных камер для отображения в UI."""
logger.info('cameras:list_active:start')
try:
cameras = list(Camera.objects.filter(is_active=True).order_by('name'))
@@ -54,6 +60,7 @@ def list_active_cameras() -> list[Camera]:
def get_camera_lastsnap_path(camera: Camera) -> Path | None:
"""Возвращает путь к lastsnap.jpg для камеры или None, если файла нет/путь небезопасен."""
logger.info('cameras:lastsnap_path:start camera_id=%s', camera.id)
try:
root = _storage_root().resolve()
@@ -75,6 +82,7 @@ def get_camera_lastsnap_path(camera: Camera) -> Path | None:
def discover_camera_candidates() -> list[dict[str, str]]:
"""Сканирует подпапки storage и возвращает кандидатов камер без записи в БД."""
logger.info('cameras:discover_candidates:start')
try:
root = _storage_root()
@@ -100,6 +108,7 @@ def discover_camera_candidates() -> list[dict[str, str]]:
def create_cameras_from_candidates(selected_storage_paths: list[str]) -> int:
"""Создает записи Camera в БД только для выбранных storage_path, возвращает количество созданных."""
logger.info('cameras:create_from_candidates:start count=%s', len(selected_storage_paths))
try:
created = 0