Files
timelaps/camlaps/services/cameras.py
ack a3df30184e
All checks were successful
Deploy timelaps / deploy (push) Successful in 5s
заработал интерфейс
2026-04-19 19:19:03 +03:00

60 lines
1.8 KiB
Python

import logging
from pathlib import Path
from django.conf import settings
from ..models import Camera
logger = logging.getLogger('camlaps')
def _storage_root() -> Path:
storage_path = getattr(settings, 'STORAGE_PATH', None)
if storage_path is None:
return Path('/app/storage')
return Path(storage_path)
def is_storage_available() -> bool:
logger.info('cameras:storage_available:start')
try:
root = _storage_root()
ok = root.exists() and root.is_dir()
logger.info('cameras:storage_available:done ok=%s', ok)
return ok
except Exception:
logger.exception('cameras:storage_available:error')
raise
def list_active_cameras() -> list[Camera]:
logger.info('cameras:list_active:start')
try:
cameras = list(Camera.objects.filter(is_active=True).order_by('name'))
logger.info('cameras:list_active:done count=%s', len(cameras))
return cameras
except Exception:
logger.exception('cameras:list_active:error')
raise
def get_camera_lastsnap_path(camera: Camera) -> Path | None:
logger.info('cameras:lastsnap_path:start camera_id=%s', camera.id)
try:
root = _storage_root().resolve()
candidate = (root / camera.storage_path / 'lastsnap.jpg').resolve()
if candidate != root and root not in candidate.parents:
logger.info('cameras:lastsnap_path:done camera_id=%s found=false', camera.id)
return None
if not candidate.exists() or not candidate.is_file():
logger.info('cameras:lastsnap_path:done camera_id=%s found=false', camera.id)
return None
logger.info('cameras:lastsnap_path:done camera_id=%s found=true', camera.id)
return candidate
except Exception:
logger.exception('cameras:lastsnap_path:error camera_id=%s', camera.id)
raise