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