Release: v3.1.0
This commit is contained in:
+39
-18
@@ -54,6 +54,23 @@ def _in_time_window(now_time: str, start: str, stop: str) -> bool:
|
||||
return now_min >= start_min or now_min < stop_min
|
||||
|
||||
|
||||
def _apply_buffers(job: dict) -> dict:
|
||||
eff = dict(job)
|
||||
pre = job.get("pre_buffer", 0) or 0
|
||||
post = job.get("post_buffer", 0) or 0
|
||||
if pre > 0 and eff.get("schedule_start"):
|
||||
m = _time_to_minutes(eff["schedule_start"]) - pre
|
||||
if m < 0:
|
||||
m += 1440
|
||||
eff["schedule_start"] = f"{m // 60:02d}:{m % 60:02d}"
|
||||
if post > 0 and eff.get("schedule_stop"):
|
||||
m = _time_to_minutes(eff["schedule_stop"]) + post
|
||||
if m >= 1440:
|
||||
m -= 1440
|
||||
eff["schedule_stop"] = f"{m // 60:02d}:{m % 60:02d}"
|
||||
return eff
|
||||
|
||||
|
||||
class StreamScheduler:
|
||||
def __init__(self, recorder):
|
||||
self.recorder = recorder
|
||||
@@ -76,6 +93,12 @@ class StreamScheduler:
|
||||
today = job.schedule_date or today
|
||||
return f"{job.id}|{job.schedule_once}|{today}|{job.schedule_start}"
|
||||
|
||||
def _original_occ_key(self, job: dict, now: datetime.datetime | None = None) -> str:
|
||||
now = now or datetime.datetime.now()
|
||||
today_date = now.strftime("%Y-%m-%d")
|
||||
date = today_date if not job["schedule_once"] else job["schedule_date"]
|
||||
return f"{job['id']}|{job['schedule_once']}|{date}|{job['schedule_start']}"
|
||||
|
||||
def _schedule_state(self, job: dict, now: datetime.datetime | None = None) -> dict:
|
||||
now = now or datetime.datetime.now()
|
||||
today_num = now.isoweekday()
|
||||
@@ -140,15 +163,19 @@ class StreamScheduler:
|
||||
"schedule_start": j.schedule_start,
|
||||
"schedule_stop": j.schedule_stop,
|
||||
"schedule_end_date": j.schedule_end_date,
|
||||
"pre_buffer": j.pre_buffer or 0,
|
||||
"post_buffer": j.post_buffer or 0,
|
||||
}
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
state = self._schedule_state(job)
|
||||
occ_key = self._original_occ_key(job)
|
||||
eff_job = _apply_buffers(job)
|
||||
state = self._schedule_state(eff_job)
|
||||
if not state["in_window"]:
|
||||
return False
|
||||
|
||||
self._started_keys.add(state["occ_key"])
|
||||
self._started_keys.add(occ_key)
|
||||
return True
|
||||
|
||||
def _occurrence_start_utc(self, job: dict, now: datetime.datetime) -> datetime.datetime | None:
|
||||
@@ -219,11 +246,8 @@ class StreamScheduler:
|
||||
"schedule_once": j.schedule_once, "schedule_date": j.schedule_date,
|
||||
"schedule_days": j.schedule_days, "schedule_start": j.schedule_start,
|
||||
"schedule_stop": j.schedule_stop, "schedule_end_date": j.schedule_end_date,
|
||||
"pre_buffer": j.pre_buffer or 0, "post_buffer": j.post_buffer or 0,
|
||||
"description": j.description,
|
||||
"metadata_monitor_enabled": j.metadata_monitor_enabled,
|
||||
"metadata_pattern": j.metadata_pattern,
|
||||
"metadata_grace_period": j.metadata_grace_period,
|
||||
"metadata_poll_interval": j.metadata_poll_interval,
|
||||
"ntfy_enabled": j.ntfy_enabled,
|
||||
"plik_enabled": j.plik_enabled,
|
||||
"delete_after_upload": j.delete_after_upload,
|
||||
@@ -235,9 +259,10 @@ class StreamScheduler:
|
||||
if not job["schedule_start"]:
|
||||
continue
|
||||
|
||||
state = self._schedule_state(job, now)
|
||||
occ_key = self._original_occ_key(job, now)
|
||||
eff_job = _apply_buffers(job)
|
||||
state = self._schedule_state(eff_job, now)
|
||||
in_window = state["in_window"]
|
||||
occ_key = state["occ_key"]
|
||||
|
||||
if in_window:
|
||||
if (
|
||||
@@ -246,16 +271,16 @@ class StreamScheduler:
|
||||
and not self._has_recording_for_occurrence(job, now)
|
||||
):
|
||||
duration = job["max_duration"]
|
||||
if not duration and job["schedule_stop"]:
|
||||
if not duration and eff_job["schedule_stop"]:
|
||||
if state["multi_day"]:
|
||||
start_dt = datetime.datetime.strptime(
|
||||
f"{job['schedule_date']} {job['schedule_start']}", "%Y-%m-%d %H:%M")
|
||||
f"{job['schedule_date']} {eff_job['schedule_start']}", "%Y-%m-%d %H:%M")
|
||||
end_dt = datetime.datetime.strptime(
|
||||
f"{job['schedule_end_date']} {job['schedule_stop']}", "%Y-%m-%d %H:%M")
|
||||
f"{job['schedule_end_date']} {eff_job['schedule_stop']}", "%Y-%m-%d %H:%M")
|
||||
duration = max(0, int((end_dt - start_dt).total_seconds()))
|
||||
else:
|
||||
start_min = _time_to_minutes(job["schedule_start"])
|
||||
stop_min = _time_to_minutes(job["schedule_stop"])
|
||||
start_min = _time_to_minutes(eff_job["schedule_start"])
|
||||
stop_min = _time_to_minutes(eff_job["schedule_stop"])
|
||||
if stop_min > start_min:
|
||||
duration = (stop_min - start_min) * 60
|
||||
else:
|
||||
@@ -272,10 +297,6 @@ class StreamScheduler:
|
||||
segment_duration=job["segment_duration"],
|
||||
is_scheduled=True,
|
||||
description=job.get("description", ""),
|
||||
metadata_monitor_enabled=job.get("metadata_monitor_enabled", False),
|
||||
metadata_pattern=job.get("metadata_pattern", ""),
|
||||
metadata_grace_period=job.get("metadata_grace_period") or 300,
|
||||
metadata_poll_interval=job.get("metadata_poll_interval") or 30,
|
||||
ntfy_enabled=job.get("ntfy_enabled", False),
|
||||
plik_enabled=job.get("plik_enabled", False),
|
||||
delete_after_upload=job.get("delete_after_upload", False),
|
||||
@@ -285,7 +306,7 @@ class StreamScheduler:
|
||||
if (
|
||||
not state["multi_day"]
|
||||
and not state["is_cross_midnight"]
|
||||
and job["schedule_stop"]
|
||||
and eff_job["schedule_stop"]
|
||||
and self._is_job_recording(job["id"])
|
||||
):
|
||||
rec_id = self._get_active_scheduled_recording_for_job(job["id"])
|
||||
|
||||
Reference in New Issue
Block a user