include ext stream in API response; better docs

In particular, the docs now explicitly call out that API changes can
happen at any version, and from 0.7.0 onward they're described in
the changelog.
This commit is contained in:
Scott Lamb 2021-11-23 13:01:20 -08:00
parent 6738de0cb7
commit 5c7263b1bd
3 changed files with 55 additions and 15 deletions

View File

@ -10,6 +10,8 @@ Each release is tagged in Git and on the Docker repository
* fix [#182](https://github.com/scottlamb/moonfire-nvr/issues/182): error * fix [#182](https://github.com/scottlamb/moonfire-nvr/issues/182): error
on upgrade from schema 6 to schema 7 when a camera's `onvif_host` is empty. on upgrade from schema 6 to schema 7 when a camera's `onvif_host` is empty.
* API bugfix: in the `GET /api/` response, include `ext` streams if
configured.
## `v0.7.1` (2021-10-27) ## `v0.7.1` (2021-10-27)
@ -20,6 +22,29 @@ Each release is tagged in Git and on the Docker repository
## `v0.7.0` (2021-10-27) ## `v0.7.0` (2021-10-27)
* [schema version 7](guide/schema.md#version-7) * [schema version 7](guide/schema.md#version-7)
* Changes to the [API](guide/api.md):
* Added fields to the `GET /api/` response:
* `serverVersion`
* Altered fields in the `GET /api/` response:
* `session` was moved into a new `user` object, to support providing
information about the user when authenticating via Unix uid rather
than session cookie (a planned feature). `session.username` is now
`user.name`; `session.csrf` is now `user.session.csrf`. `user.id`
and `user.preferences` have been added.
* `signals.source` is now `signals.uuid`. The UUID is now expected to
be unique, where before only (source, type) was guaranteed to be
unique.
* `camera.config` has been altered and extended. `onvifHost` has
become `onvifBaseUrl` to allow selecting between `http` and `https`.
* `camera.description` was moved to `camera.config.description`.
(This might have been an oversight; now it's only possible to see
the description with the `read_camera_configs` permission. This
field can be re-introduced if desired.)
* `stream.config` has been altered and extended. `rtspUrl` has become
`url` to (in the future) represent a URL for other streaming
protocols. The `record` boolean was replaced with `mode`, which
currently may be either absent or the string `record`.
* Added `POST /api/users/<id>` for altering a user's UI preferences.
## `v0.6.7` (2021-10-20) ## `v0.6.7` (2021-10-20)

View File

@ -38,6 +38,15 @@ In the future, this is likely to be expanded:
*Note:* italicized terms in this document are defined in the [glossary](glossary.md). *Note:* italicized terms in this document are defined in the [glossary](glossary.md).
Currently the API is considered an internal contract between the server and the
UI which are bundled together. Thus, breaking changes in the API may happen in
any release of Moonfire NVR, even a "minor" or "patch" release. From version
0.7.0 onward, API changes should be described in the
[changelog](../CHANGELOG.md).
Future work may introduce versioning to improve compatibility with externally
developed tools.
All requests for JSON data should be sent with the header All requests for JSON data should be sent with the header
`Accept: application/json` (exactly). `Accept: application/json` (exactly).
@ -94,19 +103,20 @@ The `application/json` response will have a JSON object as follows:
by reading logs or directly examining the filesystem/database. by reading logs or directly examining the filesystem/database.
* `shortName`: a short name (typically one or two words) * `shortName`: a short name (typically one or two words)
* `description`: a longer description (typically a phrase or paragraph) * `description`: a longer description (typically a phrase or paragraph)
* `config`: (only included if request parameter `cameraConfigs` is true) * `config`: (only included if request parameter `cameraConfigs` is
a JSON object describing the configuration of the camera: true) a JSON object describing the configuration of the camera.
* `username` See doc comments on the `CameraConfig` type in
* `password` [`server/db/json.rs`](../server/db.json.rs).
* `onvif_host` * `streams`: a JSON object. Maps each configured stream type (valid types
* `streams`: a JSON object of stream type ("main" or "sub") to a JSON are `main`, `sub`, and `ext`), a JSON object describing the stream:
object describing the stream:
* `id`: an integer. The client doesn't ever need to send the id * `id`: an integer. The client doesn't ever need to send the id
back in API requests, but stream ids are helpful to know when back in API requests, but stream ids are helpful to know when
debugging by reading logs or directly examining the debugging by reading logs or directly examining the
filesystem/database. filesystem/database.
* `retainBytes`: the configured total number of bytes of completed * `retainBytes`: the configured total number of bytes of completed
recordings to retain. recordings to retain. This is copied from the `config` to make it
available when the client doesn't have permission to view
the full configuration.
* `minStartTime90k`: the start time of the earliest recording for * `minStartTime90k`: the start time of the earliest recording for
this camera, in 90kHz units since 1970-01-01 00:00:00 UTC. this camera, in 90kHz units since 1970-01-01 00:00:00 UTC.
* `maxEndTime90k`: the end time of the latest recording for this * `maxEndTime90k`: the end time of the latest recording for this
@ -138,8 +148,9 @@ The `application/json` response will have a JSON object as follows:
might be 23 hours or 25 hours during spring forward or fall might be 23 hours or 25 hours during spring forward or fall
back, respectively. back, respectively.
* `config`: (only included if request parameter `cameraConfigs` is * `config`: (only included if request parameter `cameraConfigs` is
true) a JSON object describing the configuration of the stream: true) a JSON object describing the configuration of the stream.
* `rtsp_url` See doc comments on the `StreamConfig` type in
[`server/db/json.rs`](../server/db.json.rs).
* `signals`: a list of all *signals* known to the server. Each is a JSON * `signals`: a list of all *signals* known to the server. Each is a JSON
object with the following properties: object with the following properties:
* `id`: an integer identifier. * `id`: an integer identifier.
@ -165,7 +176,7 @@ The `application/json` response will have a JSON object as follows:
considered to have motion when this signal is in this state. considered to have motion when this signal is in this state.
* `color` (optional): a recommended color to use in UIs to represent * `color` (optional): a recommended color to use in UIs to represent
this state, as in the [HTML specification](https://html.spec.whatwg.org/#colours). this state, as in the [HTML specification](https://html.spec.whatwg.org/#colours).
* `user`: if authenticated, a JSON object: * `user`: an object, present only when authenticated:
* `name`: a human-readable name * `name`: a human-readable name
* `id`: an integer * `id`: an integer
* `preferences`: a JSON object * `preferences`: a JSON object
@ -808,7 +819,7 @@ Response:
} }
``` ```
## `POST /api/users/<id>` ### `POST /api/users/<id>`
Currently this request only allows updating the preferences for the Currently this request only allows updating the preferences for the
currently-authenticated user. This is likely to change. currently-authenticated user. This is likely to change.

View File

@ -63,7 +63,7 @@ pub struct Camera<'a> {
pub config: Option<&'a db::json::CameraConfig>, pub config: Option<&'a db::json::CameraConfig>,
#[serde(serialize_with = "Camera::serialize_streams")] #[serde(serialize_with = "Camera::serialize_streams")]
pub streams: [Option<Stream<'a>>; 2], pub streams: [Option<Stream<'a>>; db::db::NUM_STREAM_TYPES],
} }
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
@ -182,11 +182,15 @@ impl<'a> Camera<'a> {
streams: [ streams: [
Stream::wrap(db, c.streams[0], include_days, include_config)?, Stream::wrap(db, c.streams[0], include_days, include_config)?,
Stream::wrap(db, c.streams[1], include_days, include_config)?, Stream::wrap(db, c.streams[1], include_days, include_config)?,
Stream::wrap(db, c.streams[2], include_days, include_config)?,
], ],
}) })
} }
fn serialize_streams<S>(streams: &[Option<Stream>; 2], serializer: S) -> Result<S::Ok, S::Error> fn serialize_streams<S>(
streams: &[Option<Stream>; db::db::NUM_STREAM_TYPES],
serializer: S,
) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
{ {