0
|
1 /* |
|
2 * history.js -- track nickname's history |
|
3 * |
|
4 * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> |
|
5 * |
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
|
7 * purpose with or without fee is hereby granted, provided that the above |
|
8 * copyright notice and this permission notice appear in all copies. |
|
9 * |
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
17 */ |
|
18 |
|
19 /* Modules */ |
|
20 var Directory = Irccd.Directory; |
|
21 var File = Irccd.File; |
|
22 var Logger = Irccd.Logger; |
|
23 var Plugin = Irccd.Plugin; |
|
24 var Server = Irccd.Server; |
|
25 var Util = Irccd.Util; |
|
26 |
|
27 /* Plugin information */ |
|
28 info = { |
|
29 author: "David Demelier <markand@malikania.fr>", |
|
30 license: "ISC", |
|
31 summary: "track nickname's history", |
|
32 version: "@IRCCD_VERSION@" |
|
33 }; |
|
34 |
|
35 var formats = { |
|
36 "error": "#{nickname}, I'm sorry, something went wrong.", |
|
37 "seen": "#{nickname}, I've seen #{target} for the last time the %d-%m-%Y %H:%M", |
|
38 "said": "#{nickname}, #{target} said on %d-%m-%Y %H:%M: #{message}", |
|
39 "unknown": "#{nickname}, I've never seen #{target}.", |
|
40 "usage": "#{nickname}, usage: #{plugin} seen | said <target>." |
|
41 }; |
|
42 |
|
43 function isSelf(server, origin) |
|
44 { |
|
45 return server.info().nickname === Util.splituser(origin); |
|
46 } |
|
47 |
|
48 function command(server) |
|
49 { |
|
50 return server.info().commandChar + "history"; |
|
51 } |
|
52 |
|
53 function path(server, channel) |
|
54 { |
|
55 var p; |
|
56 |
31
|
57 if (Plugin.config["file"] !== undefined) { |
|
58 p = Util.format(Plugin.config["file"], { |
0
|
59 "server": server.toString(), |
|
60 "channel": channel |
|
61 }); |
|
62 } else { |
|
63 p = Plugin.cachePath + "db.json"; |
|
64 } |
|
65 |
|
66 return p; |
|
67 } |
|
68 |
|
69 function read(server, channel, nickname) |
|
70 { |
|
71 var p = path(server, channel); |
|
72 var db = {}; |
|
73 |
|
74 if (File.exists(p)) { |
|
75 var file = new File(path(server, channel), "r"); |
|
76 var str = file.read(); |
|
77 |
|
78 db = JSON.parse(str); |
|
79 } |
|
80 |
|
81 /* Complete if needed */ |
|
82 if (!db[server]) |
|
83 db[server] = {}; |
|
84 if (!db[server][channel]) |
|
85 db[server][channel] = {}; |
|
86 if (!db[server][channel][nickname]) |
|
87 db[server][channel][nickname] = {}; |
|
88 |
|
89 return db; |
|
90 } |
|
91 |
|
92 function write(server, channel, nickname, message) |
|
93 { |
|
94 var db = read(server, channel, nickname); |
|
95 var entry = db[server][channel][nickname]; |
|
96 var p = path(server, channel); |
|
97 |
|
98 if (!File.exists(File.dirname(p))) { |
|
99 Logger.debug("creating directory " + File.dirname(p)); |
|
100 Directory.mkdir(File.dirname(p)); |
|
101 } |
|
102 |
|
103 var file = new File(path(server, channel), "wt"); |
|
104 |
|
105 entry.timestamp = Date.now(); |
|
106 entry.message = (message) ? message : entry.message; |
|
107 |
|
108 file.write(JSON.stringify(db)); |
|
109 } |
|
110 |
|
111 function find(server, channel, target) |
|
112 { |
|
113 var db = read(server, channel, target); |
|
114 var it = db[server][channel][target]; |
|
115 |
|
116 if (it.timestamp) |
|
117 return it; |
|
118 } |
|
119 |
|
120 function loadFormats() |
|
121 { |
|
122 for (var key in formats) { |
|
123 var optname = "format-" + key; |
|
124 |
|
125 if (typeof (Plugin.config[optname]) !== "string") |
|
126 continue; |
|
127 |
|
128 if (Plugin.config[optname].length === 0) |
|
129 Logger.warning("skipping empty '" + optname + "' format"); |
|
130 else |
|
131 formats[key] = Plugin.config[optname]; |
|
132 } |
|
133 } |
|
134 |
|
135 function onCommand(server, origin, channel, message) |
|
136 { |
|
137 var args = message.trim().split(" "); |
|
138 var kw = { |
|
139 "server": server.toString(), |
|
140 "channel": channel, |
|
141 "origin": origin, |
|
142 "nickname": Util.splituser(origin), |
|
143 "plugin": command(server), |
|
144 }; |
|
145 |
|
146 if (args.length !== 2 || args[0].length === 0 || args[1].length === 0) { |
|
147 server.message(channel, Util.format(formats.usage, kw)); |
|
148 return; |
|
149 } |
|
150 |
|
151 if (args[0] !== "seen" && args[0] !== "said") { |
|
152 server.message(channel, Util.format(formats.usage, kw)); |
|
153 return; |
|
154 } |
|
155 |
|
156 if (isSelf(server, args[1])) |
|
157 return; |
|
158 |
|
159 try { |
|
160 var info = find(server, channel, args[1]); |
|
161 |
|
162 kw.target = args[1]; |
|
163 |
|
164 if (!info) { |
|
165 server.message(channel, Util.format(formats.unknown, kw)); |
|
166 return; |
|
167 } |
|
168 |
|
169 kw.date = info.timestamp; |
|
170 kw.message = info.message ? info.message : ""; |
|
171 |
|
172 server.message(channel, Util.format(formats[args[0] == "seen" ? "seen" : "said"], kw)); |
|
173 } catch (e) { |
|
174 server.message(channel, Util.format(kw)); |
|
175 } |
|
176 } |
|
177 |
|
178 function onJoin(server, origin, channel) |
|
179 { |
|
180 write(server, channel, Util.splituser(origin)); |
|
181 } |
|
182 |
|
183 function onMessage(server, origin, channel, message) |
|
184 { |
|
185 write(server, channel, Util.splituser(origin), message); |
|
186 } |
|
187 |
|
188 onMe = onMessage; |
|
189 |
|
190 function onTopic(server, origin, channel) |
|
191 { |
|
192 write(server, channel, Util.splituser(origin)); |
|
193 } |
|
194 |
|
195 function onLoad() |
|
196 { |
|
197 var table = Server.list(); |
|
198 |
|
199 for (var k in table) |
|
200 for (var c in table[k].info().channels) |
|
201 table[k].names(c); |
|
202 |
|
203 loadFormats(); |
|
204 } |
|
205 |
|
206 function onReload() |
|
207 { |
|
208 loadFormats(); |
|
209 } |
|
210 |
|
211 function onNames(server, channel, list) |
|
212 { |
|
213 for (var i = 0; i < list.length; ++i) |
|
214 write(server, channel, list[i]); |
31
|
215 } |