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

This commit is contained in:
ack
2026-04-19 22:54:01 +03:00
parent 34440ebf73
commit 035cbac430
8 changed files with 165 additions and 6 deletions

View File

@@ -33,7 +33,37 @@ def _is_day_time(snapshot_time: time, day_start: time, day_end: time) -> bool:
return day_start <= snapshot_time <= day_end
def _select_frames(job: TimelapseJob, camera_root: Path) -> list[Path]:
def _time_to_minutes(t: time) -> int:
return t.hour * 60 + t.minute
def _pick_nearest_frame_for_day(job: TimelapseJob, day_files: list[Path]) -> Path | None:
candidates: list[tuple[int, Path]] = []
anchor_minutes = _time_to_minutes(job.anchor_time)
for img_path in day_files:
if img_path.name.lower() == 'lastsnap.jpg':
continue
try:
snap_time = datetime.strptime(img_path.stem, '%H-%M-%S').time()
except ValueError:
continue
if not job.include_night and not _is_day_time(snap_time, job.day_start_time, job.day_end_time):
continue
diff = abs(_time_to_minutes(snap_time) - anchor_minutes)
candidates.append((diff, img_path))
if not candidates:
return None
candidates.sort(key=lambda x: (x[0], x[1].name))
return candidates[0][1]
def _select_frames(job: TimelapseJob, camera_root: Path) -> tuple[list[Path], int, int]:
logger.info('worker:select_frames:start job_id=%s', job.id)
selected: list[Path] = []
interval_seconds = int(job.sampling_interval_minutes) * 60
@@ -161,14 +191,23 @@ def process_job(job: TimelapseJob) -> bool:
shutil.rmtree(temp_dir, ignore_errors=True)
camera_root = _safe_camera_root(job)
frame_paths = _select_frames(job, camera_root)
frame_paths, days_total, days_with_frames = _select_frames(job, camera_root)
days_skipped = max(0, days_total - days_with_frames)
if not frame_paths:
TimelapseJob.objects.filter(pk=job.pk).update(
days_total=days_total,
days_with_frames=days_with_frames,
days_skipped=days_skipped,
)
raise RuntimeError('Не найдено кадров под выбранные параметры.')
TimelapseJob.objects.filter(pk=job.pk).update(
frames_total=len(frame_paths),
frames_processed=0,
days_total=days_total,
days_with_frames=days_with_frames,
days_skipped=days_skipped,
progress_percent=5,
)
@@ -232,6 +271,9 @@ def run_specific_job(job_id: int) -> bool:
progress_percent=1,
frames_processed=0,
frames_total=None,
days_total=0,
days_with_frames=0,
days_skipped=0,
error_message='',
)