aboutsummaryrefslogtreecommitdiff
path: root/src/update_database.nim
diff options
context:
space:
mode:
Diffstat (limited to 'src/update_database.nim')
-rw-r--r--src/update_database.nim75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/update_database.nim b/src/update_database.nim
new file mode 100644
index 0000000..1a27517
--- /dev/null
+++ b/src/update_database.nim
@@ -0,0 +1,75 @@
+import json
+import os
+import osproc
+import parsecfg
+import strformat
+import strutils
+
+type
+ CgiError = object of CatchableError
+ code: int
+
+proc newCgiError(code: int, message: string): ref CgiError =
+ result = newException(CgiError, message)
+ result.code = code
+
+proc readData(): string =
+ var size = parseInt(getEnv("CONTENT_LENGTH").string)
+ if size == 0:
+ return ""
+ result = newString(size)
+ if readBuffer(stdin, addr result[0], size) != 0:
+ raise newCgiError(400, "not enough data")
+
+proc main() =
+ if paramCount() != 2:
+ raise newCgiError(500, "one argument required")
+
+ let config = loadConfig(paramStr(1))
+ let databaseDir = config.getSectionValue("", "databaseDir")
+ if databaseDir == "":
+ raise newCgiError(500, "databaseDir is empty")
+
+ if getEnv("REQUEST_METHOD") != "POST":
+ raise newCgiError(400, "request method must be POST")
+
+ let j = parseJson(readData())
+
+ for alias, measurement in j:
+ let filename = normalizedPath(joinPath(databaseDir, alias & ".rrd"))
+
+ if not filename.startsWith(databaseDir):
+ raise newCgiError(400, "invalid database")
+ let
+ timestamp = measurement["timestamp"].getBiggestInt()
+ temperature = measurement["temperature"].getFloat()
+ humidity = measurement["humidity"].getFloat()
+ pressure = measurement["pressure"].getFloat()
+ battery = measurement["battery_potential"].getFloat()
+ data = &"{timestamp}:{temperature}:{humidity}:{pressure}:{battery}"
+ (_, ec) = execCmdEx(&"rrdtool update {filename} {data}")
+ if ec != 0:
+ raise newCgiError(500, "rrdtool failed")
+
+try:
+ main()
+ echo("Content-Type: text/plain")
+ echo("")
+except CgiError as e:
+ echo(&"Status: {e.code}")
+ echo("Content-Type: text/plain")
+ echo("")
+ echo(e.msg)
+ quit(0)
+except JsonParsingError as e:
+ echo(&"Status: 400 Bad Request")
+ echo("Content-Type: text/plain")
+ echo("")
+ echo(&"invalid json: {e.msg}")
+ quit(0)
+except Exception as e:
+ echo(&"Status: 500 Internal Server Error")
+ echo("Content-Type: text/plain")
+ echo("")
+ echo(e.msg)
+ quit(0)