1 _kiwi
.model
.Gateway = function () {
3 // Set to a reference to this object within initialize()
6 this.initialize = function () {
9 // For ease of access. The socket.io object
10 this.socket
= this.get('socket');
12 // Used to check if a disconnection was unplanned
13 this.disconnect_requested
= false;
18 this.reconnect = function (callback
) {
22 this.disconnect_requested
= true;
26 this.connect(callback
);
32 * Connects to the server
33 * @param {Function} callback A callback function to be invoked once Kiwi's server has connected to the IRC server
35 this.connect = function (callback
) {
36 this.connect_callback
= callback
;
38 // Keep note of the server we are connecting to
39 this.set('kiwi_server', _kiwi
.app
.kiwi_server
);
41 this.socket
= new EngineioTools
.ReconnectingSocket(this.get('kiwi_server'), {
42 transports
: _kiwi
.app
.server_settings
.transports
|| ['polling', 'websocket'],
43 path
: _kiwi
.app
.get('base_path') + '/transport',
44 reconnect_max_attempts
: 5,
48 this.rpc
= new EngineioTools
.Rpc(this.socket
);
50 this.socket
.on('connect_failed', function (reason
) {
51 this.socket
.disconnect();
52 this.trigger("connect_fail", {reason
: reason
});
55 this.socket
.on('error', function (e
) {
56 console
.log("_kiwi.gateway.socket.on('error')", {reason
: e
});
57 if (that
.connect_callback
) {
58 that
.connect_callback(e
);
59 delete that
.connect_callback
;
62 that
.trigger("connect_fail", {reason
: e
});
65 this.socket
.on('connecting', function (transport_type
) {
66 console
.log("_kiwi.gateway.socket.on('connecting')");
67 that
.trigger("connecting");
71 * Once connected to the kiwi server send the IRC connect command along
72 * with the IRC server details.
73 * A `connect` event is sent from the kiwi server once connected to the
74 * IRCD and the nick has been accepted.
76 this.socket
.on('open', function () {
77 // Reset the disconnect_requested flag
78 that
.disconnect_requested
= false;
80 console
.log("_kiwi.gateway.socket.on('open')");
83 this.rpc
.on('too_many_connections', function () {
84 that
.trigger("connect_fail", {reason
: 'too_many_connections'});
87 this.rpc
.on('irc', function (response
, data
) {
88 that
.parse(data
.command
, data
.data
);
91 this.rpc
.on('kiwi', function (response
, data
) {
92 that
.parseKiwi(data
.command
, data
.data
);
95 this.socket
.on('close', function () {
96 that
.trigger("disconnect", {});
97 console
.log("_kiwi.gateway.socket.on('close')");
100 this.socket
.on('reconnecting', function (status
) {
101 console
.log("_kiwi.gateway.socket.on('reconnecting')");
102 that
.trigger("reconnecting", {delay
: status
.delay
, attempts
: status
.attempts
});
105 this.socket
.on('reconnecting_failed', function () {
106 console
.log("_kiwi.gateway.socket.on('reconnect_failed')");
112 * Return a new network object with the new connection details
114 this.newConnection = function(connection_info
, callback_fn
) {
117 // If not connected, connect first then re-call this function
118 if (!this.isConnected()) {
119 this.connect(function(err
) {
125 that
.newConnection(connection_info
, callback_fn
);
131 this.makeIrcConnection(connection_info
, function(err
, server_num
) {
135 if (!_kiwi
.app
.connections
.getByConnectionId(server_num
)){
137 connection_id
: server_num
,
138 nick
: connection_info
.nick
,
139 address
: connection_info
.host
,
140 port
: connection_info
.port
,
141 ssl
: connection_info
.ssl
,
142 password
: connection_info
.password
144 connection
= new _kiwi
.model
.Network(inf
);
145 _kiwi
.app
.connections
.add(connection
);
148 console
.log("_kiwi.gateway.socket.on('connect')", connection
);
149 callback_fn
&& callback_fn(err
, connection
);
152 console
.log("_kiwi.gateway.socket.on('error')", {reason
: err
});
153 callback_fn
&& callback_fn(err
);
160 * Make a new IRC connection and return its connection ID
162 this.makeIrcConnection = function(connection_info
, callback_fn
) {
164 nick
: connection_info
.nick
,
165 hostname
: connection_info
.host
,
166 port
: connection_info
.port
,
167 ssl
: connection_info
.ssl
,
168 password
: connection_info
.password
171 connection_info
.options
= connection_info
.options
|| {};
173 // A few optional parameters
174 if (connection_info
.options
.encoding
)
175 server_info
.encoding
= connection_info
.options
.encoding
;
177 this.rpc
.call('kiwi.connect_irc', server_info
, function (err
, server_num
) {
179 callback_fn
&& callback_fn(err
, server_num
);
182 callback_fn
&& callback_fn(err
);
188 this.isConnected = function () {
189 // TODO: Check this. Might want to use .readyState
195 this.parseKiwi = function (command
, data
) {
200 // Send some info on this client to the server
202 build_version
: _kiwi
.global
.build_version
204 this.rpc
.call('kiwi.client_info', args
);
206 this.connect_callback
&& this.connect_callback();
207 delete this.connect_callback
;
212 this.trigger('kiwi:' + command
, data
);
213 this.trigger('kiwi', data
);
217 * Parses the response from the server
219 this.parse = function (command
, data
) {
221 // Trigger the connection specific events (used by Network objects)
222 if (typeof data
.connection_id
!== 'undefined') {
223 that
.trigger('connection:' + data
.connection_id
.toString(), {
228 // Some events trigger a more in-depth event name
229 if (command
== 'message' && data
.type
) {
230 that
.trigger('connection:' + data
.connection_id
.toString(), {
231 event_name
: 'message:' + data
.type
,
236 if (command
== 'channel' && data
.type
) {
237 that
.trigger('connection:' + data
.connection_id
.toString(), {
238 event_name
: 'channel:' + data
.type
,
244 // Trigger the global events
245 that
.trigger('connection', {event_name
: command
, event_data
: data
});
246 that
.trigger('connection:' + command
, data
);
249 this.rpcCall = function(method
, connection_id
) {
250 var args
= Array
.prototype.slice
.call(arguments
, 0);
252 if (typeof args
[1] === 'undefined' || args
[1] === null)
253 args
[1] = _kiwi
.app
.connections
.active_connection
.get('connection_id');
255 return this.rpc
.call
.apply(this.rpc
, args
);
259 * Sends a PRIVMSG message
260 * @param {String} target The target of the message (e.g. a channel or nick)
261 * @param {String} msg The message to send
262 * @param {Function} callback A callback function
264 this.privmsg = function (connection_id
, target
, msg
, callback
) {
270 this.rpcCall('irc.privmsg', connection_id
, args
, callback
);
274 * Sends a NOTICE message
275 * @param {String} target The target of the message (e.g. a channel or nick)
276 * @param {String} msg The message to send
277 * @param {Function} callback A callback function
279 this.notice = function (connection_id
, target
, msg
, callback
) {
285 this.rpcCall('irc.notice', connection_id
, args
, callback
);
289 * Sends a CTCP message
290 * @param {Boolean} request Indicates whether this is a CTCP request (true) or reply (false)
291 * @param {String} type The type of CTCP message, e.g. 'VERSION', 'TIME', 'PING' etc.
292 * @param {String} target The target of the message, e.g a channel or nick
293 * @param {String} params Additional paramaters
294 * @param {Function} callback A callback function
296 this.ctcp = function (connection_id
, is_request
, type
, target
, params
, callback
) {
298 is_request
: is_request
,
304 this.rpcCall('irc.ctcp', connection_id
, args
, callback
);
307 this.ctcpRequest = function (connection_id
, type
, target
, params
, callback
) {
308 this.ctcp(connection_id
, true, type
, target
, params
, callback
);
310 this.ctcpResponse = function (connection_id
, type
, target
, params
, callback
) {
311 this.ctcp(connection_id
, false, type
, target
, params
, callback
);
315 * @param {String} target The target of the message (e.g. a channel or nick)
316 * @param {String} msg The message to send
317 * @param {Function} callback A callback function
319 this.action = function (connection_id
, target
, msg
, callback
) {
320 this.ctcp(connection_id
, true, 'ACTION', target
, msg
, callback
);
325 * @param {String} channel The channel to join
326 * @param {String} key The key to the channel
327 * @param {Function} callback A callback function
329 this.join = function (connection_id
, channel
, key
, callback
) {
335 this.rpcCall('irc.join', connection_id
, args
, callback
);
339 * Retrieves channel information
341 this.channelInfo = function (connection_id
, channel
, callback
) {
346 this.rpcCall('irc.channel_info', connection_id
, args
, callback
);
351 * @param {String} channel The channel to part
352 * @param {String} message Optional part message
353 * @param {Function} callback A callback function
355 this.part = function (connection_id
, channel
, message
, callback
) {
358 // The message param is optional, so juggle args if it is missing
359 if (typeof arguments
[2] === 'function') {
360 callback
= arguments
[2];
368 this.rpcCall('irc.part', connection_id
, args
, callback
);
372 * Queries or modifies a channell topic
373 * @param {String} channel The channel to query or modify
374 * @param {String} new_topic The new topic to set
375 * @param {Function} callback A callback function
377 this.topic = function (connection_id
, channel
, new_topic
, callback
) {
383 this.rpcCall('irc.topic', connection_id
, args
, callback
);
387 * Kicks a user from a channel
388 * @param {String} channel The channel to kick the user from
389 * @param {String} nick The nick of the user to kick
390 * @param {String} reason The reason for kicking the user
391 * @param {Function} callback A callback function
393 this.kick = function (connection_id
, channel
, nick
, reason
, callback
) {
400 this.rpcCall('irc.kick', connection_id
, args
, callback
);
404 * Disconnects us from the server
405 * @param {String} msg The quit message to send to the IRC server
406 * @param {Function} callback A callback function
408 this.quit = function (connection_id
, msg
, callback
) {
415 this.rpcCall('irc.quit', connection_id
, args
, callback
);
419 * Sends a string unmodified to the IRC server
420 * @param {String} data The data to send to the IRC server
421 * @param {Function} callback A callback function
423 this.raw = function (connection_id
, data
, callback
) {
428 this.rpcCall('irc.raw', connection_id
, args
, callback
);
432 * Changes our nickname
433 * @param {String} new_nick Our new nickname
434 * @param {Function} callback A callback function
436 this.changeNick = function (connection_id
, new_nick
, callback
) {
441 this.rpcCall('irc.nick', connection_id
, args
, callback
);
445 * Sets a mode for a target
447 this.mode = function (connection_id
, target
, mode_string
, callback
) {
449 data
: 'MODE ' + target
+ ' ' + mode_string
452 this.rpcCall('irc.raw', connection_id
, args
, callback
);
456 * Sends ENCODING change request to server.
457 * @param {String} new_encoding The new proposed encode
458 * @param {Fucntion} callback A callback function
460 this.setEncoding = function (connection_id
, new_encoding
, callback
) {
462 encoding
: new_encoding
465 this.rpcCall('irc.encoding', connection_id
, args
, callback
);
469 return new (Backbone
.Model
.extend(this))(arguments
);