support /last with fields

This commit is contained in:
Jan-Piet Mens
2015-10-23 15:32:52 +02:00
parent 62590e8ab3
commit 90fdc8cf60
5 changed files with 56 additions and 12 deletions
+5 -1
View File
@@ -398,12 +398,16 @@ curl 'http://127.0.0.1:8083/api/0/monitor'
#### `last`
Returns a list of last users' positions. (Can be limited by _user_ and _device_.)
Returns a list of last users' positions. (Can be limited by _user_, _device_, and _fields_, a comma-separated list of fields which should be returned instead of the default of all fields.)
```
curl http://127.0.0.1:8083/api/0/last [-d user=jjolie [-d device=phone]]
```
```
curl 'http://127.0.0.1:8083/api/0/last?fields=tst,tid,addr,topic,isotst'
```
#### `list`
List users. If _user_ is specified, lists that user's devices. If both _user_ and _device_ are specified, lists that device's `.rec` files.
+17 -7
View File
@@ -38,6 +38,8 @@
#ifdef WITH_HTTP
#define MAXPARTS 40
/* A transparent 40x40 PNG image with a black border */
static unsigned char border40x40png[] = {
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00,
@@ -202,7 +204,7 @@ static void send_last(struct mg_connection *conn)
u = field(conn, "user");
d = field(conn, "device");
if ((user_array = last_users(u, d)) != NULL) {
if ((user_array = last_users(u, d, NULL)) != NULL) {
json_foreach(one, user_array) {
JsonNode *f;
@@ -282,7 +284,6 @@ static int xml_response(struct mg_connection *conn, JsonNode *obj)
* /users/ or /list
*/
#define MAXPARTS 40
#define CLEANUP do {\
int k; \
@@ -347,12 +348,21 @@ static int dispatch(struct mg_connection *conn, const char *uri)
#endif /* WITH_KILL */
if (nparts == 1 && !strcmp(uparts[0], "last")) {
JsonNode *user_array;
JsonNode *user_array, *fields = NULL;
char *flds = field(conn, "fields");
if ((user_array = last_users(u, d)) != NULL) {
if (flds != NULL) {
fields = json_splitter(flds, ",");
free(flds);
}
if ((user_array = last_users(u, d, fields)) != NULL) {
CLEANUP;
json_delete(fields);
return (json_response(conn, user_array));
}
}
json_delete(fields);
}
if ((ret = mg_get_var(conn, "limit", buf, sizeof(buf))) > 0) {
@@ -396,11 +406,11 @@ static int dispatch(struct mg_connection *conn, const char *uri)
/* /locations [<username>[<device>]] */
if (nparts == 1 && !strcmp(uparts[0], "locations")) {
/*
/*
* Obtain a list of .rec files from lister(), possibly limited
* by s_lo/s_hi times, process each and build the JSON `obj'
* with an array of locations.
*/
*/
obj = json_mkobject();
locs = json_mkarray();
+1 -1
View File
@@ -433,7 +433,7 @@ int main(int argc, char **argv)
if (last) {
JsonNode *user_array;
if ((user_array = last_users(username, device)) != NULL) {
if ((user_array = last_users(username, device, fields)) != NULL) {
if (otype == JSON) {
char *js;
+32 -2
View File
@@ -181,10 +181,11 @@ void append_device_details(JsonNode *userlist, char *user, char *device)
/*
* Return an array of users gleaned from LAST with merged details.
* If user and device are specified, limit to those; either may be
* NULL.
* NULL. If `fields' is not NULL, it's a JSON array of fields to
* be returned.
*/
JsonNode *last_users(char *in_user, char *in_device)
JsonNode *last_users(char *in_user, char *in_device, JsonNode *fields)
{
JsonNode *obj = json_mkobject();
JsonNode *un, *dn, *userlist = json_mkarray();
@@ -225,6 +226,35 @@ JsonNode *last_users(char *in_user, char *in_device)
}
json_delete(obj);
/*
* userlist now is an array of user objects. If fields were
* specified, re-create that array with object which have
* only the requested fields. It's a shame we have to re-do
* this here, but I can't think of an alternative way at
* the moment.
*/
if (fields) {
JsonNode *new_userlist = json_mkarray(), *user;
json_foreach(user, userlist) {
JsonNode *o = json_mkobject(), *f, *j;
json_foreach(f, fields) {
char *field_name = f->string_;
if ((j = json_find_member(user, field_name)) != NULL) {
json_copy_element_to_object(o, field_name, j);
}
}
json_append_element(new_userlist, o);
}
json_delete(userlist);
return (new_userlist);
}
return (userlist);
}
+1 -1
View File
@@ -43,7 +43,7 @@ int make_times(char *time_from, time_t *s_lo, char *time_to, time_t *s_to);
JsonNode *geo_json(JsonNode *json);
JsonNode *geo_linestring(JsonNode *location_array);
JsonNode *kill_datastore(char *username, char *device);
JsonNode *last_users(char *user, char *device);
JsonNode *last_users(char *user, char *device, JsonNode *fields);
char *gpx_string(JsonNode *json);
void storage_init(int revgeo);
void storage_gcache_dump(char *lmdbname);