mirror of
https://github.com/owntracks/recorder.git
synced 2026-08-27 16:57:21 +00:00
Feature: ocat userlist (incomplete!)
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user