Updated client codebase
[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
52
53 /**
54 * Connects to the server
55 * @param {String} host The hostname or IP address of the IRC server to connect to
56 * @param {Number} port The port of the IRC server to connect to
57 * @param {Boolean} ssl Whether or not to connect to the IRC server using SSL
58 * @param {String} password The password to supply to the IRC server during registration
59 * @param {Function} callback A callback function to be invoked once Kiwi's server has connected to the IRC server
60 */
61 this.connect = function (host, port, ssl, password, callback) {
62 this.socket = io.connect(this.get('kiwi_server'), {
63 'try multiple transports': true,
64 'connect timeout': 3000,
65 'max reconnection attempts': 7,
66 'reconnection delay': 2000,
67 'sync disconnect on unload': false
68 });
69 this.socket.on('connect_failed', function (reason) {
70 // TODO: When does this even actually get fired? I can't find a case! ~Darren
71 console.debug('Unable to connect Socket.IO', reason);
72 console.log("kiwi.gateway.socket.on('connect_failed')");
73 //kiwi.front.tabviews.server.addMsg(null, ' ', 'Unable to connect to Kiwi IRC.\n' + reason, 'error');
74 this.socket.disconnect();
75 this.trigger("connect_fail", {reason: reason});
76 });
77
78 this.socket.on('error', function (e) {
79 console.log("kiwi.gateway.socket.on('error')", {reason: e});
80 that.trigger("connect_fail", {reason: e});
81 });
82
83 this.socket.on('connecting', function (transport_type) {
84 console.log("kiwi.gateway.socket.on('connecting')");
85 that.trigger("connecting");
86 });
87
88 /**
89 * Once connected to the kiwi server send the IRC connect command along
90 * with the IRC server details.
91 * A `connect` event is sent from the kiwi server once connected to the
92 * IRCD and the nick has been accepted.
93 */
94 this.socket.on('connect', function () {
95 this.emit('kiwi', {command: 'connect', nick: that.get('nick'), hostname: host, port: port, ssl: ssl, password:password}, function (err, server_num) {
96 if (!err) {
97 that.server_num = server_num;
98 console.log("kiwi.gateway.socket.on('connect')");
99 } else {
100 console.log("kiwi.gateway.socket.on('error')", {reason: err});
101 }
102 });
103 });
104
105 this.socket.on('too_many_connections', function () {
106 that.trigger("connect_fail", {reason: 'too_many_connections'});
107 });
108
109 this.socket.on('irc', function (data, callback) {
110 that.parse(data.command, data.data);
111 });
112
113 this.socket.on('disconnect', function () {
114 that.trigger("disconnect", {});
115 console.log("kiwi.gateway.socket.on('disconnect')");
116 });
117
118 this.socket.on('close', function () {
119 console.log("kiwi.gateway.socket.on('close')");
120 });
121
122 this.socket.on('reconnecting', function (reconnectionDelay, reconnectionAttempts) {
123 console.log("kiwi.gateway.socket.on('reconnecting')");
124 that.trigger("reconnecting", {delay: reconnectionDelay, attempts: reconnectionAttempts});
125 });
126
127 this.socket.on('reconnect_failed', function () {
128 console.log("kiwi.gateway.socket.on('reconnect_failed')");
129 });
130 };
131
132
133
134 this.isConnected = function () {
135 return this.socket.socket.connected;
136 };
137
138
139 /*
140 Events:
141 msg
142 action
143 server_connect
144 options
145 motd
146 notice
147 userlist
148 nick
149 join
150 topic
151 part
152 kick
153 quit
154 whois
155 syncchannel_redirect
156 debug
157 */
158 /**
159 * Parses the response from the server
160 */
161 this.parse = function (command, data) {
162 console.log('gateway event', command, data);
163 if (command !== undefined) {
164 that.trigger('on' + command, data);
165
166 switch (command) {
167 case 'options':
168 $.each(data.options, function (name, value) {
169 switch (name) {
170 case 'CHANTYPES':
171 // TODO: Check this. Why is it only getting the first char?
172 that.set('channel_prefix', value.join('').charAt(0));
173 break;
174 case 'NETWORK':
175 that.set('name', value);
176 break;
177 case 'PREFIX':
178 that.set('user_prefixes', value);
179 break;
180 }
181 });
182 break;
183
184 case 'connect':
185 that.set('nick', data.nick);
186 break;
187
188 case 'nick':
189 if (data.nick === that.get('nick')) {
190 that.set('nick', data.newnick);
191 }
192 break;
193 /*
194 case 'sync':
195 if (kiwi.gateway.onSync && kiwi.gateway.syncing) {
196 kiwi.gateway.syncing = false;
197 kiwi.gateway.onSync(item);
198 }
199 break;
200 */
201
202 case 'kiwi':
203 this.emit('kiwi.' + data.namespace, data.data);
204 break;
205 }
206 }
207 };
208
209 /**
210 * Sends data to the server
211 * @private
212 * @param {Object} data The data to send
213 * @param {Function} callback A callback function
214 */
215 this.sendData = function (data, callback) {
216 this.socket.emit('irc', {server: 0, data: JSON.stringify(data)}, callback);
217 };
218
219 /**
220 * Sends a PRIVMSG message
221 * @param {String} target The target of the message (e.g. a channel or nick)
222 * @param {String} msg The message to send
223 * @param {Function} callback A callback function
224 */
225 this.privmsg = function (target, msg, callback) {
226 var data = {
227 method: 'privmsg',
228 args: {
229 target: target,
230 msg: msg
231 }
232 };
233
234 this.sendData(data, callback);
235 };
236
237 /**
238 * Sends a NOTICE message
239 * @param {String} target The target of the message (e.g. a channel or nick)
240 * @param {String} msg The message to send
241 * @param {Function} callback A callback function
242 */
243 this.notice = function (target, msg, callback) {
244 var data = {
245 method: 'notice',
246 args: {
247 target: target,
248 msg: msg
249 }
250 };
251
252 this.sendData(data, callback);
253 };
254
255 /**
256 * Sends a CTCP message
257 * @param {Boolean} request Indicates whether this is a CTCP request (true) or reply (false)
258 * @param {String} type The type of CTCP message, e.g. 'VERSION', 'TIME', 'PING' etc.
259 * @param {String} target The target of the message, e.g a channel or nick
260 * @param {String} params Additional paramaters
261 * @param {Function} callback A callback function
262 */
263 this.ctcp = function (request, type, target, params, callback) {
264 var data = {
265 method: 'ctcp',
266 args: {
267 request: request,
268 type: type,
269 target: target,
270 params: params
271 }
272 };
273
274 this.sendData(data, callback);
275 };
276
277 /**
278 * @param {String} target The target of the message (e.g. a channel or nick)
279 * @param {String} msg The message to send
280 * @param {Function} callback A callback function
281 */
282 this.action = function (target, msg, callback) {
283 this.ctcp(true, 'ACTION', target, msg, callback);
284 };
285
286 /**
287 * Joins a channel
288 * @param {String} channel The channel to join
289 * @param {String} key The key to the channel
290 * @param {Function} callback A callback function
291 */
292 this.join = function (channel, key, callback) {
293 var data = {
294 method: 'join',
295 args: {
296 channel: channel,
297 key: key
298 }
299 };
300
301 this.sendData(data, callback);
302 };
303
304 /**
305 * Leaves a channel
306 * @param {String} channel The channel to part
307 * @param {Function} callback A callback function
308 */
309 this.part = function (channel, callback) {
310 var data = {
311 method: 'part',
312 args: {
313 channel: channel
314 }
315 };
316
317 this.sendData(data, callback);
318 };
319
320 /**
321 * Queries or modifies a channell topic
322 * @param {String} channel The channel to query or modify
323 * @param {String} new_topic The new topic to set
324 * @param {Function} callback A callback function
325 */
326 this.topic = function (channel, new_topic, callback) {
327 var data = {
328 method: 'topic',
329 args: {
330 channel: channel,
331 topic: new_topic
332 }
333 };
334
335 this.sendData(data, callback);
336 };
337
338 /**
339 * Kicks a user from a channel
340 * @param {String} channel The channel to kick the user from
341 * @param {String} nick The nick of the user to kick
342 * @param {String} reason The reason for kicking the user
343 * @param {Function} callback A callback function
344 */
345 this.kick = function (channel, nick, reason, callback) {
346 var data = {
347 method: 'kick',
348 args: {
349 channel: channel,
350 nick: nick,
351 reason: reason
352 }
353 };
354
355 this.sendData(data, callback);
356 };
357
358 /**
359 * Disconnects us from the server
360 * @param {String} msg The quit message to send to the IRC server
361 * @param {Function} callback A callback function
362 */
363 this.quit = function (msg, callback) {
364 msg = msg || "";
365 var data = {
366 method: 'quit',
367 args: {
368 message: msg
369 }
370 };
371
372 this.sendData(data, callback);
373 };
374
375 /**
376 * Sends a string unmodified to the IRC server
377 * @param {String} data The data to send to the IRC server
378 * @param {Function} callback A callback function
379 */
380 this.raw = function (data, callback) {
381 data = {
382 method: 'raw',
383 args: {
384 data: data
385 }
386 };
387
388 this.sendData(data, callback);
389 };
390
391 /**
392 * Changes our nickname
393 * @param {String} new_nick Our new nickname
394 * @param {Function} callback A callback function
395 */
396 this.changeNick = function (new_nick, callback) {
397 var data = {
398 method: 'nick',
399 args: {
400 nick: new_nick
401 }
402 };
403
404 this.sendData(data, callback);
405 };
406
407 /**
408 * Sends data to a fellow Kiwi IRC user
409 * @param {String} target The nick of the Kiwi IRC user to send to
410 * @param {String} data The data to send
411 * @param {Function} callback A callback function
412 */
413 this.kiwi = function (target, data, callback) {
414 data = {
415 method: 'kiwi',
416 args: {
417 target: target,
418 data: data
419 }
420 };
421
422 this.sendData(data, callback);
423 };
424
425
426 return new (Backbone.Model.extend(this))(arguments);
427 };