From cd1c536efea5e7fe09a3e56a150c73de6aa166ad Mon Sep 17 00:00:00 2001 From: Scott Lamb Date: Mon, 2 May 2016 08:38:52 -0700 Subject: [PATCH] Export the calendar days map. --- design/api.md | 46 +++++++++++++++++++++++++++++++++++++++++----- src/web.cc | 24 +++++++++++++++++++++--- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/design/api.md b/design/api.md index a50b513..03cbd95 100644 --- a/design/api.md +++ b/design/api.md @@ -66,12 +66,48 @@ Example response: ### `/cameras/` A GET returns information for the camera with the given URL. The information -returned is a superset of that returned by the camera list. +returned is a superset of that returned by the camera list. It also includes a +list of calendar days (in the server's time zone) with data in the server's +time zone. The `days` entry is a object mapping `YYYY-mm-dd` to a day object +with the following attributes: -TODO(slamb): this should likely return a list of calendar days with data in the -server's time zone, along with the associated `start\_time\_90k` and -`end\_time\_90k`. The server will calculate this on startup and maintain it -as recordings are updated. +* `total_duration_90k` is the total duration recorded during that day. + If a recording spans a day boundary, some portion of it is accounted to + each day. +* `start_time_90k` is the start of that calendar day in the server's time + zone. +* `end_time_90k` is the end of that calendar day in the server's time zone. + It is usually 24 hours after the start time. It might be 23 hours or 25 + hours during spring forward or fall back, respectively. + +A calendar day will be present in the `days` object iff there is a non-zero +total duration of recordings for that day. + +Example response: + +```json +{ + "days": { + "2016-05-01": { + "end_time_usec": 131595516000000, + "start_time_usec": 131587740000000, + "total_duration_90k": 52617609 + }, + "2016-05-02": { + "end_time_usec": 131603292000000, + "start_time_usec": 131595516000000, + "total_duration_90k": 20946022 + } + }, + "description":"", + "max_end_time_90k": 131598273666690, + "min_start_time_90k": 131590386129355, + "retain_bytes": 104857600, + "short_name": "driveway", + "total_duration_90k": 73563631, + "total_sample_file_bytes": 98901406, +} +``` ### `/camera//recordings` diff --git a/src/web.cc b/src/web.cc index 7eb1091..9544417 100644 --- a/src/web.cc +++ b/src/web.cc @@ -285,16 +285,34 @@ void WebInterface::HandleJsonCameraDetail(evhttp_request *req, static_cast(camera_row.total_duration_90k); camera["total_sample_file_bytes"] = static_cast(camera_row.total_sample_file_bytes); - if (camera_row.min_start_time_90k != -1) { + if (camera_row.min_start_time_90k != std::numeric_limits::max()) { camera["min_start_time_90k"] = static_cast(camera_row.min_start_time_90k); } - if (camera_row.max_end_time_90k != -1) { + if (camera_row.max_end_time_90k != std::numeric_limits::min()) { camera["max_end_time_90k"] = static_cast(camera_row.max_end_time_90k); } - // TODO(slamb): include list of calendar days with data. + Json::Value days(Json::objectValue); + std::string error_message; + for (const auto &day : camera_row.days) { + int64_t start_time_usec; + int64_t end_time_usec; + if (!GetDayBounds(day.first, &start_time_usec, &end_time_usec, + &error_message)) { + return evhttp_send_error( + req, HTTP_INTERNAL, + StrCat("internal error: ", EscapeHtml(error_message)).c_str()); + } + + Json::Value day_val(Json::objectValue); + day_val["start_time_usec"] = static_cast(start_time_usec); + day_val["end_time_usec"] = static_cast(end_time_usec); + day_val["total_duration_90k"] = static_cast(day.second); + days[day.first] = day_val; + } + camera["days"] = days; ReplyWithJson(req, camera); }