From: Andy Spencer Date: Mon, 11 Jun 2012 00:55:43 +0000 (+0000) Subject: Add json load/save and save email addresses X-Git-Url: http://pileus.org/git/?p=~andy%2Frhawk;a=commitdiff_plain;h=520dcb84adcd9af6b1f3734495650c862bc9f55e Add json load/save and save email addresses --- diff --git a/email.awk b/email.awk index 270836e..a417f9e 100644 --- a/email.awk +++ b/email.awk @@ -1,3 +1,9 @@ +@include "json.awk" + +# Save email addresses +BEGIN { json_load("var/mail.txt", mail_enable) } +END { json_save("var/mail.txt", mail_enable) } + # Email notifications BEGIN { mail_hist = 60 # Send 60 seconds of backlog @@ -6,6 +12,9 @@ BEGIN { mail_from = NICK "" mail_err = "If you received this message in error,\n" \ "someone in #rhnoise is being a jerk" + + for (_user in mail_enable) + debug("watching " mail_enable[_user] " for " _user) } function mail_send(addr, subj, body, @@ -67,7 +76,7 @@ FROM ~ OWNER && } /^e?mail *[^ ]*$/ { - reply("notifying " $2) + reply("notifying " $2 " for " FROM) mail_enable[FROM] = $2 } diff --git a/json.awk b/json.awk new file mode 100644 index 0000000..2f735c4 --- /dev/null +++ b/json.awk @@ -0,0 +1,345 @@ +# value: +# object: { string : value, .. } +# array: [ value, .. ] +# string: "char .." +# number: (builtin) +# true +# false +# null +# +# chars: +# any-Unicode-character-except-"-or-\-or-control-character +# \" +# \\ +# \/ +# \b +# \f +# \n +# \r +# \t +# \u four-hex-digits + + +# Helpers +function json_gettype(value, key, sort, n, i) +{ + if (isarray(value)) { + for (key in value) + if (isarray(key)) + return "error" + n = asorti(value, sort) + for (i = 0; i < n; i++) + if (sort[i+1] != i) + return "object" + return "array" + } else { + if (value == value + 0) + return "number" + if (value == value "") + return "string" + return "error" + } +} + +function json_join(array, sep, i, str) +{ + str = array[0] + for (i = 1; i < length(array); i++) + str = str sep array[i] + return str +} + +function json_copy(dst, to, src, key) +{ + if (isarray(src)) { + delete dst[to] + for (key in src) { + dst[to][key] + json_copy(dst[to], key, src[key]) + } + } else { + dst[to] = src + } +} + + +# Write functions +function json_write_value(value, pad) +{ + switch (json_gettype(value)) { + case "object": return json_write_object(value, pad) + case "array": return json_write_array(value, pad) + case "number": return json_write_number(value) + case "string": return json_write_string(value) + default: return "error" + } +} + +function json_write_object(object, pad, n, i, sort, key, val, data, len, max) +{ + n = asorti(object, sort) + for (i = 0; i < n; i++) { + key = json_write_string(sort[i+1]) + if (length(key) > max) + max = length(key) + } + for (i = 0; i < n; i++) { + key = json_write_string(sort[i+1]) + val = json_write_value(object[sort[i+1]], + sprintf("%s %"max"s ", pad, "")) + data[i] = sprintf("%-"(max+1)"s %s", key":", val) + } + return "{ " json_join(data, ",\n " pad) " }" +} + +function json_write_array(array, pad, i, data) +{ + for (i = 0; i < length(array); i++) + data[i] = json_write_value(array[i], pad " ") + return "[ " json_join(data, ",\n " pad) " ]" +} + +function json_write_number(number) +{ + return "" number "" +} + +function json_write_string(string) +{ + # todo: special characters + return "\"" string "\"" +} + + +# Read functions +function json_tokenize(str, tokens, i, items, table, type, found) +{ + table["term"] = "^[\\[\\]{}:,]" + table["str"] = "^\"[^\"]*\"" + table["num"] = "^[0-9]+" + table["var"] = "^(true|false|null)" + table["space"] = "^[ \\t\\n]+" + i = 0 + while (length(str) > 0) { + found = 0 + for (type in table) { + #print "match: str=["str"] type="type" regex=/"table[type]"/" + if (match(str, table[type], items) > 0) { + #print " len="RLENGTH" item=["items[0]"]" + if (type == "term") + type = items[0] + if (type != "space") { + tokens[i]["type"] = type + tokens[i]["text"] = items[0] + i++ + } + str = substr(str, RLENGTH+1) + found = 1 + break + } + } + if (!found) { + debug("error tokenizing") + return 0 + } + } + return i + + #for (i = 0; i < length(tokens); i++) + # printf "%-3s %-5s [%s]\n", i":", + # tokens[i]["type"], tokens[i]["text"] +} + +function json_parse_value(tokens, i, value, key, type, text) +{ + if (!i ) i = 0; + if (!depth) depth = 0 + depth++ + type = tokens[i]["type"] + text = tokens[i]["text"] + #printf "parse %d: i=%-2d type=%-3s text=%s\n", depth, i, type, text + switch (type) { + case "{": i = json_parse_object(tokens, i, value, key); break + case "[": i = json_parse_array(tokens, i, value, key); break + case "str": i = json_parse_string(tokens, i, value, key); break + case "num": i = json_parse_number(tokens, i, value, key); break + case "var": i = json_parse_var(tokens, i, value, key); break + default: debug("error: type="type" text="text); return 0 + } + depth-- + return i +} + +function json_parse_object(tokens, i, value, key, object, k, v) +{ + if (tokens[i++]["text"] != "{") + return 0; + + do { + delete k + delete v + if (!(i=json_parse_value(tokens, i, k, 0))) + return 0 + if (tokens[i++]["text"] != ":") + return 0 + if (!(i=json_parse_value(tokens, i, v, 0))) + return 0 + json_copy(object, k[0], v[0]) + } while (tokens[i++]["text"] == ",") + i-- + + if (tokens[i++]["text"] != "}") + return 0; + + json_copy(value, key, object) + return i +} + +function json_parse_array(tokens, i, value, key, array, k, v) +{ + #print "parse_array: .." + if (tokens[i++]["text"] != "[") + return 0; + + do { + delete v + if (!(i=json_parse_value(tokens, i, v, 0))) + return 0 + json_copy(array, k++, v[0]) + } while (tokens[i++]["text"] == ",") + i-- + + if (tokens[i++]["text"] != "]") + return 0; + + json_copy(value, key, array) + return i +} + +function json_parse_number(tokens, i, value, key, text) +{ + text = tokens[i++]["text"] + json_copy(value, key, text + 0) + #print "parse_number: " (text + 0) + return i +} + +function json_parse_string(tokens, i, value, key, text) +{ + text = tokens[i++]["text"] + text = substr(text, 2, length(text)-2) + json_copy(value, key, text) + #print "parse_string: " text + return i +} + +function json_parse_var(tokens, i, value, key, text) +{ + text = tokens[i++]["text"] + json_copy(value, key, text == "true") + #print "parse_var: " text " -> " text == "true" + return i +} + + +# Nice API? +function json_load(file, var, line, text, tokens, data, key) +{ + while ((getline line < file) > 0) + text = text line + close(file) + if (!json_tokenize(text, tokens)) + return "" + if (!json_parse_value(tokens, 0, data, 0)) + return "" + if (!isarray(data[0])) + return data[0] + for (key in data[0]) + json_copy(var, key, data[0][key]) +} + +function json_save(file, var, cmd, tmp) +{ + cmd = "mktemp ." file ".XXX" + cmd | getline tmp + close(cmd) + print json_write_value(var) > tmp + close(tmp) + system("mv " tmp " " file) +} + + +# Test functions +function json_test_write() +{ + num = 42 + str = "hello, world" + arr[0] = "zero" + arr[1] = "one" + arr[2] = "two" + obj["A"] = "a!" + obj["B"] = "b!" + obj["C"] = "c!" + json_copy(mix, "number", num); + json_copy(mix, "str", str); + json_copy(mix, "arr", arr); + json_copy(mix, "obj", obj); + json_copy(dub, "first", mix); + json_copy(dub, "second", mix); + print json_write_value(num) + print json_write_value(str) + print json_write_value(arr) + print json_write_value(obj) + print json_write_value(mix) + print json_write_value(dub) +} + +function json_test_read() +{ + json_tokenize("[8, \"abc\", 9]", tokens) + json_parse_value(tokens, 0, array, 0) + json_print write_value(array[0]) + + json_tokenize("{\"abc\": 1, \"def\": 2}", tokens) + json_parse_value(tokens, 0, array, 0) + json_print write_value(array[0]) + + json = "{ \"first\": { \"arr\": [ \"zero\", " \ + " \"one\", " \ + " \"two\" ], " \ + " \"number\": 42, " \ + " \"obj\": { \"A\": \"a!\", " \ + " \"B\": \"b!\", " \ + " \"C\": \"c!\" }, " \ + " \"str\": \"hello, world\" }, " \ + " \"second\": { \"arr\": [ \"zero\", " \ + " \"one\", " \ + " \"two\" ], " \ + " \"number\": 42, " \ + " \"obj\": { \"A\": \"a!\", " \ + " \"B\": \"b!\", " \ + " \"C\": \"c!\" }, " \ + " \"str\": \"hello, world\" } }" + + json_tokenize(json, tokens) + json_parse_value(tokens, 0, array, 0) + print json_write_value(array[0]) +} + +function json_test_files() +{ + print "load: [" json_load("email.txt", mail) "]" + print "mail: " json_write_value(mail, " ") + mail["andy753421"] = "andy753421@gmail.com" + mail["andy"] = "andy@gmail.com" + mail["somebody"] = "foo@example.com" + print "mail: " json_write_value(mail, " ") + print "save: [" json_save("email.txt", mail) "]" +} + +# Main +BEGIN { + #json_test_write() + #json_test_read() + #json_test_files() +}