v158
This commit is contained in:
@@ -32,16 +32,17 @@ def _parse_started_at(path: str) -> int:
|
||||
|
||||
|
||||
def _scan_segments(root: str) -> dict[str, list[str]]:
|
||||
"""Возвращает {camera_id: [пути mp4, отсортированы]}.
|
||||
"""Возвращает {имя_папки: [пути mp4, отсортированы]} (папка = номер слота или
|
||||
легаси-id камеры — сопоставление в камеру делает вызывающий).
|
||||
|
||||
Файлы лежат в подпапке даты <cam>/<YYYY-MM-DD>/*.mp4; старые «плоские»
|
||||
<cam>/*.mp4 тоже подхватываем (обратная совместимость). Сортировка по полному
|
||||
Файлы лежат в подпапке даты <folder>/<YYYY-MM-DD>/*.mp4; старые «плоские»
|
||||
<folder>/*.mp4 тоже подхватываем (обратная совместимость). Сортировка по полному
|
||||
пути == хронологическая (ISO-даты и в каталоге, и в имени)."""
|
||||
result: dict[str, list[str]] = {}
|
||||
if not os.path.isdir(root):
|
||||
return result
|
||||
for cam_id in os.listdir(root):
|
||||
cam_dir = os.path.join(root, cam_id)
|
||||
for folder in os.listdir(root):
|
||||
cam_dir = os.path.join(root, folder)
|
||||
if not os.path.isdir(cam_dir):
|
||||
continue
|
||||
files: list[str] = []
|
||||
@@ -58,7 +59,7 @@ def _scan_segments(root: str) -> dict[str, list[str]]:
|
||||
# из-за чего пишущийся сейчас файл в подпапке не оказывался бы последним)
|
||||
files.sort(key=os.path.basename)
|
||||
if files:
|
||||
result[cam_id] = files
|
||||
result[folder] = files
|
||||
return result
|
||||
|
||||
|
||||
@@ -102,9 +103,10 @@ class Indexer:
|
||||
store = self.config.storage_by_id(cam.storage_id) or self.config.active_storage()
|
||||
if store.type == "nas" and not os.path.ismount(store.path):
|
||||
continue
|
||||
sub = self.config.archive_dir(cam.id) # папка-слот, напр. «05»
|
||||
for d in days:
|
||||
try:
|
||||
os.makedirs(os.path.join(store.path, cam.id, d), exist_ok=True)
|
||||
os.makedirs(os.path.join(store.path, sub, d), exist_ok=True)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
@@ -115,12 +117,23 @@ class Indexer:
|
||||
|
||||
# сканируем ВСЕ хранилища: после смены активного старые записи не теряются
|
||||
for root in self.config.storage_paths():
|
||||
by_cam = _scan_segments(root)
|
||||
by_dir = _scan_segments(root)
|
||||
is_active = (root == active_path)
|
||||
for cam_id, files in by_cam.items():
|
||||
# в активном хранилище последний файл ещё пишется — пропускаем;
|
||||
# в неактивных все сегменты завершены, индексируем целиком.
|
||||
complete = files[:-1] if is_active else files
|
||||
for folder, files in by_dir.items():
|
||||
# Сопоставление папки с камерой по приоритету:
|
||||
# 1) точное совпадение с id камеры — легаси-папка по id (в т.ч. числовому),
|
||||
# иначе папка камеры с id «5» спуталась бы со слотом 5;
|
||||
# 2) папка-слот «NN» → камера в этом слоте (новая схема);
|
||||
# 3) иначе оставляем имя папки (осиротевший архив индексируется как раньше).
|
||||
cam = self.config.camera(folder) or self.config.camera_by_archive_dir(folder)
|
||||
cam_id = cam.id if cam else folder
|
||||
# последний файл ещё пишется только в активной папке-слоте ТЕКУЩЕЙ камеры;
|
||||
# легаси-папки и неактивное хранилище дописаны — индексируем целиком.
|
||||
being_written = (
|
||||
is_active and cam is not None
|
||||
and self.config.archive_dir(cam.id) == folder
|
||||
)
|
||||
complete = files[:-1] if being_written else files
|
||||
for path in complete:
|
||||
if path in known:
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user