Feature: ocat userlist (incomplete!)

This commit is contained in:
Jan-Piet Mens
2015-08-25 18:01:50 +02:00
parent 8e38c64fbf
commit b2f84eb55c
3 changed files with 125 additions and 2 deletions
+20 -2
View File
@@ -121,6 +121,7 @@ void usage(char *prog)
printf(" geojson\n");
printf(" raw\n");
printf(" tabular\n");
printf(" --last -L JSON object with last users\n");
printf(" --killdata requires -u and -d\n");
exit(1);
@@ -130,7 +131,7 @@ int main(int argc, char **argv)
{
char *progname = *argv, *p;
int c;
int list = 0, killdata = 0;
int list = 0, killdata = 0, last = 0;
char *username = NULL, *device = NULL, *time_from = NULL, *time_to = NULL;
JsonNode *json, *obj, *locs;
time_t now, s_lo, s_hi;
@@ -164,12 +165,13 @@ int main(int argc, char **argv)
{ "from", required_argument, 0, 'F'},
{ "to", required_argument, 0, 'T'},
{ "format", required_argument, 0, 'f'},
{ "last", no_argument, 0, 'L'},
{ "killdata", no_argument, 0, 'K'},
{0, 0, 0, 0}
};
int optindex = 0;
c = getopt_long(argc, argv, "hlu:d:F:T:f:K", long_options, &optindex);
c = getopt_long(argc, argv, "hlu:d:F:T:f:KL", long_options, &optindex);
if (c == -1)
break;
@@ -208,6 +210,9 @@ int main(int argc, char **argv)
case 'K':
killdata = 1;
break;
case 'L':
last = 1;
break;
case 'h':
case '?':
/* getopt_long already printed message */
@@ -247,6 +252,19 @@ int main(int argc, char **argv)
return (0);
}
if (last) {
JsonNode *obj;
char *js;
obj = last_users();
js = json_stringify(obj, " ");
printf("%s\n", js);
free(js);
json_delete(obj);
return (0);
}
if (!username && device) {
fprintf(stderr, "%s: device name without username doesn't make sense\n", progname);
return (-2);
+104
View File
@@ -8,6 +8,7 @@
#include <fnmatch.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/stat.h>
#include "utstring.h"
#include "config.h"
#include "storage.h"
@@ -36,6 +37,109 @@ void get_geo(JsonNode *o, char *ghash)
}
}
/*
* Populate a JSON object (`node') keyed by directory name; each element points
* to a JSON array with a list of subdirectories on the first level.
*
* { "jpm": [ "5s", "nex4" ], "jjolie": [ "iphone5" ] }
*
* Returns 1 on failure.
*/
static int user_device_list(char *name, int level, JsonNode *obj)
{
DIR *dirp;
struct dirent *dp;
char path[BUFSIZ];
JsonNode *devlist;
int rc = 0;
struct stat sb;
if ((dirp = opendir(name)) == NULL) {
perror(name);
return (1);
}
while ((dp = readdir(dirp)) != NULL) {
if (*dp->d_name != '.') {
sprintf(path, "%s/%s", name, dp->d_name);
if (stat(path, &sb) != 0) {
continue;
}
if (!S_ISDIR(sb.st_mode))
continue;
if (level == 0) {
devlist = json_mkarray();
json_append_member(obj, dp->d_name, devlist);
rc = user_device_list(path, level + 1, devlist);
} else if (level == 1) {
json_append_element(obj, json_mkstring(dp->d_name));
}
}
}
closedir(dirp);
return (rc);
}
void append_device_details(JsonNode *userlist, char *user, char *device)
{
char path[BUFSIZ];
JsonNode *last, *card;
snprintf(path, BUFSIZ, "%s/last/%s/%s/%s-%s.json",
STORAGEDIR, user, device, user, device);
last = json_mkobject();
if (json_copy_from_file(last, path) == TRUE) {
json_append_element(userlist, last);
} else {
json_delete(last);
}
snprintf(path, BUFSIZ, "%s/cards/%s/%s.json",
STORAGEDIR, user, user);
card = json_mkobject();
if (json_copy_from_file(card, path) == TRUE) {
json_copy_to_object(last, card);
} else {
json_delete(card);
}
}
JsonNode *last_users()
{
JsonNode *obj = json_mkobject();
JsonNode *un, *dn, *userlist = json_mkarray();
char path[BUFSIZ], user[BUFSIZ], device[BUFSIZ];
snprintf(path, BUFSIZ, "%s/last", STORAGEDIR);
if (user_device_list(path, 0, obj) == 1)
return (obj);
/* Loop through users, devices */
json_foreach(un, obj) {
if (un->tag != JSON_ARRAY)
continue;
strcpy(user, un->key);
json_foreach(dn, un) {
if (dn->tag == JSON_STRING) {
strcpy(device, dn->string_);
} else if (dn->tag == JSON_NUMBER) { /* all digits? */
sprintf(device, "%.lf", dn->number_);
}
append_device_details(userlist, user, device);
}
}
json_delete(obj);
return (userlist);
}
/*
* `s' has a time string in it. Try to convert into time_t
* using a variety of formats from higher to lower precision.
+1
View File
@@ -10,5 +10,6 @@ void locations(char *filename, JsonNode *obj, JsonNode *arr, time_t s_lo, time_t
int make_times(char *time_from, time_t *s_lo, char *time_to, time_t *s_to);
JsonNode *geo_json(JsonNode *json);
JsonNode *kill_datastore(char *username, char *device);
JsonNode *last_users();
#endif