Lua function may disable REC file storage

closes #27
This commit is contained in:
Jan-Piet Mens
2015-09-28 18:59:16 +02:00
parent c03886bea8
commit 0700293bfc
4 changed files with 63 additions and 14 deletions
+10 -3
View File
@@ -239,7 +239,7 @@ Unless already provided by the package you installed, we recommend you create a
The _recorder_ has, like _ocat_, a daunting number of options, most of which you will not require. Running either utility with the `-h` or `--help` switch will summarize their meanings. You can, for example launch with a specific storage directory, disable the HTTP server, change its port, etc.
If you require authentication or TLS to connect to your MQTT broker, pay attention to the `$OTR_` environment variables listed in the help.
If you require authentication or TLS to connect to your MQTT broker, pay attention to the `$OTR_` environment variables listed in the help.
Launch the recorder:
@@ -249,7 +249,7 @@ $ ./ot-recorder 'owntracks/#'
Publish a location from your OwnTracks app and you should see the _recorder_ receive that on the console. If you haven't disabled Geo-lookups, you'll also see the address from which the publish originated.
The location message received by the _recorder_ will be written to storage.
The location message received by the _recorder_ will be written to storage.
### Launching `ot-recorder` for _Hosted mode_
@@ -321,7 +321,7 @@ We recommend you keep reverse-geo lookups enabled, this data (country code `cc`,
## Monitoring
In order to monitor the _recorder_, whenever an MQTT message is received, a `monitor` file located relative to STORAGEDEFAULT is maintained. It contains a single line of text: the epoch timestamp and the last received topic separated from each other by a space.
In order to monitor the _recorder_, whenever an MQTT message is received, a `monitor` file located relative to STORAGEDEFAULT is maintained. It contains a single line of text: the epoch timestamp and the last received topic separated from each other by a space.
```
1439738692 owntracks/jjolie/ipad
@@ -500,6 +500,13 @@ written by OwnTracks Recorder version 0.3.0
It is 14:10:01 in the year 2015 owntracks/jane/phone lat=48.858339 Avenue Anatole France, 75007 Paris, France
```
### `putrec`
An optional function you provide is called `putrec(u, d, s)`. If it exists,
it is called with the current user in `u`, the device in `d` and the payload
(which is possibly not JSON) in the string `s`. If your function returns a
non-zero value, the _recorder_ will *not* write the REC file for this publish.
### Hooklets
After running `otr_hook()`, the _recorder_ attempts to invoke a Lua function for each of the elements in the extended JSON. If, say, your Lua script contains a function called `hooklet_lat`, it will be invoked every time a `lat` is received as part of the JSON payload. Similarly with `hooklet_addr`, `hooklet_cc`, `hooklet_tst`, etc. These _hooklets_ are invoked with the same parameters as `otr_hook()`.
+34
View File
@@ -185,6 +185,40 @@ static void hooks_hooklet(struct udata *ud, char *topic, JsonNode *fullo)
}
}
/*
* Invoked from putrec() in storage. If the Lua putrec function is available
* and it returns non-zero, do not putrec.
*/
int hooks_norec(struct udata *ud, char *user, char *device, char *payload)
{
struct luadata *ld = ud->luadata;
int rc;
if (ld == NULL)
return (0);
lua_settop(ld->L, 0);
lua_getglobal(ld->L, "putrec");
if (lua_type(ld->L, -1) != LUA_TFUNCTION) {
return (0);
}
lua_pushstring(ld->L, user);
lua_pushstring(ld->L, device);
lua_pushstring(ld->L, payload);
/* Invoke `hook' function in Lua with our args */
if (lua_pcall(ld->L, 3, 1, 0)) {
olog(LOG_ERR, "Failed to run putrec in Lua: %s", lua_tostring(ld->L, -1));
exit(1);
}
rc = (int)lua_tonumber(ld->L, -1);
printf("C: hooks_norec returns %d\n", rc);
return (rc);
}
void hooks_hook(struct udata *ud, char *topic, JsonNode *fullo)
{
do_hook("otr_hook", ud, topic, fullo);
+1
View File
@@ -13,6 +13,7 @@ struct luadata {
struct luadata *hooks_init(struct udata *ud, char *luascript);
void hooks_exit(struct luadata *, char *reason);
void hooks_hook(struct udata *ud, char *topic, JsonNode *obj);
int hooks_norec(struct udata *ud, char *user, char *device, char *payload);
#endif /* WITH_LUA */
+18 -11
View File
@@ -260,18 +260,25 @@ JsonNode *csv_to_json(char *payload)
#define RECFORMAT "%s\t%-18s\t%s\n"
static void putrec(time_t now, UT_string *reltopic, UT_string *username, UT_string *device, char *string)
/*
* Store payload in REC file unless our Lua putrec() function says
* we shouldn't for this particular user/device combo.
*/
static void putrec(struct udata *ud, time_t now, UT_string *reltopic, UT_string *username, UT_string *device, char *string)
{
FILE *fp;
if ((fp = pathn("a", "rec", username, device, "rec")) == NULL) {
olog(LOG_ERR, "Cannot write REC for %s/%s: %m",
UB(username), UB(device));
}
if (hooks_norec(ud, UB(username), UB(device), string) == 0) {
if ((fp = pathn("a", "rec", username, device, "rec")) == NULL) {
olog(LOG_ERR, "Cannot write REC for %s/%s: %m",
UB(username), UB(device));
}
fprintf(fp, RECFORMAT, isotime(now),
fprintf(fp, RECFORMAT, isotime(now),
UB(reltopic), string);
fclose(fp);
fclose(fp);
}
}
void on_message(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *m)
@@ -379,7 +386,7 @@ void on_message(struct mosquitto *mosq, void *userdata, const struct mosquitto_m
if ((json = json_decode(m->payload)) == NULL) {
if ((json = csv_to_json(m->payload)) == NULL) {
/* It's not JSON or it's not a location CSV; store it */
putrec(now, reltopic, username, device, bindump(m->payload, m->payloadlen));
putrec(ud, now, reltopic, username, device, bindump(m->payload, m->payloadlen));
return;
}
}
@@ -420,14 +427,14 @@ void on_message(struct mosquitto *mosq, void *userdata, const struct mosquitto_m
case T_LWT:
case T_STEPS:
case T_WAYPOINTS:
putrec(now, reltopic, username, device, bindump(m->payload, m->payloadlen));
putrec(ud, now, reltopic, username, device, bindump(m->payload, m->payloadlen));
goto cleanup;
case T_WAYPOINT:
case T_TRANSITION:
case T_LOCATION:
break;
default:
putrec(now, reltopic, username, device, bindump(m->payload, m->payloadlen));
putrec(ud, now, reltopic, username, device, bindump(m->payload, m->payloadlen));
goto cleanup;
}
@@ -542,7 +549,7 @@ void on_message(struct mosquitto *mosq, void *userdata, const struct mosquitto_m
if (!pingping) {
if ((jsonstring = json_stringify(json, NULL)) != NULL) {
putrec(now, reltopic, username, device, jsonstring);
putrec(ud, now, reltopic, username, device, jsonstring);
free(jsonstring);
}
}