]> Pileus Git - ~andy/rhawk/blob - remind.awk
Save game after flipping the table
[~andy/rhawk] / remind.awk
1 @include "json.awk"
2
3 # Load saved at queue
4 BEGIN {
5         json_load("var/remind.json", remind);
6 }
7
8 # Parse an at style time
9 function atp(now, time,   cmd, iso, arr, month) {
10         # Remove quotes if needed
11         gsub(/["']/, "", time);
12
13         # Normalize date
14         cmd = "atp " now " " time " 2>/dev/null";
15         cmd | getline iso;
16         close(cmd);
17
18         # Parse date
19         gsub(/^\w+ |:/, " ", iso);
20         if (!match(iso, /(\w+) +([0-9]+ [0-9]+ [0-9]+ [0-9]+) +([0-9]+)/, arr))
21                 return -1;
22         month = (index("JanFebMarAprMayJunJulAugSepOctNovDec", arr[1])-1)/3+1;
23         return mktime(arr[3] " " month " " arr[2])
24 }
25
26 # Queue a new job
27 function at(from, text, prefix,   now, arr, desc, time, mesg, cmd) {
28         now = systime();
29
30         # Check input
31         if (!match(text, /^.(at|in) +([a-zA-Z0-9:+-]+|"[ a-zA-Z0-9:+-]+") +(.*)/, arr))
32                 return reply("invalid time");
33         if (!arr[3])
34                 return reply("no message");
35         desc = arr[2];
36         mesg = arr[3];
37
38         # Parse date
39         time = atp(now, prefix desc);
40         if (time < 0)
41                 return reply("unparsable time: " desc);
42         if (time < now)
43                 return reply("time is in the past");
44         if (time == now)
45                 return reply("date is right now");
46
47         # Log message
48         id = length(remind);
49         remind[id]["time"] = time;
50         remind[id]["from"] = from;
51         remind[id]["mesg"] = mesg;
52         remind[id]["done"] = "pending";
53         json_save("var/remind.json", remind);
54
55         say("queued job " id ": " \
56                 strftime("%Y-%m-%d %H:%M", time));
57 }
58
59 # Print the at queue
60 function atq(all,    i, from, time, done, desc, line) {
61         for (i = 0; i < length(remind); i++) {
62                 from = remind[i]["from"];
63                 time = remind[i]["time"];
64                 done = remind[i]["done"];
65                 if (!all && done != "pending")
66                         continue;
67                 desc = strftime("%Y-%m-%d %H:%M", time);
68                 line = sprintf("%-3d %s  %s (%s)", i, desc, from, done);
69                 say(line);
70         }
71 }
72
73 # Print an at job
74 function atc(id) {
75         if (id >= length(remind))
76                 return reply("invalid job id");
77         say("job " id ": " remind[id]["mesg"]);
78 }
79
80 # Remove job from the queue
81 function atrm(id) {
82         if (id >= length(remind))
83                 return reply("invalid job id");
84         if (remind[id]["done"] != "pending")
85                 return reply("job is not pending");
86         remind[id]["done"] = "canceled";
87         json_save("var/remind.json", remind);
88         say("canceled job " id);
89 }
90
91 # Run the at daemon
92 function atd(now) {
93         now = systime();
94         for (i = 0; i < length(remind); i++) {
95                 if (remind[i]["done"] != "pending")
96                         continue;
97                 if (remind[i]["time"] > now)
98                         continue;
99                 remind[i]["done"] = "finished";
100                 say(CHANNEL, remind[i]["from"] ": " remind[i]["mesg"]);
101         }
102         json_save("var/remind.json", remind);
103 }
104
105
106 # At handlers
107 /^\.at / {
108         at(FROM, $0, "");
109 }
110
111 /^\.in / {
112         at(FROM, $0, "now+");
113 }
114
115 /^\.atq/ {
116         atq($0 ~ /!/);
117 }
118
119 /^\.atc +[0-9]+$/ {
120         atc($2);
121 }
122
123 /^\.atrm +[0-9]+$/ {
124         atrm($2);
125 }
126
127 /^\.help$/ {
128         say(".help at   -- queue reminders for later")
129 }
130
131 /^\.help at/ {
132         say(".at [time] [msg] -- record a message for the given time")
133         say(".in [len] [msg] -- same as .at \"now + len\"")
134         say(".atq -- list any pending job")
135         say(".atq! -- list all jobs in the queue")
136         say(".atc [n] -- print the given job")
137         say(".atrm [n] -- delete the given job")
138         next
139 }
140
141 // { 
142         atd();
143 }