Joining multiple channels; Checking for active channel before re-creating
authorDarren <darren@darrenwhitlen.com>
Sat, 25 Aug 2012 20:03:08 +0000 (21:03 +0100)
committerDarren <darren@darrenwhitlen.com>
Sat, 25 Aug 2012 20:03:08 +0000 (21:03 +0100)
client_backbone/model_application.js
client_backbone/model_gateway.js

index 74c6a518d1a80c08c100490e74e3fba455282c68..080537ca25123c459b939b63fc53f8039b1bc4a8 100644 (file)
@@ -235,10 +235,26 @@ kiwi.model.Application = Backbone.Model.extend(new (function () {
     };\r
 \r
     this.joinCommand = function (ev) {\r
-        var c = new kiwi.model.Channel({name: ev.params[0]});\r
-        kiwi.app.panels.add(c);\r
-        c.view.show();\r
-        kiwi.gateway.join(ev.params[0]);\r
+        var channel, channel_names;\r
+\r
+        channel_names = ev.params.join(' ').split(',');\r
+\r
+        $.each(channel_names, function (index, channel_name) {\r
+            // Trim any whitespace off the name\r
+            channel_name = channel_name.trim();\r
+\r
+            // Check if we have the panel already. If not, create it\r
+            channel = that.panels.getByName(channel_name);\r
+            if (!channel) {\r
+                channel = new kiwi.model.Channel({name: channel_name});\r
+                kiwi.app.panels.add(channel);\r
+            }\r
+\r
+            kiwi.gateway.join(channel_name);\r
+        });\r
+\r
+        if (channel) channel.view.show();\r
+        \r
     };\r
 \r
     this.msgCommand = function (ev) {\r
index a901fc7f4baf650128d226e7f6b08c0a48b292d6..52cf62fe3e61e789cb6a6bcfb94baf970163028c 100644 (file)
-kiwi.model.Gateway = Backbone.Model.extend(new (function () {
-    var that = this;
-
-    this.defaults = {
-        /**
-        *   The name of the network
-        *   @type    String
-        */
-        name: 'Server',
-
-        /**
-        *   The address (URL) of the network
-        *   @type    String
-        */
-        address: '',
-
-        /**
-        *   The current nickname
-        *   @type   String
-        */
-        nick: '',
-
-        /**
-        *   The channel prefix for this network
-        *   @type    String
-        */
-        channel_prefix: '#',
-
-        /**
-        *   The user prefixes for channel owner/admin/op/voice etc. on this network
-        *   @type   Array
-        */
-        user_prefixes: ['~', '&', '@', '+'],
-
-        /**
-        *   The URL to the Kiwi server
-        *   @type   String
-        */
-        //kiwi_server: '//kiwi'
-        kiwi_server: 'http://localhost:7778/kiwi'
-    };
-
-
-    this.initialize = function () {
-        // Update `that` with this new Model object
-        that = this;
-
-        // For ease of access. The socket.io object
-        this.socket = this.get('socket');
-
-        // Redundant perhaps? Legacy
-        this.session_id = '';
-
-        network = this;
-    };
-
-
-    /**
-    *   Connects to the server
-    *   @param  {String}    host        The hostname or IP address of the IRC server to connect to
-    *   @param  {Number}    port        The port of the IRC server to connect to
-    *   @param  {Boolean}   ssl         Whether or not to connect to the IRC server using SSL
-    *   @param  {String}    password    The password to supply to the IRC server during registration
-    *   @param  {Function}  callback    A callback function to be invoked once Kiwi's server has connected to the IRC server
-    */
-    this.connect = function (host, port, ssl, password, callback) {
-        this.socket = io.connect(this.get('kiwi_server'), {
-            'try multiple transports': true,
-            'connect timeout': 3000,
-            'max reconnection attempts': 7,
-            'reconnection delay': 2000
-        });
-        this.socket.on('connect_failed', function (reason) {
-            // TODO: When does this even actually get fired? I can't find a case! ~Darren
-            console.debug('Unable to connect Socket.IO', reason);
-            console.log("kiwi.gateway.socket.on('connect_failed')");
-            //kiwi.front.tabviews.server.addMsg(null, ' ', 'Unable to connect to Kiwi IRC.\n' + reason, 'error');
-            this.socket.disconnect();
-            this.emit("connect_fail", {reason: reason});
-        });
-
-        this.socket.on('error', function (e) {
-            this.emit("connect_fail", {reason: e});
-            console.log("kiwi.gateway.socket.on('error')", {reason: e});
-        });
-
-        this.socket.on('connecting', function (transport_type) {
-            console.log("kiwi.gateway.socket.on('connecting')");
-            this.emit("connecting");
-        });
-
-        this.socket.on('connect', function () {
-            this.emit('irc connect', that.get('nick'), host, port, ssl, password, callback);
-            console.log("kiwi.gateway.socket.on('connect')");
-        });
-
-        this.socket.on('too_many_connections', function () {
-            this.emit("connect_fail", {reason: 'too_many_connections'});
-        });
-
-        this.socket.on('message', this.parse);
-
-        this.socket.on('disconnect', function () {
-            this.emit("disconnect", {});
-            console.log("kiwi.gateway.socket.on('disconnect')");
-        });
-
-        this.socket.on('close', function () {
-            console.log("kiwi.gateway.socket.on('close')");
-        });
-
-        this.socket.on('reconnecting', function (reconnectionDelay, reconnectionAttempts) {
-            console.log("kiwi.gateway.socket.on('reconnecting')");
-            this.emit("reconnecting", {delay: reconnectionDelay, attempts: reconnectionAttempts});
-        });
-
-        this.socket.on('reconnect_failed', function () {
-            console.log("kiwi.gateway.socket.on('reconnect_failed')");
-        });
-    };
-
-
-    /*
-        Events:
-            msg
-            action
-            server_connect
-            options
-            motd
-            notice
-            userlist
-            nick
-            join
-            topic
-            part
-            kick
-            quit
-            whois
-            syncchannel_redirect
-            debug
-    */
-    /**
-    *   Parses the response from the server
-    */
-    this.parse = function (item) {
-        console.log('gateway event', item);
-        if (item.event !== undefined) {
-            that.trigger('on' + item.event, item);
-
-            switch (item.event) {
-            case 'options':
-                $.each(item.options, function (name, value) {
-                    switch (name) {
-                    case 'CHANTYPES':
-                        // TODO: Check this. Why is it only getting the first char?
-                        that.set('channel_prefix', value.charAt(0));
-                        break;
-                    case 'NETWORK':
-                        that.set('name', value);
-                        break;
-                    case 'PREFIX':
-                        that.set('user_prefixes', value);
-                        break;
-                    }
-                });
-                break;
-
-            case 'connect':
-                that.set('nick', item.nick);
-                break;
-
-            case 'nick':
-                that.set('nick', item.newnick);
-                break;
-            /*
-            case 'sync':
-                if (kiwi.gateway.onSync && kiwi.gateway.syncing) {
-                    kiwi.gateway.syncing = false;
-                    kiwi.gateway.onSync(item);
-                }
-                break;
-            */
-
-            case 'kiwi':
-                this.emit('kiwi.' + item.namespace, item.data);
-                break;
-            }
-        }
-    };
-
-    /**
-    *   Sends data to the server
-    *   @private
-    *   @param  {Object}    data        The data to send
-    *   @param  {Function}  callback    A callback function
-    */
-    this.sendData = function (data, callback) {
-        this.socket.emit('message', {sid: this.session_id, data: JSON.stringify(data)}, callback);
-    };
-
-    /**
-    *   Sends a PRIVMSG message
-    *   @param  {String}    target      The target of the message (e.g. a channel or nick)
-    *   @param  {String}    msg         The message to send
-    *   @param  {Function}  callback    A callback function
-    */
-    this.privmsg = function (target, msg, callback) {
-        var data = {
-            method: 'privmsg',
-            args: {
-                target: target,
-                msg: msg
-            }
-        };
-
-        this.sendData(data, callback);
-    };
-
-    /**
-    *   Sends a NOTICE message
-    *   @param  {String}    target      The target of the message (e.g. a channel or nick)
-    *   @param  {String}    msg         The message to send
-    *   @param  {Function}  callback    A callback function
-    */
-    this.notice = function (target, msg, callback) {
-        var data = {
-            method: 'notice',
-            args: {
-                target: target,
-                msg: msg
-            }
-        };
-
-        this.sendData(data, callback);
-    };
-
-    /**
-    *   Sends a CTCP message
-    *   @param  {Boolean}   request     Indicates whether this is a CTCP request (true) or reply (false)
-    *   @param  {String}    type        The type of CTCP message, e.g. 'VERSION', 'TIME', 'PING' etc.
-    *   @param  {String}    target      The target of the message, e.g a channel or nick
-    *   @param  {String}    params      Additional paramaters
-    *   @param  {Function}  callback    A callback function
-    */
-    this.ctcp = function (request, type, target, params, callback) {
-        var data = {
-            method: 'ctcp',
-            args: {
-                request: request,
-                type: type,
-                target: target,
-                params: params
-            }
-        };
-
-        this.sendData(data, callback);
-    };
-
-    /**
-    *   @param  {String}    target      The target of the message (e.g. a channel or nick)
-    *   @param  {String}    msg         The message to send
-    *   @param  {Function}  callback    A callback function
-    */
-    this.action = function (target, msg, callback) {
-        this.ctcp(true, 'ACTION', target, msg, callback);
-    };
-
-    /**
-    *   Joins a channel
-    *   @param  {String}    channel     The channel to join
-    *   @param  {String}    key         The key to the channel
-    *   @param  {Function}  callback    A callback function
-    */
-    this.join = function (channel, key, callback) {
-        var data = {
-            method: 'join',
-            args: {
-                channel: channel,
-                key: key
-            }
-        };
-
-        this.sendData(data, callback);
-    };
-
-    /**
-    *   Leaves a channel
-    *   @param  {String}    channel     The channel to part
-    *   @param  {Function}  callback    A callback function
-    */
-    this.part = function (channel, callback) {
-        var data = {
-            method: 'part',
-            args: {
-                channel: channel
-            }
-        };
-
-        this.sendData(data, callback);
-    };
-
-    /**
-    *   Queries or modifies a channell topic
-    *   @param  {String}    channel     The channel to query or modify
-    *   @param  {String}    new_topic   The new topic to set
-    *   @param  {Function}  callback    A callback function
-    */
-    this.topic = function (channel, new_topic, callback) {
-        var data = {
-            method: 'topic',
-            args: {
-                channel: channel,
-                topic: new_topic
-            }
-        };
-
-        this.sendData(data, callback);
-    };
-
-    /**
-    *   Kicks a user from a channel
-    *   @param  {String}    channel     The channel to kick the user from
-    *   @param  {String}    nick        The nick of the user to kick
-    *   @param  {String}    reason      The reason for kicking the user
-    *   @param  {Function}  callback    A callback function
-    */
-    this.kick = function (channel, nick, reason, callback) {
-        var data = {
-            method: 'kick',
-            args: {
-                channel: channel,
-                nick: nick,
-                reason: reason
-            }
-        };
-
-        this.sendData(data, callback);
-    };
-
-    /**
-    *   Disconnects us from the server
-    *   @param  {String}    msg         The quit message to send to the IRC server
-    *   @param  {Function}   callback    A callback function
-    */
-    this.quit = function (msg, callback) {
-        msg = msg || "";
-        var data = {
-            method: 'quit',
-            args: {
-                message: msg
-            }
-        };
-
-        this.sendData(data, callback);
-    };
-
-    /**
-    *   Sends a string unmodified to the IRC server
-    *   @param  {String}    data        The data to send to the IRC server
-    *   @param  {Function}  callback    A callback function
-    */
-    this.raw = function (data, callback) {
-        data = {
-            method: 'raw',
-            args: {
-                data: data
-            }
-        };
-
-        this.sendData(data, callback);
-    };
-
-    /**
-    *   Changes our nickname
-    *   @param  {String}    new_nick    Our new nickname
-    *   @param  {Function}  callback    A callback function
-    */
-    this.changeNick = function (new_nick, callback) {
-        var data = {
-            method: 'nick',
-            args: {
-                nick: new_nick
-            }
-        };
-
-        this.sendData(data, callback);
-    };
-
-    /**
-    *   Sends data to a fellow Kiwi IRC user
-    *   @param  {String}    target      The nick of the Kiwi IRC user to send to
-    *   @param  {String}    data        The data to send
-    *   @param  {Function}  callback    A callback function
-    */
-    this.kiwi = function (target, data, callback) {
-        data = {
-            method: 'kiwi',
-            args: {
-                target: target,
-                data: data
-            }
-        };
-
-        this.sendData(data, callback);
-    };
+kiwi.model.Gateway = Backbone.Model.extend(new (function () {\r
+    var that = this;\r
+\r
+    this.defaults = {\r
+        /**\r
+        *   The name of the network\r
+        *   @type    String\r
+        */\r
+        name: 'Server',\r
+\r
+        /**\r
+        *   The address (URL) of the network\r
+        *   @type    String\r
+        */\r
+        address: '',\r
+\r
+        /**\r
+        *   The current nickname\r
+        *   @type   String\r
+        */\r
+        nick: '',\r
+\r
+        /**\r
+        *   The channel prefix for this network\r
+        *   @type    String\r
+        */\r
+        channel_prefix: '#',\r
+\r
+        /**\r
+        *   The user prefixes for channel owner/admin/op/voice etc. on this network\r
+        *   @type   Array\r
+        */\r
+        user_prefixes: ['~', '&', '@', '+'],\r
+\r
+        /**\r
+        *   The URL to the Kiwi server\r
+        *   @type   String\r
+        */\r
+        //kiwi_server: '//kiwi'\r
+        kiwi_server: 'http://localhost:7778/kiwi'\r
+    };\r
+\r
+\r
+    this.initialize = function () {\r
+        // Update `that` with this new Model object\r
+        that = this;\r
+\r
+        // For ease of access. The socket.io object\r
+        this.socket = this.get('socket');\r
+\r
+        // Redundant perhaps? Legacy\r
+        this.session_id = '';\r
+\r
+        network = this;\r
+    };\r
+\r
+\r
+    /**\r
+    *   Connects to the server\r
+    *   @param  {String}    host        The hostname or IP address of the IRC server to connect to\r
+    *   @param  {Number}    port        The port of the IRC server to connect to\r
+    *   @param  {Boolean}   ssl         Whether or not to connect to the IRC server using SSL\r
+    *   @param  {String}    password    The password to supply to the IRC server during registration\r
+    *   @param  {Function}  callback    A callback function to be invoked once Kiwi's server has connected to the IRC server\r
+    */\r
+    this.connect = function (host, port, ssl, password, callback) {\r
+        this.socket = io.connect(this.get('kiwi_server'), {\r
+            'try multiple transports': true,\r
+            'connect timeout': 3000,\r
+            'max reconnection attempts': 7,\r
+            'reconnection delay': 2000\r
+        });\r
+        this.socket.on('connect_failed', function (reason) {\r
+            // TODO: When does this even actually get fired? I can't find a case! ~Darren\r
+            console.debug('Unable to connect Socket.IO', reason);\r
+            console.log("kiwi.gateway.socket.on('connect_failed')");\r
+            //kiwi.front.tabviews.server.addMsg(null, ' ', 'Unable to connect to Kiwi IRC.\n' + reason, 'error');\r
+            this.socket.disconnect();\r
+            this.emit("connect_fail", {reason: reason});\r
+        });\r
+\r
+        this.socket.on('error', function (e) {\r
+            this.emit("connect_fail", {reason: e});\r
+            console.log("kiwi.gateway.socket.on('error')", {reason: e});\r
+        });\r
+\r
+        this.socket.on('connecting', function (transport_type) {\r
+            console.log("kiwi.gateway.socket.on('connecting')");\r
+            this.emit("connecting");\r
+        });\r
+\r
+        this.socket.on('connect', function () {\r
+            this.emit('irc connect', that.get('nick'), host, port, ssl, password, callback);\r
+            console.log("kiwi.gateway.socket.on('connect')");\r
+        });\r
+\r
+        this.socket.on('too_many_connections', function () {\r
+            this.emit("connect_fail", {reason: 'too_many_connections'});\r
+        });\r
+\r
+        this.socket.on('message', this.parse);\r
+\r
+        this.socket.on('disconnect', function () {\r
+            this.emit("disconnect", {});\r
+            console.log("kiwi.gateway.socket.on('disconnect')");\r
+        });\r
+\r
+        this.socket.on('close', function () {\r
+            console.log("kiwi.gateway.socket.on('close')");\r
+        });\r
+\r
+        this.socket.on('reconnecting', function (reconnectionDelay, reconnectionAttempts) {\r
+            console.log("kiwi.gateway.socket.on('reconnecting')");\r
+            this.emit("reconnecting", {delay: reconnectionDelay, attempts: reconnectionAttempts});\r
+        });\r
+\r
+        this.socket.on('reconnect_failed', function () {\r
+            console.log("kiwi.gateway.socket.on('reconnect_failed')");\r
+        });\r
+    };\r
+\r
+\r
+    /*\r
+        Events:\r
+            msg\r
+            action\r
+            server_connect\r
+            options\r
+            motd\r
+            notice\r
+            userlist\r
+            nick\r
+            join\r
+            topic\r
+            part\r
+            kick\r
+            quit\r
+            whois\r
+            syncchannel_redirect\r
+            debug\r
+    */\r
+    /**\r
+    *   Parses the response from the server\r
+    */\r
+    this.parse = function (item) {\r
+        console.log('gateway event', item);\r
+        if (item.event !== undefined) {\r
+            that.trigger('on' + item.event, item);\r
+\r
+            switch (item.event) {\r
+            case 'options':\r
+                $.each(item.options, function (name, value) {\r
+                    switch (name) {\r
+                    case 'CHANTYPES':\r
+                        // TODO: Check this. Why is it only getting the first char?\r
+                        that.set('channel_prefix', value.charAt(0));\r
+                        break;\r
+                    case 'NETWORK':\r
+                        that.set('name', value);\r
+                        break;\r
+                    case 'PREFIX':\r
+                        that.set('user_prefixes', value);\r
+                        break;\r
+                    }\r
+                });\r
+                break;\r
+\r
+            case 'connect':\r
+                that.set('nick', item.nick);\r
+                break;\r
+\r
+            case 'nick':\r
+                that.set('nick', item.newnick);\r
+                break;\r
+            /*\r
+            case 'sync':\r
+                if (kiwi.gateway.onSync && kiwi.gateway.syncing) {\r
+                    kiwi.gateway.syncing = false;\r
+                    kiwi.gateway.onSync(item);\r
+                }\r
+                break;\r
+            */\r
+\r
+            case 'kiwi':\r
+                this.emit('kiwi.' + item.namespace, item.data);\r
+                break;\r
+            }\r
+        }\r
+    };\r
+\r
+    /**\r
+    *   Sends data to the server\r
+    *   @private\r
+    *   @param  {Object}    data        The data to send\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.sendData = function (data, callback) {\r
+        this.socket.emit('message', {sid: this.session_id, data: JSON.stringify(data)}, callback);\r
+    };\r
+\r
+    /**\r
+    *   Sends a PRIVMSG message\r
+    *   @param  {String}    target      The target of the message (e.g. a channel or nick)\r
+    *   @param  {String}    msg         The message to send\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.privmsg = function (target, msg, callback) {\r
+        var data = {\r
+            method: 'privmsg',\r
+            args: {\r
+                target: target,\r
+                msg: msg\r
+            }\r
+        };\r
+\r
+        this.sendData(data, callback);\r
+    };\r
+\r
+    /**\r
+    *   Sends a NOTICE message\r
+    *   @param  {String}    target      The target of the message (e.g. a channel or nick)\r
+    *   @param  {String}    msg         The message to send\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.notice = function (target, msg, callback) {\r
+        var data = {\r
+            method: 'notice',\r
+            args: {\r
+                target: target,\r
+                msg: msg\r
+            }\r
+        };\r
+\r
+        this.sendData(data, callback);\r
+    };\r
+\r
+    /**\r
+    *   Sends a CTCP message\r
+    *   @param  {Boolean}   request     Indicates whether this is a CTCP request (true) or reply (false)\r
+    *   @param  {String}    type        The type of CTCP message, e.g. 'VERSION', 'TIME', 'PING' etc.\r
+    *   @param  {String}    target      The target of the message, e.g a channel or nick\r
+    *   @param  {String}    params      Additional paramaters\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.ctcp = function (request, type, target, params, callback) {\r
+        var data = {\r
+            method: 'ctcp',\r
+            args: {\r
+                request: request,\r
+                type: type,\r
+                target: target,\r
+                params: params\r
+            }\r
+        };\r
+\r
+        this.sendData(data, callback);\r
+    };\r
+\r
+    /**\r
+    *   @param  {String}    target      The target of the message (e.g. a channel or nick)\r
+    *   @param  {String}    msg         The message to send\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.action = function (target, msg, callback) {\r
+        this.ctcp(true, 'ACTION', target, msg, callback);\r
+    };\r
+\r
+    /**\r
+    *   Joins a channel\r
+    *   @param  {String}    channel     The channel to join\r
+    *   @param  {String}    key         The key to the channel\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.join = function (channel, key, callback) {\r
+        var data = {\r
+            method: 'join',\r
+            args: {\r
+                channel: channel,\r
+                key: key\r
+            }\r
+        };\r
+\r
+        this.sendData(data, callback);\r
+    };\r
+\r
+    /**\r
+    *   Leaves a channel\r
+    *   @param  {String}    channel     The channel to part\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.part = function (channel, callback) {\r
+        var data = {\r
+            method: 'part',\r
+            args: {\r
+                channel: channel\r
+            }\r
+        };\r
+\r
+        this.sendData(data, callback);\r
+    };\r
+\r
+    /**\r
+    *   Queries or modifies a channell topic\r
+    *   @param  {String}    channel     The channel to query or modify\r
+    *   @param  {String}    new_topic   The new topic to set\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.topic = function (channel, new_topic, callback) {\r
+        var data = {\r
+            method: 'topic',\r
+            args: {\r
+                channel: channel,\r
+                topic: new_topic\r
+            }\r
+        };\r
+\r
+        this.sendData(data, callback);\r
+    };\r
+\r
+    /**\r
+    *   Kicks a user from a channel\r
+    *   @param  {String}    channel     The channel to kick the user from\r
+    *   @param  {String}    nick        The nick of the user to kick\r
+    *   @param  {String}    reason      The reason for kicking the user\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.kick = function (channel, nick, reason, callback) {\r
+        var data = {\r
+            method: 'kick',\r
+            args: {\r
+                channel: channel,\r
+                nick: nick,\r
+                reason: reason\r
+            }\r
+        };\r
+\r
+        this.sendData(data, callback);\r
+    };\r
+\r
+    /**\r
+    *   Disconnects us from the server\r
+    *   @param  {String}    msg         The quit message to send to the IRC server\r
+    *   @param  {Function}   callback    A callback function\r
+    */\r
+    this.quit = function (msg, callback) {\r
+        msg = msg || "";\r
+        var data = {\r
+            method: 'quit',\r
+            args: {\r
+                message: msg\r
+            }\r
+        };\r
+\r
+        this.sendData(data, callback);\r
+    };\r
+\r
+    /**\r
+    *   Sends a string unmodified to the IRC server\r
+    *   @param  {String}    data        The data to send to the IRC server\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.raw = function (data, callback) {\r
+        data = {\r
+            method: 'raw',\r
+            args: {\r
+                data: data\r
+            }\r
+        };\r
+\r
+        this.sendData(data, callback);\r
+    };\r
+\r
+    /**\r
+    *   Changes our nickname\r
+    *   @param  {String}    new_nick    Our new nickname\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.changeNick = function (new_nick, callback) {\r
+        var data = {\r
+            method: 'nick',\r
+            args: {\r
+                nick: new_nick\r
+            }\r
+        };\r
+\r
+        this.sendData(data, callback);\r
+    };\r
+\r
+    /**\r
+    *   Sends data to a fellow Kiwi IRC user\r
+    *   @param  {String}    target      The nick of the Kiwi IRC user to send to\r
+    *   @param  {String}    data        The data to send\r
+    *   @param  {Function}  callback    A callback function\r
+    */\r
+    this.kiwi = function (target, data, callback) {\r
+        data = {\r
+            method: 'kiwi',\r
+            args: {\r
+                target: target,\r
+                data: data\r
+            }\r
+        };\r
+\r
+        this.sendData(data, callback);\r
+    };\r
 })());
\ No newline at end of file