aboutsummaryrefslogtreecommitdiff
path: root/src/update_database.nim
blob: 1a2751748bca99551502301b8be98e7e72f2b71a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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)