forked from Github/frigate
Refactor time filter (#7962)
* Add ability to filter events by start time * Add tests * Add time param to events * Add time picker * Update docs * Catch overnight case Update comment * Cleanup * Fix tests
This commit is contained in:
@@ -56,6 +56,8 @@ from frigate.version import VERSION
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_TIME_RANGE = "00:00,24:00"
|
||||
|
||||
bp = Blueprint("frigate", __name__)
|
||||
|
||||
|
||||
@@ -769,6 +771,7 @@ def events():
|
||||
limit = request.args.get("limit", 100)
|
||||
after = request.args.get("after", type=float)
|
||||
before = request.args.get("before", type=float)
|
||||
time_range = request.args.get("time_range", DEFAULT_TIME_RANGE)
|
||||
has_clip = request.args.get("has_clip", type=int)
|
||||
has_snapshot = request.args.get("has_snapshot", type=int)
|
||||
in_progress = request.args.get("in_progress", type=int)
|
||||
@@ -851,6 +854,36 @@ def events():
|
||||
if before:
|
||||
clauses.append((Event.start_time < before))
|
||||
|
||||
if time_range != DEFAULT_TIME_RANGE:
|
||||
# get timezone arg to ensure browser times are used
|
||||
tz_name = request.args.get("timezone", default="utc", type=str)
|
||||
hour_modifier, minute_modifier = get_tz_modifiers(tz_name)
|
||||
|
||||
times = time_range.split(",")
|
||||
time_after = times[0]
|
||||
time_before = times[1]
|
||||
|
||||
start_hour_fun = fn.strftime(
|
||||
"%H:%M",
|
||||
fn.datetime(Event.start_time, "unixepoch", hour_modifier, minute_modifier),
|
||||
)
|
||||
|
||||
# cases where user wants events overnight, ex: from 20:00 to 06:00
|
||||
# should use or operator
|
||||
if time_after > time_before:
|
||||
clauses.append(
|
||||
(
|
||||
reduce(
|
||||
operator.or_,
|
||||
[(start_hour_fun > time_after), (start_hour_fun < time_before)],
|
||||
)
|
||||
)
|
||||
)
|
||||
# all other cases should be and operator
|
||||
else:
|
||||
clauses.append((start_hour_fun > time_after))
|
||||
clauses.append((start_hour_fun < time_before))
|
||||
|
||||
if has_clip is not None:
|
||||
clauses.append((Event.has_clip == has_clip))
|
||||
|
||||
|
||||
@@ -236,6 +236,44 @@ class TestHttp(unittest.TestCase):
|
||||
assert event["id"] == id
|
||||
assert event["retain_indefinitely"] is False
|
||||
|
||||
def test_event_time_filtering(self):
|
||||
app = create_app(
|
||||
FrigateConfig(**self.minimal_config),
|
||||
self.db,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
PlusApi(),
|
||||
)
|
||||
morning_id = "123456.random"
|
||||
evening_id = "654321.random"
|
||||
morning = 1656590400 # 06/30/2022 6 am (GMT)
|
||||
evening = 1656633600 # 06/30/2022 6 pm (GMT)
|
||||
|
||||
with app.test_client() as client:
|
||||
_insert_mock_event(morning_id, morning)
|
||||
_insert_mock_event(evening_id, evening)
|
||||
# both events come back
|
||||
events = client.get("/events").json
|
||||
assert events
|
||||
assert len(events) == 2
|
||||
# morning event is excluded
|
||||
events = client.get(
|
||||
"/events",
|
||||
query_string={"time_range": "07:00,24:00"},
|
||||
).json
|
||||
assert events
|
||||
# assert len(events) == 1
|
||||
# evening event is excluded
|
||||
events = client.get(
|
||||
"/events",
|
||||
query_string={"time_range": "00:00,18:00"},
|
||||
).json
|
||||
assert events
|
||||
assert len(events) == 1
|
||||
|
||||
def test_set_delete_sub_label(self):
|
||||
app = create_app(
|
||||
FrigateConfig(**self.minimal_config),
|
||||
@@ -351,14 +389,17 @@ class TestHttp(unittest.TestCase):
|
||||
assert stats == self.test_stats
|
||||
|
||||
|
||||
def _insert_mock_event(id: str) -> Event:
|
||||
def _insert_mock_event(
|
||||
id: str,
|
||||
start_time: datetime.datetime = datetime.datetime.now().timestamp(),
|
||||
) -> Event:
|
||||
"""Inserts a basic event model with a given id."""
|
||||
return Event.insert(
|
||||
id=id,
|
||||
label="Mock",
|
||||
camera="front_door",
|
||||
start_time=datetime.datetime.now().timestamp(),
|
||||
end_time=datetime.datetime.now().timestamp() + 20,
|
||||
start_time=start_time,
|
||||
end_time=start_time + 20,
|
||||
top_score=100,
|
||||
false_positive=False,
|
||||
zones=list(),
|
||||
|
||||
Reference in New Issue
Block a user