mirror of
https://github.com/owntracks/recorder.git
synced 2026-08-23 11:26:16 +00:00
@@ -14,6 +14,7 @@
|
||||
<td><xsl:value-of select="lat"/>, <xsl:value-of select="lon"/></td>
|
||||
<td><xsl:value-of select="ghash"/></td>
|
||||
<td><xsl:value-of select="addr"/></td>
|
||||
<td><xsl:value-of select="cc"/></td>
|
||||
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
|
||||
@@ -229,6 +229,22 @@ static int json_response(struct mg_connection *conn, JsonNode *json)
|
||||
return (MG_TRUE);
|
||||
}
|
||||
|
||||
static void emit_xml_line(char *line, void *param)
|
||||
{
|
||||
struct mg_connection *conn = (struct mg_connection *)param;
|
||||
|
||||
mg_printf_data(conn, line);
|
||||
mg_printf_data(conn, "\n");
|
||||
}
|
||||
|
||||
static int xml_response(struct mg_connection *conn, JsonNode *obj)
|
||||
{
|
||||
/* TODO: support fields? */
|
||||
xml_output(obj, CSV, NULL, emit_xml_line, conn);
|
||||
|
||||
json_delete(obj);
|
||||
return (MG_TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* We are being called with the portion behind /api/0/ as in
|
||||
@@ -317,6 +333,8 @@ static int dispatch(struct mg_connection *conn, const char *uri)
|
||||
otype = JSON;
|
||||
else if (!strcmp(buf, "linestring"))
|
||||
otype = LINESTRING;
|
||||
else if (!strcmp(buf, "xml"))
|
||||
otype = XML;
|
||||
else {
|
||||
mg_send_status(conn, 400);
|
||||
mg_printf_data(conn, "unrecognized format\n");
|
||||
@@ -372,6 +390,8 @@ static int dispatch(struct mg_connection *conn, const char *uri)
|
||||
|
||||
if (otype == JSON) {
|
||||
return (json_response(conn, obj));
|
||||
} else if (otype == XML) {
|
||||
return (xml_response(conn, obj));
|
||||
} else if (otype == LINESTRING) {
|
||||
JsonNode *geoline = geo_linestring(locs);
|
||||
|
||||
|
||||
@@ -55,44 +55,13 @@ static void print_one(JsonNode *j, JsonNode *inttypes)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the value in a single JSON node as XML. If string, easy. If number account for
|
||||
* what we call 'integer' types which shouldn't be printed as floats.
|
||||
*/
|
||||
|
||||
static void emit_one(JsonNode *j, JsonNode *inttypes)
|
||||
static void print_xml_line(char *line, void *param)
|
||||
{
|
||||
if (!strcmp(j->key, "_type"))
|
||||
return;
|
||||
FILE *fp = (FILE *)param;
|
||||
|
||||
printf(" <%s>", j->key);
|
||||
/* 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) {
|
||||
char *bp;
|
||||
|
||||
for (bp = j->string_; bp && *bp; bp++) {
|
||||
switch (*bp) {
|
||||
case '&': printf("&"); break;
|
||||
case '<': printf("<"); break;
|
||||
case '>': printf(">"); break;
|
||||
case '"': printf("""); break;
|
||||
case '\'': printf("'"); break;
|
||||
default: putc(*bp, stdout); break;
|
||||
}
|
||||
}
|
||||
} else if (j->tag == JSON_BOOL) {
|
||||
printf("%s", (j->bool_) ? "true" : "false");
|
||||
} else if (j->tag == JSON_NULL) {
|
||||
printf("null");
|
||||
}
|
||||
printf("</%s>\n", j->key);
|
||||
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
|
||||
@@ -154,47 +123,6 @@ void csv_output(JsonNode *json, output_type otype, JsonNode *fields)
|
||||
json_delete(inttypes);
|
||||
}
|
||||
|
||||
|
||||
void xml_output(JsonNode *json, output_type otype, JsonNode *fields)
|
||||
{
|
||||
JsonNode *node, *inttypes;
|
||||
JsonNode *arr, *one, *j;
|
||||
|
||||
/* 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));
|
||||
|
||||
printf("<?xml version='1.0' encoding='UTF-8'?>\n\
|
||||
<?xml-stylesheet type='text/xsl' href='owntracks.xsl'?>\n");
|
||||
printf("<owntracks>\n");
|
||||
|
||||
arr = json_find_member(json, "locations");
|
||||
json_foreach(one, arr) {
|
||||
printf(" <point>\n");
|
||||
if (fields) {
|
||||
json_foreach(node, fields) {
|
||||
if ((j = json_find_member(one, node->string_)) != NULL) {
|
||||
emit_one(j, inttypes);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
json_foreach(j, one) {
|
||||
emit_one(j, inttypes);
|
||||
}
|
||||
}
|
||||
printf(" </point>\n\n");
|
||||
}
|
||||
printf("</owntracks>\n");
|
||||
|
||||
json_delete(inttypes);
|
||||
}
|
||||
|
||||
void usage(char *prog)
|
||||
{
|
||||
printf("Usage: %s [options..] [file ...]\n", prog);
|
||||
@@ -277,6 +205,7 @@ int main(int argc, char **argv)
|
||||
time_t now, s_lo, s_hi;
|
||||
output_type otype = JSON;
|
||||
JsonNode *fields = NULL;
|
||||
FILE *xmlp = stdout;
|
||||
|
||||
if ((p = getenv("OCAT_USERNAME")) != NULL) {
|
||||
username = strdup(p);
|
||||
@@ -478,7 +407,7 @@ int main(int argc, char **argv)
|
||||
JsonNode *o = json_mkobject();
|
||||
|
||||
json_append_member(o, "locations", user_array);
|
||||
xml_output(o, CSV, fields);
|
||||
xml_output(o, XML, fields, print_xml_line, xmlp);
|
||||
json_delete(o);
|
||||
|
||||
} else {
|
||||
@@ -596,7 +525,7 @@ int main(int argc, char **argv)
|
||||
} else if (otype == CSV) {
|
||||
csv_output(obj, CSV, fields);
|
||||
} else if (otype == XML) {
|
||||
xml_output(obj, XML, fields);
|
||||
xml_output(obj, XML, fields, print_xml_line, xmlp);
|
||||
} else if (otype == RAW || otype == RAWPAYLOAD) {
|
||||
/* We've already done what we need to do in locations() */
|
||||
} else if (otype == LINESTRING) {
|
||||
|
||||
@@ -953,3 +953,88 @@ JsonNode *kill_datastore(char *user, char *device)
|
||||
return (obj);
|
||||
}
|
||||
#endif /* HAVE_KILL */
|
||||
|
||||
/*
|
||||
* Print the value in a single JSON node as XML by invoking func(). If string,
|
||||
* easy. If number account for what we call 'integer' types which shouldn't be
|
||||
* printed as floats.
|
||||
*/
|
||||
|
||||
static void emit_one(JsonNode *j, JsonNode *inttypes, void (func)(char *line, void *param), void *param)
|
||||
{
|
||||
static UT_string *line = NULL;
|
||||
|
||||
|
||||
if (!strcmp(j->key, "_type"))
|
||||
return;
|
||||
|
||||
utstring_renew(line);
|
||||
utstring_printf(line, " <%s>", j->key);
|
||||
/* Check if the value should be an "integer" (ie not float) */
|
||||
if (j->tag == JSON_NUMBER) {
|
||||
if (json_find_member(inttypes, j->key)) {
|
||||
utstring_printf(line, "%.lf", j->number_);
|
||||
} else {
|
||||
utstring_printf(line, "%lf", j->number_);
|
||||
}
|
||||
} else if (j->tag == JSON_STRING) {
|
||||
char *bp;
|
||||
|
||||
for (bp = j->string_; bp && *bp; bp++) {
|
||||
switch (*bp) {
|
||||
case '&': utstring_printf(line, "&"); break;
|
||||
case '<': utstring_printf(line, "<"); break;
|
||||
case '>': utstring_printf(line, ">"); break;
|
||||
case '"': utstring_printf(line, """); break;
|
||||
case '\'': utstring_printf(line, "'"); break;
|
||||
default: utstring_printf(line, "%c", *bp); break;
|
||||
}
|
||||
}
|
||||
} else if (j->tag == JSON_BOOL) {
|
||||
utstring_printf(line, "%s", (j->bool_) ? "true" : "false");
|
||||
} else if (j->tag == JSON_NULL) {
|
||||
utstring_printf(line, "null");
|
||||
}
|
||||
utstring_printf(line, "</%s>", j->key);
|
||||
func(utstring_body(line), param);
|
||||
}
|
||||
|
||||
void xml_output(JsonNode *json, output_type otype, JsonNode *fields, void (*func)(char *s, void *param), void *param)
|
||||
{
|
||||
JsonNode *node, *inttypes;
|
||||
JsonNode *arr, *one, *j;
|
||||
|
||||
/* 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));
|
||||
|
||||
func("<?xml version='1.0' encoding='UTF-8'?>\n\
|
||||
<?xml-stylesheet type='text/xsl' href='owntracks.xsl'?>", param);
|
||||
func("<owntracks>", param);
|
||||
|
||||
arr = json_find_member(json, "locations");
|
||||
json_foreach(one, arr) {
|
||||
func(" <point>", param);
|
||||
if (fields) {
|
||||
json_foreach(node, fields) {
|
||||
if ((j = json_find_member(one, node->string_)) != NULL) {
|
||||
emit_one(j, inttypes, func, param);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
json_foreach(j, one) {
|
||||
emit_one(j, inttypes, func, param);
|
||||
}
|
||||
}
|
||||
func(" </point>\n", param);
|
||||
}
|
||||
func("</owntracks>", param);
|
||||
|
||||
json_delete(inttypes);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user