Enhance API data with timezone at location's position

closes #444
This commit is contained in:
Jan-Piet Mens 2024-01-30 17:09:29 +01:00
parent 421cd5b944
commit 99520208fc
14 changed files with 1435 additions and 4 deletions

30
LICENSE
View File

@ -1,6 +1,6 @@
OwnTracks Recorder OwnTracks Recorder
Copyright (C) 2015-2020 Jan-Piet Mens <jpmens@gmail.com> Copyright (C) 2015-2024 Jan-Piet Mens <jpmens@gmail.com>
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
@ -330,3 +330,31 @@ 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
---------------------------------------------------------------------------
# zonedetect https://github.com/BertoldVdb/ZoneDetect
Copyright (c) 2018-2019, Bertold Van den Bergh (vandenbergh@bertold.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -15,7 +15,8 @@ OTR_OBJS = json.o \
util.o \ util.o \
storage.o \ storage.o \
fences.o \ fences.o \
listsort.o listsort.o \
zonedetect.o
OTR_EXTRA_OBJS = OTR_EXTRA_OBJS =
CFLAGS += -DGHASHPREC=$(GHASHPREC) CFLAGS += -DGHASHPREC=$(GHASHPREC)
@ -85,6 +86,7 @@ endif
CFLAGS += -DSTORAGEDEFAULT=\"$(STORAGEDEFAULT)\" -DDOCROOT=\"$(DOCROOT)\" CFLAGS += -DSTORAGEDEFAULT=\"$(STORAGEDEFAULT)\" -DDOCROOT=\"$(DOCROOT)\"
CFLAGS += -DCONFIGFILE=\"$(CONFIGFILE)\" CFLAGS += -DCONFIGFILE=\"$(CONFIGFILE)\"
CFLAGS += -DGEOCODE_TIMEOUT=$(GEOCODE_TIMEOUT) CFLAGS += -DGEOCODE_TIMEOUT=$(GEOCODE_TIMEOUT)
CFLAGS += -DTZDATADB=\"$(TZDATADB)\"
TARGETS += ot-recorder ocat TARGETS += ot-recorder ocat
@ -115,9 +117,10 @@ http.o: http.c mongoose.h util.h http.h storage.h version.h hooks.h
util.o: util.c util.h util.o: util.c util.h
mongoose.o: mongoose.c mongoose.h mongoose.o: mongoose.c mongoose.h
ocat.o: ocat.c storage.h util.h version.h config.mk Makefile ocat.o: ocat.c storage.h util.h version.h config.mk Makefile
storage.o: storage.c storage.h util.h gcache.h listsort.h storage.o: storage.c storage.h util.h gcache.h listsort.h zonedetect.c
hooks.o: hooks.c udata.h hooks.h util.h version.h gcache.h hooks.o: hooks.c udata.h hooks.h util.h version.h gcache.h
listsort.o: listsort.c listsort.h listsort.o: listsort.c listsort.h
zonedetect.o: zonedetect.c zonedetect.h
fences.o: fences.c fences.h util.h json.h udata.h gcache.h hooks.h fences.o: fences.c fences.h util.h json.h udata.h gcache.h hooks.h
@ -130,6 +133,8 @@ install: ot-recorder ocat
mkdir -p $(DESTDIR)$(INSTALLDIR)/bin mkdir -p $(DESTDIR)$(INSTALLDIR)/bin
mkdir -p $(DESTDIR)$(INSTALLDIR)/sbin mkdir -p $(DESTDIR)$(INSTALLDIR)/sbin
mkdir -p $(DESTDIR)$(DOCROOT) mkdir -p $(DESTDIR)$(DOCROOT)
mkdir -p $$(dirname $(DESTDIR)$(TZDATADB))
install contrib/tzdatadb/timezone16.bin $(TZDATADB)
mkdir -p $(DESTDIR)$(STORAGEDEFAULT) mkdir -p $(DESTDIR)$(STORAGEDEFAULT)
cd docroot && find ! -type d ! -name .gitignore -exec install -m0644 -D {} $(DESTDIR)$(DOCROOT)/{} \; cd docroot && find ! -type d ! -name .gitignore -exec install -m0644 -D {} $(DESTDIR)$(DOCROOT)/{} \;
install -m 0755 ot-recorder $(DESTDIR)$(INSTALLDIR)/sbin install -m 0755 ot-recorder $(DESTDIR)$(INSTALLDIR)/sbin

View File

@ -0,0 +1 @@
This is `timezone16.bin` from https://github.com/BertoldVdb/ZoneDetect/tree/master/database

Binary file not shown.

View File

@ -15,6 +15,7 @@ WITH_GREENWICH ?= yes
STORAGEDEFAULT = /var/spool/owntracks/recorder/store STORAGEDEFAULT = /var/spool/owntracks/recorder/store
DOCROOT = /usr/share/owntracks/recorder/htdocs DOCROOT = /usr/share/owntracks/recorder/htdocs
TZDATADB = /usr/share/owntracks/recorder/timezone16.bin
GHASHPREC = 7 GHASHPREC = 7
JSON_INDENT ?= no JSON_INDENT ?= no
MOSQUITTO_CFLAGS = MOSQUITTO_CFLAGS =

View File

@ -19,6 +19,7 @@ case "$1" in
chown owntracks:owntracks /usr/bin/ocat /usr/sbin/ot-recorder chown owntracks:owntracks /usr/bin/ocat /usr/sbin/ot-recorder
chmod a+rX -R /usr/share/owntracks/ chmod a+rX -R /usr/share/owntracks/
chmod 444 /usr/share/owntracks/recorder/timezone16.bin
chmod 4555 /usr/bin/ocat /usr/sbin/ot-recorder chmod 4555 /usr/bin/ocat /usr/sbin/ot-recorder
/usr/sbin/ot-recorder --initialize /usr/sbin/ot-recorder --initialize

View File

@ -16,6 +16,7 @@ WITH_GREENWICH ?= yes
STORAGEDEFAULT = /var/spool/owntracks/recorder/store STORAGEDEFAULT = /var/spool/owntracks/recorder/store
DOCROOT = /usr/share/owntracks/recorder/htdocs DOCROOT = /usr/share/owntracks/recorder/htdocs
TZDATADB = /usr/share/owntracks/recorder/timezone16.bin
GHASHPREC = 7 GHASHPREC = 7
JSON_INDENT ?= no JSON_INDENT ?= no
MOSQUITTO_CFLAGS = MOSQUITTO_CFLAGS =

View File

@ -19,6 +19,7 @@ case "$1" in
chown owntracks:owntracks /usr/bin/ocat /usr/sbin/ot-recorder chown owntracks:owntracks /usr/bin/ocat /usr/sbin/ot-recorder
chmod a+rX -R /usr/share/owntracks/ chmod a+rX -R /usr/share/owntracks/
chmod 444 /usr/share/owntracks/recorder/timezone16.bin
chmod 4555 /usr/bin/ocat /usr/sbin/ot-recorder chmod 4555 /usr/bin/ocat /usr/sbin/ot-recorder
/usr/sbin/ot-recorder --initialize /usr/sbin/ot-recorder --initialize

View File

@ -1986,6 +1986,7 @@ int main(int argc, char **argv)
#endif #endif
olog(LOG_INFO, "Using storage at %s with precision %d", STORAGEDIR, geohash_prec()); olog(LOG_INFO, "Using storage at %s with precision %d", STORAGEDIR, geohash_prec());
olog(LOG_INFO, "TZDATADB is at %s", TZDATADB);
while (run) { while (run) {
#ifdef WITH_MQTT #ifdef WITH_MQTT

View File

@ -1,6 +1,6 @@
/* /*
* OwnTracks Recorder * OwnTracks Recorder
* Copyright (C) 2015-2023 Jan-Piet Mens <jpmens@gmail.com> * Copyright (C) 2015-2024 Jan-Piet Mens <jpmens@gmail.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -37,6 +37,7 @@
#include "gcache.h" #include "gcache.h"
#include "util.h" #include "util.h"
#include "listsort.h" #include "listsort.h"
#include "zonedetect.h"
char STORAGEDIR[BUFSIZ] = STORAGEDEFAULT; char STORAGEDIR[BUFSIZ] = STORAGEDEFAULT;
@ -44,6 +45,7 @@ char STORAGEDIR[BUFSIZ] = STORAGEDEFAULT;
#define LARGEBUF (BUFSIZ * 2) #define LARGEBUF (BUFSIZ * 2)
static struct gcache *gc = NULL; static struct gcache *gc = NULL;
static ZoneDetect *zdb = NULL;
void storage_init(int revgeo) void storage_init(int revgeo)
{ {
@ -58,6 +60,10 @@ void storage_init(int revgeo)
olog(LOG_ERR, "storage_init(): gc is NULL"); olog(LOG_ERR, "storage_init(): gc is NULL");
} }
} }
if (zdb == NULL) {
zdb = ZDOpenDatabase(TZDATADB);
}
} }
void storage_gcache_dump(char *lmdbname) void storage_gcache_dump(char *lmdbname)
@ -710,6 +716,18 @@ static JsonNode *line_to_location(char *line)
json_append_member(o, "isotst", json_mkstring(isotime(tst))); json_append_member(o, "isotst", json_mkstring(isotime(tst)));
json_append_member(o, "disptst", json_mkstring(disptime(tst))); json_append_member(o, "disptst", json_mkstring(disptime(tst)));
if (zdb) {
char *tz_str = ZDHelperSimpleLookupString(zdb, lat, lon);
if (tz_str) {
json_append_member(o, "tz", json_mkstring(tz_str));
json_append_member(o, "isolocal", json_mkstring(isolocal(tst, tz_str)));
ZDHelperSimpleLookupStringFree(tz_str);
}
}
return (o); return (o);
} }

20
util.c
View File

@ -64,6 +64,26 @@ const char *disptime(time_t t) {
return(buf); return(buf);
} }
const char *isolocal(long tst, char *tzname)
{
char old_tz[64] = "UTC", *p;
static char local[128];
struct tm *tm;
if ((p = getenv("TZ")) != NULL) {
strcpy(old_tz, p);
}
setenv("TZ", tzname, 1);
strcpy(local, "-");
if ((tm = localtime(&tst)) != NULL) {
strftime(local, sizeof(local), "%FT%T%z", tm);
}
setenv("TZ", old_tz, 1);
return local;
}
char *slurp_file(char *filename, int fold_newlines) char *slurp_file(char *filename, int fold_newlines)
{ {
FILE *fp; FILE *fp;

1
util.h
View File

@ -19,6 +19,7 @@ int mkpath(char *path);
int is_directory(char *path); int is_directory(char *path);
const char *isotime(time_t t); const char *isotime(time_t t);
const char *disptime(time_t t); const char *disptime(time_t t);
const char *isolocal(long tst, char *tzname);
char *slurp_file(char *filename, int fold_newlines); char *slurp_file(char *filename, int fold_newlines);
int json_copy_to_object(JsonNode *obj, JsonNode * object_or_array, int clobber); int json_copy_to_object(JsonNode *obj, JsonNode * object_or_array, int clobber);
int json_copy_element_to_object(JsonNode *obj, char *key, JsonNode *node); int json_copy_element_to_object(JsonNode *obj, char *key, JsonNode *node);

1260
zonedetect.c Normal file

File diff suppressed because it is too large Load Diff

93
zonedetect.h Normal file
View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2018, Bertold Van den Bergh (vandenbergh@bertold.org)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stddef.h>
#include <stdint.h>
#ifndef INCL_ZONEDETECT_H_
#define INCL_ZONEDETECT_H_
#if !defined(ZD_EXPORT)
#if defined(_MSC_VER)
#define ZD_EXPORT __declspec(dllimport)
#else
#define ZD_EXPORT
#endif
#endif
typedef enum {
ZD_LOOKUP_IGNORE = -3,
ZD_LOOKUP_END = -2,
ZD_LOOKUP_PARSE_ERROR = -1,
ZD_LOOKUP_NOT_IN_ZONE = 0,
ZD_LOOKUP_IN_ZONE = 1,
ZD_LOOKUP_IN_EXCLUDED_ZONE = 2,
ZD_LOOKUP_ON_BORDER_VERTEX = 3,
ZD_LOOKUP_ON_BORDER_SEGMENT = 4
} ZDLookupResult;
typedef struct {
ZDLookupResult lookupResult;
uint32_t polygonId;
uint32_t metaId;
uint8_t numFields;
char **fieldNames;
char **data;
} ZoneDetectResult;
struct ZoneDetectOpaque;
typedef struct ZoneDetectOpaque ZoneDetect;
#ifdef __cplusplus
extern "C" {
#endif
ZD_EXPORT ZoneDetect *ZDOpenDatabase(const char *path);
ZD_EXPORT ZoneDetect *ZDOpenDatabaseFromMemory(void* buffer, size_t length);
ZD_EXPORT void ZDCloseDatabase(ZoneDetect *library);
ZD_EXPORT ZoneDetectResult *ZDLookup(const ZoneDetect *library, float lat, float lon, float *safezone);
ZD_EXPORT void ZDFreeResults(ZoneDetectResult *results);
ZD_EXPORT const char *ZDGetNotice(const ZoneDetect *library);
ZD_EXPORT uint8_t ZDGetTableType(const ZoneDetect *library);
ZD_EXPORT const char *ZDLookupResultToString(ZDLookupResult result);
ZD_EXPORT int ZDSetErrorHandler(void (*handler)(int, int));
ZD_EXPORT const char *ZDGetErrorString(int errZD);
ZD_EXPORT float* ZDPolygonToList(const ZoneDetect *library, uint32_t polygonId, size_t* length);
ZD_EXPORT char* ZDHelperSimpleLookupString(const ZoneDetect* library, float lat, float lon);
ZD_EXPORT void ZDHelperSimpleLookupStringFree(char* str);
#ifdef __cplusplus
}
#endif
#endif // INCL_ZONEDETECT_H_