Change favicon format to .ico. Small improvements to the script.
[KiwiIRC.git] / client / assets / 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
6 this.defaults = {\r
7 /**\r
8 * The name of the network\r
9 * @type String\r
10 */\r
11 name: 'Server',\r
12\r
13 /**\r
14 * The address (URL) of the network\r
15 * @type String\r
16 */\r
17 address: '',\r
18\r
19 /**\r
20 * The current nickname\r
21 * @type String\r
22 */\r
23 nick: '',\r
24\r
25 /**\r
26 * The channel prefix for this network\r
27 * @type String\r
28 */\r
29 channel_prefix: '#',\r
30\r
31 /**\r
32 * The user prefixes for channel owner/admin/op/voice etc. on this network\r
33 * @type Array\r
34 */\r
35 user_prefixes: ['~', '&', '@', '+'],\r
36\r
37 /**\r
38 * The URL to the Kiwi server\r
39 * @type String\r
40 */\r
f3091277
D
41 kiwi_server: '//kiwi',\r
42\r
43 /**\r
44 * List of nicks we are ignoring\r
45 * @type Array\r
46 */\r
47 ignore_list: []\r
696a66f8
D
48 };\r
49\r
50\r
51 this.initialize = function () {\r
52 that = this;\r
53 \r
54 // For ease of access. The socket.io object\r
55 this.socket = this.get('socket');\r
6228b635
D
56\r
57 this.applyEventHandlers();\r
58 };\r
59\r
60\r
61 this.applyEventHandlers = function () {\r
62 /*\r
a1629e09
D
63 kiwi.gateway.on('message:#channel', my_function);\r
64 kiwi.gateway.on('message:somenick', my_function);\r
6228b635
D
65\r
66 kiwi.gateway.on('notice:#channel', my_function);\r
67 kiwi.gateway.on('action:somenick', my_function);\r
68\r
69 kiwi.gateway.on('join:#channel', my_function);\r
70 kiwi.gateway.on('part:#channel', my_function);\r
71 kiwi.gateway.on('quit', my_function);\r
72 */\r
73 var that = this;\r
74 \r
75 // Some easier handler events\r
76 this.on('onmsg', function (event) {\r
77 var source,\r
fc9b83de
D
78 connection = _kiwi.app.connections.getByConnectionId(event.server),\r
79 is_pm = (event.channel == connection.get('nick'));\r
6228b635
D
80\r
81 source = is_pm ? event.nick : event.channel;\r
82 \r
8913f3ea
D
83 that.trigger('message:' + source, event);\r
84 that.trigger('message', event);\r
6228b635
D
85\r
86 if (is_pm) {\r
6228b635 87 that.trigger('pm:' + source, event);\r
8913f3ea 88 that.trigger('pm', event);\r
6228b635
D
89 }\r
90 }, this);\r
91\r
92\r
93 this.on('onnotice', function (event) {\r
94 // The notice towards a channel or a query window?\r
95 var source = event.target || event.nick;\r
96\r
6228b635 97 this.trigger('notice:' + source, event);\r
8913f3ea 98 this.trigger('notice', event);\r
6228b635
D
99 }, this);\r
100\r
101\r
102 this.on('onaction', function (event) {\r
103 var source,\r
fc9b83de 104 connection = _kiwi.app.connections.getByConnectionId(event.server),\r
444589dc 105 is_pm = (event.channel == connection.get('nick'));\r
6228b635
D
106\r
107 source = is_pm ? event.nick : event.channel;\r
108 \r
109 that.trigger('action:' + source, event);\r
110\r
111 if (is_pm) {\r
6228b635 112 that.trigger('action:' + source, event);\r
8913f3ea 113 that.trigger('action', event);\r
6228b635
D
114 }\r
115 }, this);\r
116\r
117\r
118 this.on('ontopic', function (event) {\r
6228b635 119 that.trigger('topic:' + event.channel, event);\r
8913f3ea 120 that.trigger('topic', event);\r
6228b635 121 });\r
22373da6
D
122\r
123\r
124 this.on('onjoin', function (event) {\r
125 that.trigger('join:' + event.channel, event);\r
126 that.trigger('join', event);\r
127 });\r
128\r
696a66f8
D
129 };\r
130\r
131\r
6228b635 132\r
696a66f8
D
133 /**\r
134 * Connects to the server\r
696a66f8
D
135 * @param {Function} callback A callback function to be invoked once Kiwi's server has connected to the IRC server\r
136 */\r
f2bb5380 137 this.connect = function (callback) {\r
8b0eb787
D
138 var resource;\r
139\r
140 // Work out the resource URL for socket.io\r
eaaf73b0
D
141 if (_kiwi.app.get('base_path').substr(0, 1) === '/') {\r
142 resource = _kiwi.app.get('base_path');\r
8b0eb787
D
143 resource = resource.substr(1, resource.length-1);\r
144 resource += '/transport';\r
145 } else {\r
eaaf73b0 146 resource = _kiwi.app.get('base_path') + '/transport';\r
8b0eb787
D
147 }\r
148\r
696a66f8 149 this.socket = io.connect(this.get('kiwi_server'), {\r
8b0eb787 150 'resource': resource,\r
f2bb5380 151\r
696a66f8
D
152 'try multiple transports': true,\r
153 'connect timeout': 3000,\r
154 'max reconnection attempts': 7,\r
155 'reconnection delay': 2000,\r
156 'sync disconnect on unload': false\r
157 });\r
158 this.socket.on('connect_failed', function (reason) {\r
696a66f8
D
159 this.socket.disconnect();\r
160 this.trigger("connect_fail", {reason: reason});\r
161 });\r
162\r
163 this.socket.on('error', function (e) {\r
eaaf73b0 164 console.log("_kiwi.gateway.socket.on('error')", {reason: e});\r
696a66f8
D
165 that.trigger("connect_fail", {reason: e});\r
166 });\r
167\r
168 this.socket.on('connecting', function (transport_type) {\r
eaaf73b0 169 console.log("_kiwi.gateway.socket.on('connecting')");\r
696a66f8
D
170 that.trigger("connecting");\r
171 });\r
172\r
173 /**\r
174 * Once connected to the kiwi server send the IRC connect command along\r
175 * with the IRC server details.\r
176 * A `connect` event is sent from the kiwi server once connected to the\r
177 * IRCD and the nick has been accepted.\r
178 */\r
179 this.socket.on('connect', function () {\r
f2bb5380 180 callback && callback();\r
2a27c998 181 /*\r
696a66f8
D
182 this.emit('kiwi', {command: 'connect', nick: that.get('nick'), hostname: host, port: port, ssl: ssl, password:password}, function (err, server_num) {\r
183 if (!err) {\r
184 that.server_num = server_num;\r
eaaf73b0 185 console.log("_kiwi.gateway.socket.on('connect')");\r
696a66f8 186 } else {\r
eaaf73b0 187 console.log("_kiwi.gateway.socket.on('error')", {reason: err});\r
d2d91c10 188 callback(err);\r
696a66f8
D
189 }\r
190 });\r
2a27c998 191 */\r
696a66f8
D
192 });\r
193\r
194 this.socket.on('too_many_connections', function () {\r
195 that.trigger("connect_fail", {reason: 'too_many_connections'});\r
196 });\r
197\r
198 this.socket.on('irc', function (data, callback) {\r
199 that.parse(data.command, data.data);\r
200 });\r
201\r
d2d91c10
D
202 this.socket.on('kiwi', function (data, callback) {\r
203 that.parseKiwi(data.command, data.data);\r
204 });\r
205\r
696a66f8
D
206 this.socket.on('disconnect', function () {\r
207 that.trigger("disconnect", {});\r
eaaf73b0 208 console.log("_kiwi.gateway.socket.on('disconnect')");\r
696a66f8
D
209 });\r
210\r
211 this.socket.on('close', function () {\r
eaaf73b0 212 console.log("_kiwi.gateway.socket.on('close')");\r
696a66f8
D
213 });\r
214\r
215 this.socket.on('reconnecting', function (reconnectionDelay, reconnectionAttempts) {\r
eaaf73b0 216 console.log("_kiwi.gateway.socket.on('reconnecting')");\r
696a66f8
D
217 that.trigger("reconnecting", {delay: reconnectionDelay, attempts: reconnectionAttempts});\r
218 });\r
219\r
220 this.socket.on('reconnect_failed', function () {\r
eaaf73b0 221 console.log("_kiwi.gateway.socket.on('reconnect_failed')");\r
696a66f8
D
222 });\r
223 };\r
224\r
225\r
226\r
2a27c998
D
227 this.newConnection = function(connection_info, callback_fn) {\r
228 var that = this,\r
229 h = connection_info;\r
230\r
231 this.socket.emit('kiwi', {command: 'connect', nick: h.nick, hostname: h.host, port: h.port, ssl: h.ssl, password: h.password}, function (err, server_num) {\r
c966123a
D
232 var connection;\r
233\r
2a27c998 234 if (!err) {\r
f2bb5380 235 if (!_kiwi.app.connections.getByConnectionId(server_num)){\r
3f78c3ce 236 connection = new _kiwi.model.Network({connection_id: server_num, nick: h.nick});\r
c966123a 237 _kiwi.app.connections.add(connection);\r
2a27c998
D
238 }\r
239\r
240 console.log("_kiwi.gateway.socket.on('connect')");\r
c966123a 241 callback_fn && callback_fn(err, connection);\r
c62a9570 242 \r
2a27c998
D
243 } else {\r
244 console.log("_kiwi.gateway.socket.on('error')", {reason: err});\r
245 callback_fn && callback_fn(err);\r
246 }\r
247 });\r
248 };\r
249\r
250\r
251\r
696a66f8
D
252 this.isConnected = function () {\r
253 return this.socket.socket.connected;\r
254 };\r
255\r
256\r
d2d91c10
D
257\r
258 this.parseKiwi = function (command, data) {\r
a1629e09
D
259 this.trigger('kiwi:' + command, data);\r
260 this.trigger('kiwi', data);\r
d2d91c10 261 };\r
696a66f8
D
262 /*\r
263 Events:\r
264 msg\r
265 action\r
266 server_connect\r
267 options\r
268 motd\r
269 notice\r
270 userlist\r
271 nick\r
272 join\r
273 topic\r
274 part\r
275 kick\r
276 quit\r
277 whois\r
278 syncchannel_redirect\r
279 debug\r
280 */\r
281 /**\r
282 * Parses the response from the server\r
283 */\r
284 this.parse = function (command, data) {\r
d2d91c10 285 //console.log('gateway event', command, data);\r
ce13508b 286\r
696a66f8 287 if (command !== undefined) {\r
696a66f8
D
288 switch (command) {\r
289 case 'options':\r
290 $.each(data.options, function (name, value) {\r
291 switch (name) {\r
292 case 'CHANTYPES':\r
d9e06c6e 293 that.set('channel_prefix', value.join(''));\r
696a66f8
D
294 break;\r
295 case 'NETWORK':\r
296 that.set('name', value);\r
297 break;\r
298 case 'PREFIX':\r
299 that.set('user_prefixes', value);\r
300 break;\r
301 }\r
302 });\r
dff8edba 303 that.set('cap', data.cap);\r
696a66f8
D
304 break;\r
305\r
696a66f8
D
306 /*\r
307 case 'sync':\r
eaaf73b0
D
308 if (_kiwi.gateway.onSync && _kiwi.gateway.syncing) {\r
309 _kiwi.gateway.syncing = false;\r
310 _kiwi.gateway.onSync(item);\r
696a66f8
D
311 }\r
312 break;\r
313 */\r
314\r
315 case 'kiwi':\r
eaaf73b0 316 this.emit('_kiwi.' + data.namespace, data.data);\r
696a66f8
D
317 break;\r
318 }\r
319 }\r
ce13508b
D
320\r
321\r
322 if (typeof data.server !== 'undefined') {\r
323 that.trigger('connection:' + data.server.toString(), {\r
324 event_name: command,\r
325 event_data: data\r
326 });\r
327 }\r
fc9b83de
D
328\r
329 // Trigger the global events (Mainly legacy now)\r
330 that.trigger('on' + command, data);\r
696a66f8
D
331 };\r
332\r
333 /**\r
334 * Sends data to the server\r
335 * @private\r
336 * @param {Object} data The data to send\r
337 * @param {Function} callback A callback function\r
338 */\r
e7d65587
D
339 this.sendData = function (connection_id, data, callback) {\r
340 if (typeof connection_id === 'undefined' || connection_id === null)\r
341 connection_id = _kiwi.app.connections.active_connection.get('connection_id');\r
342\r
2ffd1291 343 var data_buffer = {\r
e7d65587 344 server: connection_id,\r
2ffd1291
D
345 data: JSON.stringify(data)\r
346 };\r
2ffd1291 347 this.socket.emit('irc', data_buffer, callback);\r
696a66f8
D
348 };\r
349\r
350 /**\r
351 * Sends a PRIVMSG message\r
352 * @param {String} target The target of the message (e.g. a channel or nick)\r
353 * @param {String} msg The message to send\r
354 * @param {Function} callback A callback function\r
355 */\r
e7d65587 356 this.privmsg = function (connection_id, target, msg, callback) {\r
696a66f8
D
357 var data = {\r
358 method: 'privmsg',\r
359 args: {\r
360 target: target,\r
361 msg: msg\r
362 }\r
363 };\r
364\r
e7d65587 365 this.sendData(connection_id, data, callback);\r
696a66f8
D
366 };\r
367\r
368 /**\r
369 * Sends a NOTICE message\r
370 * @param {String} target The target of the message (e.g. a channel or nick)\r
371 * @param {String} msg The message to send\r
372 * @param {Function} callback A callback function\r
373 */\r
e7d65587 374 this.notice = function (connection_id, target, msg, callback) {\r
696a66f8
D
375 var data = {\r
376 method: 'notice',\r
377 args: {\r
378 target: target,\r
379 msg: msg\r
380 }\r
381 };\r
382\r
e7d65587 383 this.sendData(connection_id, data, callback);\r
696a66f8
D
384 };\r
385\r
386 /**\r
387 * Sends a CTCP message\r
388 * @param {Boolean} request Indicates whether this is a CTCP request (true) or reply (false)\r
389 * @param {String} type The type of CTCP message, e.g. 'VERSION', 'TIME', 'PING' etc.\r
390 * @param {String} target The target of the message, e.g a channel or nick\r
391 * @param {String} params Additional paramaters\r
392 * @param {Function} callback A callback function\r
393 */\r
e7d65587 394 this.ctcp = function (connection_id, request, type, target, params, callback) {\r
696a66f8
D
395 var data = {\r
396 method: 'ctcp',\r
397 args: {\r
398 request: request,\r
399 type: type,\r
400 target: target,\r
401 params: params\r
402 }\r
403 };\r
404\r
e7d65587 405 this.sendData(connection_id, data, callback);\r
696a66f8
D
406 };\r
407\r
408 /**\r
409 * @param {String} target The target of the message (e.g. a channel or nick)\r
410 * @param {String} msg The message to send\r
411 * @param {Function} callback A callback function\r
412 */\r
e7d65587 413 this.action = function (connection_id, target, msg, callback) {\r
11177392 414 this.ctcp(connection_id, true, 'ACTION', target, msg, callback);\r
696a66f8
D
415 };\r
416\r
417 /**\r
418 * Joins a channel\r
419 * @param {String} channel The channel to join\r
420 * @param {String} key The key to the channel\r
421 * @param {Function} callback A callback function\r
422 */\r
e7d65587 423 this.join = function (connection_id, channel, key, callback) {\r
696a66f8
D
424 var data = {\r
425 method: 'join',\r
426 args: {\r
427 channel: channel,\r
428 key: key\r
429 }\r
430 };\r
431\r
e7d65587 432 this.sendData(connection_id, data, callback);\r
696a66f8
D
433 };\r
434\r
435 /**\r
436 * Leaves a channel\r
437 * @param {String} channel The channel to part\r
438 * @param {Function} callback A callback function\r
439 */\r
e7d65587 440 this.part = function (connection_id, channel, callback) {\r
696a66f8
D
441 var data = {\r
442 method: 'part',\r
443 args: {\r
444 channel: channel\r
445 }\r
446 };\r
447\r
e7d65587 448 this.sendData(connection_id, data, callback);\r
696a66f8
D
449 };\r
450\r
451 /**\r
452 * Queries or modifies a channell topic\r
453 * @param {String} channel The channel to query or modify\r
454 * @param {String} new_topic The new topic to set\r
455 * @param {Function} callback A callback function\r
456 */\r
e7d65587 457 this.topic = function (connection_id, channel, new_topic, callback) {\r
696a66f8
D
458 var data = {\r
459 method: 'topic',\r
460 args: {\r
461 channel: channel,\r
462 topic: new_topic\r
463 }\r
464 };\r
465\r
e7d65587 466 this.sendData(connection_id, data, callback);\r
696a66f8
D
467 };\r
468\r
469 /**\r
470 * Kicks a user from a channel\r
471 * @param {String} channel The channel to kick the user from\r
472 * @param {String} nick The nick of the user to kick\r
473 * @param {String} reason The reason for kicking the user\r
474 * @param {Function} callback A callback function\r
475 */\r
e7d65587 476 this.kick = function (connection_id, channel, nick, reason, callback) {\r
696a66f8
D
477 var data = {\r
478 method: 'kick',\r
479 args: {\r
480 channel: channel,\r
481 nick: nick,\r
482 reason: reason\r
483 }\r
484 };\r
485\r
e7d65587 486 this.sendData(connection_id, data, callback);\r
696a66f8
D
487 };\r
488\r
489 /**\r
490 * Disconnects us from the server\r
491 * @param {String} msg The quit message to send to the IRC server\r
492 * @param {Function} callback A callback function\r
493 */\r
e7d65587 494 this.quit = function (connection_id, msg, callback) {\r
696a66f8
D
495 msg = msg || "";\r
496 var data = {\r
497 method: 'quit',\r
498 args: {\r
499 message: msg\r
500 }\r
501 };\r
502\r
e7d65587 503 this.sendData(connection_id, data, callback);\r
696a66f8
D
504 };\r
505\r
506 /**\r
507 * Sends a string unmodified to the IRC server\r
508 * @param {String} data The data to send to the IRC server\r
509 * @param {Function} callback A callback function\r
510 */\r
e7d65587 511 this.raw = function (connection_id, data, callback) {\r
696a66f8
D
512 data = {\r
513 method: 'raw',\r
514 args: {\r
515 data: data\r
516 }\r
517 };\r
518\r
e7d65587 519 this.sendData(connection_id, data, callback);\r
696a66f8
D
520 };\r
521\r
522 /**\r
523 * Changes our nickname\r
524 * @param {String} new_nick Our new nickname\r
525 * @param {Function} callback A callback function\r
526 */\r
e7d65587 527 this.changeNick = function (connection_id, new_nick, callback) {\r
696a66f8
D
528 var data = {\r
529 method: 'nick',\r
530 args: {\r
531 nick: new_nick\r
532 }\r
533 };\r
534\r
e7d65587 535 this.sendData(connection_id, data, callback);\r
696a66f8
D
536 };\r
537\r
538 /**\r
539 * Sends data to a fellow Kiwi IRC user\r
540 * @param {String} target The nick of the Kiwi IRC user to send to\r
541 * @param {String} data The data to send\r
542 * @param {Function} callback A callback function\r
543 */\r
544 this.kiwi = function (target, data, callback) {\r
545 data = {\r
546 method: 'kiwi',\r
547 args: {\r
548 target: target,\r
549 data: data\r
550 }\r
551 };\r
552\r
553 this.sendData(data, callback);\r
554 };\r
555\r
556\r
f3091277
D
557 // Check a nick alongside our ignore list\r
558 this.isNickIgnored = function (nick) {\r
559 var idx, list = this.get('ignore_list');\r
560 var pattern, regex;\r
561\r
562 for (idx = 0; idx < list.length; idx++) {\r
563 pattern = list[idx].replace(/([.+^$[\]\\(){}|-])/g, "\\$1")\r
564 .replace('*', '.*')\r
565 .replace('?', '.');\r
566\r
567 regex = new RegExp(pattern, 'i');\r
568 if (regex.test(nick)) return true;\r
569 }\r
570\r
571 return false;\r
4047ee2b 572 };\r
f3091277
D
573\r
574\r
696a66f8
D
575 return new (Backbone.Model.extend(this))(arguments);\r
576};