/* * Copyright (C) 2015 Jan-Piet Mens and OwnTracks * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * JAN-PIET MENS OR OWNTRACKS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #include #include #include #include "json.h" #include "storage.h" #include "util.h" #include "misc.h" #include "version.h" /* * Print the value in a single JSON node. If string, easy. If number account for * what we call 'integer' types which shouldn't be printed as floats. */ static void print_one(JsonNode *j, JsonNode *inttypes) { /* Check if the value should be an "integer" (ie not float) */ if (j->tag == JSON_NUMBER) { if (json_find_member(inttypes, j->key)) { printf("%.lf", j->number_); } else { printf("%lf", j->number_); } } else if (j->tag == JSON_STRING) { printf("%s", j->string_); } else if (j->tag == JSON_BOOL) { printf("%s", (j->bool_) ? "true" : "false"); } else if (j->tag == JSON_NULL) { printf("null"); } } static void print_xml_line(char *line, void *param) { FILE *fp = (FILE *)param; fprintf(fp, "%s\n", line); } /* * Output location data as CSV. If `fields' is not NULL, it's a JSON * array of JSON elment names which should be printed instead of the * default ALL. */ void csv_output(JsonNode *json, output_type otype, JsonNode *fields) { JsonNode *node, *inttypes; JsonNode *arr, *one, *j; short virgin = 1; /* Prime the inttypes object with types we consider "integer" */ inttypes = json_mkobject(); json_append_member(inttypes, "batt", json_mkbool(1)); json_append_member(inttypes, "vel", json_mkbool(1)); json_append_member(inttypes, "cog", json_mkbool(1)); json_append_member(inttypes, "tst", json_mkbool(1)); json_append_member(inttypes, "alt", json_mkbool(1)); json_append_member(inttypes, "dist", json_mkbool(1)); json_append_member(inttypes, "trip", json_mkbool(1)); arr = json_find_member(json, "locations"); json_foreach(one, arr) { /* Headings */ if (virgin) { virgin = !virgin; if (fields) { json_foreach(node, fields) { printf("%s%c", node->string_, (node->next) ? ',' : '\n'); } } else { json_foreach(j, one) { if (j->key) printf("%s%c", j->key, (j->next) ? ',' : '\n'); } } } /* Now the values */ if (fields) { json_foreach(node, fields) { if ((j = json_find_member(one, node->string_)) != NULL) { print_one(j, inttypes); printf("%c", node->next ? ',' : '\n'); } else { /* specified field not in JSON for this row */ printf("%c", node->next ? ',' : '\n'); } } } else { json_foreach(j, one) { print_one(j, inttypes); printf("%c", j->next ? ',' : '\n'); } } } json_delete(inttypes); } void usage(char *prog) { printf("Usage: %s [options..] [file ...]\n", prog); printf(" --help -h this message\n"); printf(" --list -l list users (or a user's (-u) devices\n"); printf(" --user username -u specify username ($OCAT_USERNAME)\n"); printf(" --device devicename -d specify device name ($OCAT_DEVICE)\n"); printf(" --from