diff options
author | euxane | 2025-02-08 22:41:27 +0100 |
---|---|---|
committer | euxane | 2025-02-08 23:34:38 +0100 |
commit | bda07906d1851f95bfc25f0bfc43a42ced8d48b2 (patch) | |
tree | a97f4a5ff7570a1f6d5da3fa8cbd0a215d3b9064 /main.nim | |
parent | 93d00382d3a8f4a89674c60207d6b797bf0d0b99 (diff) | |
download | tickwatch-bda07906d1851f95bfc25f0bfc43a42ced8d48b2.tar.gz |
repo: move nim sources into subdir
Diffstat (limited to 'main.nim')
-rw-r--r-- | main.nim | 133 |
1 files changed, 0 insertions, 133 deletions
diff --git a/main.nim b/main.nim deleted file mode 100644 index 07686ed..0000000 --- a/main.nim +++ /dev/null | |||
@@ -1,133 +0,0 @@ | |||
1 | # tickwatch | ||
2 | # Author: Euxane TRAN-GIRARD | ||
3 | # Licence: EUPL-1.2 | ||
4 | |||
5 | import std/sugar | ||
6 | import std/math | ||
7 | import std/times | ||
8 | import std/net | ||
9 | import std/posix | ||
10 | import std/paths | ||
11 | import std/strutils | ||
12 | import std/sequtils | ||
13 | import std/parseopt | ||
14 | |||
15 | import file | ||
16 | import ping | ||
17 | import logger | ||
18 | |||
19 | |||
20 | const | ||
21 | NAME = "tickwatch" | ||
22 | VERSION = staticExec(""" | ||
23 | command -v git >/dev/null && git describe --tags --always || echo $VERSION | ||
24 | """).strip() | ||
25 | HELP_TEXT = | ||
26 | staticRead("readme.md") | ||
27 | .split("```helptext", 1)[1] | ||
28 | .split("```", 1)[0] | ||
29 | .strip() | ||
30 | |||
31 | proc registerTerminationHandlers() = | ||
32 | proc terminationHandler(sig: cint) {.noconv.} = flushAndQuit() | ||
33 | var action = SigAction(sa_handler: terminationHandler) | ||
34 | for signal in [SIGTERM, SIGHUP, SIGQUIT, SIGINT]: | ||
35 | discard sigaction(signal, action) | ||
36 | |||
37 | func getArg( | ||
38 | args: seq[tuple[kind: CmdLineKind, key, val: string]], | ||
39 | index: int, | ||
40 | label: string | ||
41 | ): string = | ||
42 | try: args[index].key | ||
43 | except: raise newException(ValueError, "Missing " & label & " argument") | ||
44 | |||
45 | proc main() = | ||
46 | var | ||
47 | scale: Scale = log2 | ||
48 | symbols = UNICODE_SYMBOLS | ||
49 | timestampHeader = formatTimestampDateTime | ||
50 | (min, max) = (0, 1000) | ||
51 | |||
52 | for optKind, key, val in getopt(): | ||
53 | if optKind notin {cmdLongOption, cmdShortOption}: | ||
54 | continue | ||
55 | |||
56 | case key: | ||
57 | |||
58 | of "help", "h": | ||
59 | echo HELP_TEXT | ||
60 | quit(0) | ||
61 | |||
62 | of "version", "v": | ||
63 | echo NAME & " " & VERSION | ||
64 | quit(0) | ||
65 | |||
66 | of "scale": | ||
67 | case val: | ||
68 | of "logarithmic", "log", "log2": scale = log2 | ||
69 | of "log10": scale = log10 | ||
70 | of "ln": scale = ln | ||
71 | of "linear", "lin": scale = (val: float) => val | ||
72 | else: raise newException(ValueError, "Unrecognised scale choice") | ||
73 | |||
74 | of "symbols": | ||
75 | case val: | ||
76 | of "unicode", "utf8", "utf-8": symbols = UNICODE_SYMBOLS | ||
77 | of "numeric", "ascii": symbols = NUMERIC_SYMBOLS | ||
78 | else: raise newException(ValueError, "Unrecognised symbols choice") | ||
79 | |||
80 | of "timestamp": | ||
81 | case val: | ||
82 | of "datetime", "date-time": timestampHeader = formatTimestampDateTime | ||
83 | of "unix", "epoch": timestampHeader = formatTimestampUnix | ||
84 | of "none", "false": timestampHeader = formatTimestampNone | ||
85 | else: raise newException(ValueError, "Unrecognised timestamp choice") | ||
86 | |||
87 | of "range": | ||
88 | let parts = val.split(':', 1) | ||
89 | if parts.len != 2: raise newException(ValueError, "Invalid range") | ||
90 | (min, max) = (parseInt(parts[0]), parseInt(parts[1])) | ||
91 | |||
92 | else: | ||
93 | raise newException(ValueError, "Unrecognised option") | ||
94 | |||
95 | let | ||
96 | args = getopt().toSeq.filterIt(it.kind == cmdArgument) | ||
97 | monitor = args.getArg(0, "monitor") | ||
98 | target = args.getArg(1, "target") | ||
99 | |||
100 | if args.len > 2: | ||
101 | raise newException(ValueError, "Invalid number of arguments") | ||
102 | |||
103 | let probe = case monitor: | ||
104 | of "ping": | ||
105 | let targetIp = resolve(target) | ||
106 | let mon = initPingMonitor(targetIp, procIdent()) | ||
107 | (timeout: Duration) => mon.ping(timeout).inMilliseconds.int | ||
108 | |||
109 | of "value": | ||
110 | let mon = initFileValueMonitor(Path target) | ||
111 | (timeout: Duration) => mon.readValue() | ||
112 | |||
113 | of "change": | ||
114 | let mon = initFileChangeMonitor(Path target) | ||
115 | (timeout: Duration) => mon.readValue() | ||
116 | |||
117 | else: | ||
118 | raise newException(ValueError, "Unrecognised monitor argument") | ||
119 | |||
120 | loop( | ||
121 | probe, | ||
122 | (val: int) => symbols.indicator(min, max, val, scale), | ||
123 | timestampHeader, | ||
124 | ) | ||
125 | |||
126 | |||
127 | when not defined(test): | ||
128 | try: | ||
129 | registerTerminationHandlers() | ||
130 | main() | ||
131 | except CatchableError as err: | ||
132 | stderr.writeLine err.msg | ||
133 | quit(1) | ||