Merge pull request #548 from M2Ys4U/api-cleanup
[KiwiIRC.git] / client / src / models / gateway.js
CommitLineData
eaaf73b0 1_kiwi.model.Gateway = function () {\r
696a66f8
D
2\r
3 // Set to a reference to this object within initialize()\r
4 var that = null;\r
5\r
696a66f8
D
6 this.initialize = function () {\r
7 that = this;\r
09c26937 8\r
696a66f8
D
9 // For ease of access. The socket.io object\r
10 this.socket = this.get('socket');\r
6228b635 11\r
09c26937
D
12 // Used to check if a disconnection was unplanned\r
13 this.disconnect_requested = false;\r
6228b635
D
14 };\r
15\r
16\r
6228b635 17\r
09c26937 18 this.reconnect = function (callback) {\r
d6eec6ed
D
19 var that = this,\r
20 transport_path;\r
21\r
09c26937 22 this.disconnect_requested = true;\r
d99e7823
D
23 this.socket.close();\r
24\r
33432128 25 this.socket = null;\r
c6a65334 26 this.connect(callback);\r
09c26937
D
27 };\r
28\r
29\r
30\r
696a66f8
D
31 /**\r
32 * Connects to the server\r
696a66f8
D
33 * @param {Function} callback A callback function to be invoked once Kiwi's server has connected to the IRC server\r
34 */\r
f2bb5380 35 this.connect = function (callback) {\r
8cc59dbe
D
36 this.connect_callback = callback;\r
37\r
e5baa247
D
38 // Keep note of the server we are connecting to\r
39 this.set('kiwi_server', _kiwi.app.kiwi_server);\r
40\r
33432128 41 this.socket = new EngineioTools.ReconnectingSocket(this.get('kiwi_server'), {\r
9af18c41 42 transports: _kiwi.app.server_settings.transports || ['websocket', 'polling'],\r
d99e7823 43 path: _kiwi.app.get('base_path') + '/transport',\r
d99e7823
D
44 reconnect_max_attempts: 5,\r
45 reconnect_delay: 2000\r
46 });\r
8b0eb787 47\r
33432128 48 this.rpc = new EngineioTools.Rpc(this.socket);\r
f2bb5380 49\r
696a66f8 50 this.socket.on('connect_failed', function (reason) {\r
696a66f8
D
51 this.socket.disconnect();\r
52 this.trigger("connect_fail", {reason: reason});\r
53 });\r
54\r
55 this.socket.on('error', function (e) {\r
eaaf73b0 56 console.log("_kiwi.gateway.socket.on('error')", {reason: e});\r
28b4b095
D
57 if (that.connect_callback) {\r
58 that.connect_callback(e);\r
59 delete that.connect_callback;\r
60 }\r
61\r
696a66f8
D
62 that.trigger("connect_fail", {reason: e});\r
63 });\r
64\r
65 this.socket.on('connecting', function (transport_type) {\r
eaaf73b0 66 console.log("_kiwi.gateway.socket.on('connecting')");\r
696a66f8
D
67 that.trigger("connecting");\r
68 });\r
69\r
70 /**\r
71 * Once connected to the kiwi server send the IRC connect command along\r
72 * with the IRC server details.\r
73 * A `connect` event is sent from the kiwi server once connected to the\r
74 * IRCD and the nick has been accepted.\r
75 */\r
d99e7823 76 this.socket.on('open', function () {\r
09c26937
D
77 // Reset the disconnect_requested flag\r
78 that.disconnect_requested = false;\r
79\r
28635406 80 console.log("_kiwi.gateway.socket.on('open')");\r
696a66f8
D
81 });\r
82\r
d99e7823 83 this.rpc.on('too_many_connections', function () {\r
696a66f8
D
84 that.trigger("connect_fail", {reason: 'too_many_connections'});\r
85 });\r
86\r
d99e7823 87 this.rpc.on('irc', function (response, data) {\r
696a66f8
D
88 that.parse(data.command, data.data);\r
89 });\r
90\r
d99e7823 91 this.rpc.on('kiwi', function (response, data) {\r
d2d91c10
D
92 that.parseKiwi(data.command, data.data);\r
93 });\r
94\r
696a66f8 95 this.socket.on('close', function () {\r
d99e7823 96 that.trigger("disconnect", {});\r
eaaf73b0 97 console.log("_kiwi.gateway.socket.on('close')");\r
696a66f8
D
98 });\r
99\r
d99e7823 100 this.socket.on('reconnecting', function (status) {\r
eaaf73b0 101 console.log("_kiwi.gateway.socket.on('reconnecting')");\r
d99e7823 102 that.trigger("reconnecting", {delay: status.delay, attempts: status.attempts});\r
696a66f8
D
103 });\r
104\r
d99e7823 105 this.socket.on('reconnecting_failed', function () {\r
eaaf73b0 106 console.log("_kiwi.gateway.socket.on('reconnect_failed')");\r
696a66f8
D
107 });\r
108 };\r
109\r
110\r
d6eec6ed
D
111 /**\r
112 * Return a new network object with the new connection details\r
113 */\r
2a27c998 114 this.newConnection = function(connection_info, callback_fn) {\r
d6eec6ed 115 var that = this;\r
2a27c998 116\r
28b4b095
D
117 // If not connected, connect first then re-call this function\r
118 if (!this.isConnected()) {\r
119 this.connect(function(err) {\r
120 if (err) {\r
121 callback_fn(err);\r
122 return;\r
123 }\r
124\r
125 that.newConnection(connection_info, callback_fn);\r
126 });\r
127\r
128 return;\r
129 }\r
130\r
d6eec6ed 131 this.makeIrcConnection(connection_info, function(err, server_num) {\r
c966123a
D
132 var connection;\r
133\r
2a27c998 134 if (!err) {\r
f2bb5380 135 if (!_kiwi.app.connections.getByConnectionId(server_num)){\r
d6eec6ed
D
136 var inf = {\r
137 connection_id: server_num,\r
138 nick: connection_info.nick,\r
139 address: connection_info.host,\r
140 port: connection_info.port,\r
141 ssl: connection_info.ssl,\r
142 password: connection_info.password\r
143 };\r
144 connection = new _kiwi.model.Network(inf);\r
c966123a 145 _kiwi.app.connections.add(connection);\r
2a27c998
D
146 }\r
147\r
d6eec6ed 148 console.log("_kiwi.gateway.socket.on('connect')", connection);\r
c966123a 149 callback_fn && callback_fn(err, connection);\r
09c26937 150\r
2a27c998
D
151 } else {\r
152 console.log("_kiwi.gateway.socket.on('error')", {reason: err});\r
153 callback_fn && callback_fn(err);\r
154 }\r
155 });\r
156 };\r
157\r
d6eec6ed
D
158\r
159 /**\r
160 * Make a new IRC connection and return its connection ID\r
161 */\r
162 this.makeIrcConnection = function(connection_info, callback_fn) {\r
163 var server_info = {\r
d6eec6ed
D
164 nick: connection_info.nick,\r
165 hostname: connection_info.host,\r
166 port: connection_info.port,\r
167 ssl: connection_info.ssl,\r
168 password: connection_info.password\r
169 };\r
170\r
c6a65334
D
171 connection_info.options = connection_info.options || {};\r
172\r
cc54c0a1
D
173 // A few optional parameters\r
174 if (connection_info.options.encoding)\r
175 server_info.encoding = connection_info.options.encoding;\r
176\r
aae35fd3 177 this.rpc.call('kiwi.connect_irc', server_info, function (err, server_num) {\r
d6eec6ed
D
178 if (!err) {\r
179 callback_fn && callback_fn(err, server_num);\r
180\r
181 } else {\r
182 callback_fn && callback_fn(err);\r
183 }\r
184 });\r
185 };\r
186\r
187\r
696a66f8 188 this.isConnected = function () {\r
d99e7823
D
189 // TODO: Check this. Might want to use .readyState\r
190 return this.socket;\r
696a66f8
D
191 };\r
192\r
193\r
d2d91c10
D
194\r
195 this.parseKiwi = function (command, data) {\r
ac102e9d 196 var args;\r
9b95f5f1 197\r
8cc59dbe
D
198 switch (command) {\r
199 case 'connected':\r
9b95f5f1 200 // Send some info on this client to the server\r
ac102e9d 201 args = {\r
9b95f5f1
D
202 build_version: _kiwi.global.build_version\r
203 };\r
ac102e9d 204 this.rpc.call('kiwi.client_info', args);\r
9b95f5f1 205\r
8cc59dbe
D
206 this.connect_callback && this.connect_callback();\r
207 delete this.connect_callback;\r
9b95f5f1 208\r
8cc59dbe
D
209 break;\r
210 }\r
78354438
D
211\r
212 this.trigger('kiwi:' + command, data);\r
213 this.trigger('kiwi', data);\r
d2d91c10 214 };\r
ac102e9d 215\r
696a66f8
D
216 /**\r
217 * Parses the response from the server\r
218 */\r
219 this.parse = function (command, data) {\r
ce13508b 220\r
7aa19933 221 // Trigger the connection specific events (used by Network objects)\r
cbdab563
D
222 if (typeof data.connection_id !== 'undefined') {\r
223 that.trigger('connection:' + data.connection_id.toString(), {\r
ce13508b
D
224 event_name: command,\r
225 event_data: data\r
226 });\r
afcfe02c
D
227\r
228 // Some events trigger a more in-depth event name\r
229 if (command == 'message' && data.type) {\r
230 that.trigger('connection:' + data.connection_id.toString(), {\r
231 event_name: 'message:' + data.type,\r
232 event_data: data\r
233 });\r
c0bbfb79
D
234 }\r
235\r
236 if (command == 'channel' && data.type) {\r
237 that.trigger('connection:' + data.connection_id.toString(), {\r
238 event_name: 'channel:' + data.type,\r
239 event_data: data\r
240 });\r
afcfe02c 241 }\r
ce13508b 242 }\r
fc9b83de 243\r
7aa19933
D
244 // Trigger the global events\r
245 that.trigger(command, data);\r
696a66f8
D
246 };\r
247\r
ac102e9d
D
248 this.rpcCall = function(method, connection_id) {\r
249 var args = Array.prototype.slice.call(arguments, 0);\r
e7d65587 250\r
ac102e9d
D
251 if (typeof args[1] === 'undefined' || args[1] === null)\r
252 args[1] = _kiwi.app.connections.active_connection.get('connection_id');\r
253\r
254 return this.rpc.call.apply(this.rpc, args);\r
696a66f8
D
255 };\r
256\r
257 /**\r
258 * Sends a PRIVMSG message\r
259 * @param {String} target The target of the message (e.g. a channel or nick)\r
260 * @param {String} msg The message to send\r
261 * @param {Function} callback A callback function\r
262 */\r
e7d65587 263 this.privmsg = function (connection_id, target, msg, callback) {\r
ac102e9d
D
264 var args = {\r
265 target: target,\r
266 msg: msg\r
696a66f8
D
267 };\r
268\r
ac102e9d 269 this.rpcCall('irc.privmsg', connection_id, args, callback);\r
696a66f8
D
270 };\r
271\r
272 /**\r
273 * Sends a NOTICE message\r
274 * @param {String} target The target of the message (e.g. a channel or nick)\r
275 * @param {String} msg The message to send\r
276 * @param {Function} callback A callback function\r
277 */\r
e7d65587 278 this.notice = function (connection_id, target, msg, callback) {\r
ac102e9d
D
279 var args = {\r
280 target: target,\r
281 msg: msg\r
696a66f8
D
282 };\r
283\r
ac102e9d 284 this.rpcCall('irc.notice', connection_id, args, callback);\r
696a66f8
D
285 };\r
286\r
287 /**\r
288 * Sends a CTCP message\r
289 * @param {Boolean} request Indicates whether this is a CTCP request (true) or reply (false)\r
290 * @param {String} type The type of CTCP message, e.g. 'VERSION', 'TIME', 'PING' etc.\r
291 * @param {String} target The target of the message, e.g a channel or nick\r
292 * @param {String} params Additional paramaters\r
293 * @param {Function} callback A callback function\r
294 */\r
d07c8435 295 this.ctcp = function (connection_id, is_request, type, target, params, callback) {\r
ac102e9d 296 var args = {\r
d07c8435 297 is_request: is_request,\r
ac102e9d
D
298 type: type,\r
299 target: target,\r
300 params: params\r
696a66f8
D
301 };\r
302\r
ac102e9d 303 this.rpcCall('irc.ctcp', connection_id, args, callback);\r
696a66f8
D
304 };\r
305\r
d07c8435
D
306 this.ctcpRequest = function (connection_id, type, target, params, callback) {\r
307 this.ctcp(connection_id, true, type, target, params, callback);\r
308 };\r
309 this.ctcpResponse = function (connection_id, type, target, params, callback) {\r
310 this.ctcp(connection_id, false, type, target, params, callback);\r
311 };\r
312\r
696a66f8
D
313 /**\r
314 * @param {String} target The target of the message (e.g. a channel or nick)\r
315 * @param {String} msg The message to send\r
316 * @param {Function} callback A callback function\r
317 */\r
e7d65587 318 this.action = function (connection_id, target, msg, callback) {\r
11177392 319 this.ctcp(connection_id, true, 'ACTION', target, msg, callback);\r
696a66f8
D
320 };\r
321\r
322 /**\r
323 * Joins a channel\r
324 * @param {String} channel The channel to join\r
325 * @param {String} key The key to the channel\r
326 * @param {Function} callback A callback function\r
327 */\r
e7d65587 328 this.join = function (connection_id, channel, key, callback) {\r
ac102e9d
D
329 var args = {\r
330 channel: channel,\r
331 key: key\r
696a66f8
D
332 };\r
333\r
ac102e9d 334 this.rpcCall('irc.join', connection_id, args, callback);\r
696a66f8
D
335 };\r
336\r
72db27e4
D
337 /**\r
338 * Retrieves channel information\r
339 */\r
340 this.channelInfo = function (connection_id, channel, callback) {\r
ac102e9d
D
341 var args = {\r
342 channel: channel\r
72db27e4
D
343 };\r
344\r
ac102e9d 345 this.rpcCall('irc.channel_info', connection_id, args, callback);\r
72db27e4
D
346 };\r
347\r
696a66f8
D
348 /**\r
349 * Leaves a channel\r
350 * @param {String} channel The channel to part\r
7f272ac9 351 * @param {String} message Optional part message\r
696a66f8
D
352 * @param {Function} callback A callback function\r
353 */\r
7f272ac9
JA
354 this.part = function (connection_id, channel, message, callback) {\r
355 "use strict";\r
356\r
357 // The message param is optional, so juggle args if it is missing\r
358 if (typeof arguments[2] === 'function') {\r
359 callback = arguments[2];\r
360 message = undefined;\r
361 }\r
ac102e9d 362 var args = {\r
7f272ac9
JA
363 channel: channel,\r
364 message: message\r
696a66f8
D
365 };\r
366\r
ac102e9d 367 this.rpcCall('irc.part', connection_id, args, callback);\r
696a66f8
D
368 };\r
369\r
370 /**\r
371 * Queries or modifies a channell topic\r
372 * @param {String} channel The channel to query or modify\r
373 * @param {String} new_topic The new topic to set\r
374 * @param {Function} callback A callback function\r
375 */\r
e7d65587 376 this.topic = function (connection_id, channel, new_topic, callback) {\r
ac102e9d
D
377 var args = {\r
378 channel: channel,\r
379 topic: new_topic\r
696a66f8
D
380 };\r
381\r
ac102e9d 382 this.rpcCall('irc.topic', connection_id, args, callback);\r
696a66f8
D
383 };\r
384\r
385 /**\r
386 * Kicks a user from a channel\r
387 * @param {String} channel The channel to kick the user from\r
388 * @param {String} nick The nick of the user to kick\r
389 * @param {String} reason The reason for kicking the user\r
390 * @param {Function} callback A callback function\r
391 */\r
e7d65587 392 this.kick = function (connection_id, channel, nick, reason, callback) {\r
ac102e9d
D
393 var args = {\r
394 channel: channel,\r
395 nick: nick,\r
396 reason: reason\r
696a66f8
D
397 };\r
398\r
ac102e9d 399 this.rpcCall('irc.kick', connection_id, args, callback);\r
696a66f8
D
400 };\r
401\r
402 /**\r
403 * Disconnects us from the server\r
404 * @param {String} msg The quit message to send to the IRC server\r
405 * @param {Function} callback A callback function\r
406 */\r
e7d65587 407 this.quit = function (connection_id, msg, callback) {\r
696a66f8 408 msg = msg || "";\r
ac102e9d
D
409\r
410 var args = {\r
411 message: msg\r
696a66f8
D
412 };\r
413\r
ac102e9d 414 this.rpcCall('irc.quit', connection_id, args, callback);\r
696a66f8
D
415 };\r
416\r
417 /**\r
418 * Sends a string unmodified to the IRC server\r
419 * @param {String} data The data to send to the IRC server\r
420 * @param {Function} callback A callback function\r
421 */\r
e7d65587 422 this.raw = function (connection_id, data, callback) {\r
ac102e9d
D
423 var args = {\r
424 data: data\r
696a66f8
D
425 };\r
426\r
ac102e9d 427 this.rpcCall('irc.raw', connection_id, args, callback);\r
696a66f8
D
428 };\r
429\r
430 /**\r
431 * Changes our nickname\r
432 * @param {String} new_nick Our new nickname\r
433 * @param {Function} callback A callback function\r
434 */\r
e7d65587 435 this.changeNick = function (connection_id, new_nick, callback) {\r
ac102e9d
D
436 var args = {\r
437 nick: new_nick\r
696a66f8
D
438 };\r
439\r
ac102e9d 440 this.rpcCall('irc.nick', connection_id, args, callback);\r
696a66f8
D
441 };\r
442\r
72db27e4
D
443 /**\r
444 * Sets a mode for a target\r
445 */\r
446 this.mode = function (connection_id, target, mode_string, callback) {\r
ac102e9d
D
447 var args = {\r
448 data: 'MODE ' + target + ' ' + mode_string\r
72db27e4
D
449 };\r
450\r
ac102e9d 451 this.rpcCall('irc.raw', connection_id, args, callback);\r
72db27e4
D
452 };\r
453\r
d1b3e8b3
VDF
454 /**\r
455 * Sends ENCODING change request to server.\r
456 * @param {String} new_encoding The new proposed encode\r
457 * @param {Fucntion} callback A callback function\r
458 */\r
459 this.setEncoding = function (connection_id, new_encoding, callback) {\r
ac102e9d
D
460 var args = {\r
461 encoding: new_encoding\r
696a66f8
D
462 };\r
463\r
ac102e9d 464 this.rpcCall('irc.encoding', connection_id, args, callback);\r
696a66f8 465 };\r
5bede446 466\r
f3091277 467\r
696a66f8 468 return new (Backbone.Model.extend(this))(arguments);\r
d1b3e8b3 469};\r