mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-01-14 08:15:01 -05:00
separate out signals API to own file
This commit is contained in:
parent
1f41a27cc3
commit
1e17a53280
@ -5,6 +5,7 @@
|
|||||||
mod live;
|
mod live;
|
||||||
mod path;
|
mod path;
|
||||||
mod session;
|
mod session;
|
||||||
|
mod signals;
|
||||||
mod static_file;
|
mod static_file;
|
||||||
mod view;
|
mod view;
|
||||||
|
|
||||||
@ -224,18 +225,6 @@ impl Service {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn signals(&self, req: Request<hyper::Body>, caller: Caller) -> ResponseResult {
|
|
||||||
match *req.method() {
|
|
||||||
Method::POST => self.post_signals(req, caller).await,
|
|
||||||
Method::GET | Method::HEAD => self.get_signals(&req),
|
|
||||||
_ => Err(plain_response(
|
|
||||||
StatusCode::METHOD_NOT_ALLOWED,
|
|
||||||
"POST, GET, or HEAD expected",
|
|
||||||
)
|
|
||||||
.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serves an HTTP request.
|
/// Serves an HTTP request.
|
||||||
/// Note that the `serve` wrapper handles responses the same whether they
|
/// Note that the `serve` wrapper handles responses the same whether they
|
||||||
/// are `Ok` or `Err`. But returning `Err` here with the `?` operator is
|
/// are `Ok` or `Err`. But returning `Err` here with the `?` operator is
|
||||||
@ -564,58 +553,6 @@ impl Service {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn post_signals(&self, mut req: Request<hyper::Body>, caller: Caller) -> ResponseResult {
|
|
||||||
if !caller.permissions.update_signals {
|
|
||||||
bail_t!(PermissionDenied, "update_signals required");
|
|
||||||
}
|
|
||||||
let r = extract_json_body(&mut req).await?;
|
|
||||||
let r: json::PostSignalsRequest =
|
|
||||||
serde_json::from_slice(&r).map_err(|e| bad_req(e.to_string()))?;
|
|
||||||
let now = recording::Time::new(self.db.clocks().realtime());
|
|
||||||
let mut l = self.db.lock();
|
|
||||||
let start = match r.start {
|
|
||||||
json::PostSignalsTimeBase::Epoch(t) => t,
|
|
||||||
json::PostSignalsTimeBase::Now(d) => now + d,
|
|
||||||
};
|
|
||||||
let end = match r.end {
|
|
||||||
json::PostSignalsTimeBase::Epoch(t) => t,
|
|
||||||
json::PostSignalsTimeBase::Now(d) => now + d,
|
|
||||||
};
|
|
||||||
l.update_signals(start..end, &r.signal_ids, &r.states)
|
|
||||||
.map_err(from_base_error)?;
|
|
||||||
serve_json(&req, &json::PostSignalsResponse { time_90k: now })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_signals(&self, req: &Request<hyper::Body>) -> ResponseResult {
|
|
||||||
let mut time = recording::Time::min_value()..recording::Time::max_value();
|
|
||||||
if let Some(q) = req.uri().query() {
|
|
||||||
for (key, value) in form_urlencoded::parse(q.as_bytes()) {
|
|
||||||
let (key, value) = (key.borrow(), value.borrow());
|
|
||||||
match key {
|
|
||||||
"startTime90k" => {
|
|
||||||
time.start = recording::Time::parse(value)
|
|
||||||
.map_err(|_| bad_req("unparseable startTime90k"))?
|
|
||||||
}
|
|
||||||
"endTime90k" => {
|
|
||||||
time.end = recording::Time::parse(value)
|
|
||||||
.map_err(|_| bad_req("unparseable endTime90k"))?
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut signals = json::Signals::default();
|
|
||||||
self.db
|
|
||||||
.lock()
|
|
||||||
.list_changes_by_time(time, &mut |c: &db::signal::ListStateChangesRow| {
|
|
||||||
signals.times_90k.push(c.when);
|
|
||||||
signals.signal_ids.push(c.signal);
|
|
||||||
signals.states.push(c.state);
|
|
||||||
});
|
|
||||||
serve_json(req, &signals)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Authenticates the session (if any) and returns a Caller.
|
/// Authenticates the session (if any) and returns a Caller.
|
||||||
///
|
///
|
||||||
/// If there's no session,
|
/// If there's no session,
|
||||||
|
89
server/src/web/signals.rs
Normal file
89
server/src/web/signals.rs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// This file is part of Moonfire NVR, a security camera network video recorder.
|
||||||
|
// Copyright (C) 2021 The Moonfire NVR Authors; see AUTHORS and LICENSE.txt.
|
||||||
|
// SPDX-License-Identifier: GPL-v3.0-or-later WITH GPL-3.0-linking-exception.
|
||||||
|
|
||||||
|
//! `/api/signals` handling.
|
||||||
|
|
||||||
|
use base::{bail_t, clock::Clocks};
|
||||||
|
use db::recording;
|
||||||
|
use http::{Method, Request, StatusCode};
|
||||||
|
use url::form_urlencoded;
|
||||||
|
|
||||||
|
use crate::json;
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
bad_req, extract_json_body, from_base_error, plain_response, serve_json, Caller,
|
||||||
|
ResponseResult, Service,
|
||||||
|
};
|
||||||
|
|
||||||
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
|
impl Service {
|
||||||
|
pub(super) async fn signals(
|
||||||
|
&self,
|
||||||
|
req: Request<hyper::Body>,
|
||||||
|
caller: Caller,
|
||||||
|
) -> ResponseResult {
|
||||||
|
match *req.method() {
|
||||||
|
Method::POST => self.post_signals(req, caller).await,
|
||||||
|
Method::GET | Method::HEAD => self.get_signals(&req),
|
||||||
|
_ => Err(plain_response(
|
||||||
|
StatusCode::METHOD_NOT_ALLOWED,
|
||||||
|
"POST, GET, or HEAD expected",
|
||||||
|
)
|
||||||
|
.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn post_signals(&self, mut req: Request<hyper::Body>, caller: Caller) -> ResponseResult {
|
||||||
|
if !caller.permissions.update_signals {
|
||||||
|
bail_t!(PermissionDenied, "update_signals required");
|
||||||
|
}
|
||||||
|
let r = extract_json_body(&mut req).await?;
|
||||||
|
let r: json::PostSignalsRequest =
|
||||||
|
serde_json::from_slice(&r).map_err(|e| bad_req(e.to_string()))?;
|
||||||
|
let now = recording::Time::new(self.db.clocks().realtime());
|
||||||
|
let mut l = self.db.lock();
|
||||||
|
let start = match r.start {
|
||||||
|
json::PostSignalsTimeBase::Epoch(t) => t,
|
||||||
|
json::PostSignalsTimeBase::Now(d) => now + d,
|
||||||
|
};
|
||||||
|
let end = match r.end {
|
||||||
|
json::PostSignalsTimeBase::Epoch(t) => t,
|
||||||
|
json::PostSignalsTimeBase::Now(d) => now + d,
|
||||||
|
};
|
||||||
|
l.update_signals(start..end, &r.signal_ids, &r.states)
|
||||||
|
.map_err(from_base_error)?;
|
||||||
|
serve_json(&req, &json::PostSignalsResponse { time_90k: now })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_signals(&self, req: &Request<hyper::Body>) -> ResponseResult {
|
||||||
|
let mut time = recording::Time::min_value()..recording::Time::max_value();
|
||||||
|
if let Some(q) = req.uri().query() {
|
||||||
|
for (key, value) in form_urlencoded::parse(q.as_bytes()) {
|
||||||
|
let (key, value) = (key.borrow(), value.borrow());
|
||||||
|
match key {
|
||||||
|
"startTime90k" => {
|
||||||
|
time.start = recording::Time::parse(value)
|
||||||
|
.map_err(|_| bad_req("unparseable startTime90k"))?
|
||||||
|
}
|
||||||
|
"endTime90k" => {
|
||||||
|
time.end = recording::Time::parse(value)
|
||||||
|
.map_err(|_| bad_req("unparseable endTime90k"))?
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut signals = json::Signals::default();
|
||||||
|
self.db
|
||||||
|
.lock()
|
||||||
|
.list_changes_by_time(time, &mut |c: &db::signal::ListStateChangesRow| {
|
||||||
|
signals.times_90k.push(c.when);
|
||||||
|
signals.signal_ids.push(c.signal);
|
||||||
|
signals.states.push(c.state);
|
||||||
|
});
|
||||||
|
serve_json(req, &signals)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user