| Index: tools/fmibot/control.js | 
| — | — | @@ -0,0 +1,81 @@ | 
|  | 2 | +/* | 
|  | 3 | + | 
|  | 4 | +    Copyright 2014 user890104 | 
|  | 5 | + | 
|  | 6 | + | 
|  | 7 | +    This file is part of fmibot. | 
|  | 8 | + | 
|  | 9 | +    fmibot is free software: you can redistribute it and/or | 
|  | 10 | +    modify it under the terms of the GNU General Public License as | 
|  | 11 | +    published by the Free Software Foundation, either version 2 of the | 
|  | 12 | +    License, or (at your option) any later version. | 
|  | 13 | + | 
|  | 14 | +    fmibot is distributed in the hope that it will be useful, | 
|  | 15 | +    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 16 | +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 
|  | 17 | +    See the GNU General Public License for more details. | 
|  | 18 | + | 
|  | 19 | +    You should have received a copy of the GNU General Public License along | 
|  | 20 | +    with fmibot.  If not, see <http://www.gnu.org/licenses/>. | 
|  | 21 | + | 
|  | 22 | +*/ | 
|  | 23 | + | 
|  | 24 | +var net = require('net'); | 
|  | 25 | +var fs = require('fs'); | 
|  | 26 | + | 
|  | 27 | +function Socket(path, successCallback, cmdCallback) { | 
|  | 28 | +    var server = net.createServer(); | 
|  | 29 | + | 
|  | 30 | +    server.on('connection', function(connection) { | 
|  | 31 | +        console.info('CONTROL: Socket open'); | 
|  | 32 | + | 
|  | 33 | +        connection.on('end', function() { | 
|  | 34 | +            console.info('CONTROL: Socket closed'); | 
|  | 35 | +        }); | 
|  | 36 | + | 
|  | 37 | +        connection.on('data', function(data) { | 
|  | 38 | +            //console.log('CONTROL: Got raw data:', data); | 
|  | 39 | +            var text = data.toString(); | 
|  | 40 | + | 
|  | 41 | +            var lines = text.split('\n').filter(function(val, idx, arr) { | 
|  | 42 | +                return !!val; | 
|  | 43 | +            }); | 
|  | 44 | + | 
|  | 45 | +            //console.log(lines); | 
|  | 46 | + | 
|  | 47 | +            var i, len = lines.length; | 
|  | 48 | + | 
|  | 49 | +            for (i = 0; i < len; ++i) { | 
|  | 50 | +                console.log('CONTROL: Got data:', lines[i]); | 
|  | 51 | +                cmdCallback(lines[i]); | 
|  | 52 | +            } | 
|  | 53 | +        }); | 
|  | 54 | +    }); | 
|  | 55 | + | 
|  | 56 | +    server.on('listening', function() { | 
|  | 57 | +        console.info('CONTROL: Socket bound'); | 
|  | 58 | + | 
|  | 59 | +        fs.chmod(path, 0775, successCallback); | 
|  | 60 | +    }); | 
|  | 61 | + | 
|  | 62 | +    server.on('error', function (e) { | 
|  | 63 | +        switch (e.code) { | 
|  | 64 | +            case 'EADDRINUSE': | 
|  | 65 | +                console.warn('CONTROL: Socket in use, retrying...'); | 
|  | 66 | +                fs.unlink(path, bindSocket); | 
|  | 67 | +            break; | 
|  | 68 | +            default: | 
|  | 69 | +                throw e; | 
|  | 70 | +            break; | 
|  | 71 | +        } | 
|  | 72 | +    }); | 
|  | 73 | + | 
|  | 74 | +    function bindSocket() { | 
|  | 75 | +        console.info('CONTROL: Attempting to bind socket...'); | 
|  | 76 | +        server.listen(path); | 
|  | 77 | +    } | 
|  | 78 | + | 
|  | 79 | +    bindSocket(); | 
|  | 80 | +} | 
|  | 81 | + | 
|  | 82 | +exports.Socket = Socket; | 
| Index: tools/fmibot/fmibot.js | 
| — | — | @@ -0,0 +1,235 @@ | 
|  | 2 | +#!/usr/bin/env node | 
|  | 3 | +/* | 
|  | 4 | + | 
|  | 5 | +    Copyright 2014 user890104 | 
|  | 6 | + | 
|  | 7 | + | 
|  | 8 | +    This file is part of fmibot. | 
|  | 9 | + | 
|  | 10 | +    fmibot is free software: you can redistribute it and/or | 
|  | 11 | +    modify it under the terms of the GNU General Public License as | 
|  | 12 | +    published by the Free Software Foundation, either version 2 of the | 
|  | 13 | +    License, or (at your option) any later version. | 
|  | 14 | + | 
|  | 15 | +    fmibot is distributed in the hope that it will be useful, | 
|  | 16 | +    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 17 | +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 
|  | 18 | +    See the GNU General Public License for more details. | 
|  | 19 | + | 
|  | 20 | +    You should have received a copy of the GNU General Public License along | 
|  | 21 | +    with fmibot.  If not, see <http://www.gnu.org/licenses/>. | 
|  | 22 | + | 
|  | 23 | +*/ | 
|  | 24 | + | 
|  | 25 | +var irc = require('irc'); | 
|  | 26 | +var fs = require('fs'); | 
|  | 27 | +var http = require('http'); | 
|  | 28 | + | 
|  | 29 | +var control = require('./control'); | 
|  | 30 | + | 
|  | 31 | +var server = 'hitchcock.freenode.net'; | 
|  | 32 | +var nickname = 'fmibot'; | 
|  | 33 | +var nicknamePassword = fs.readFileSync('nickserv.txt'); | 
|  | 34 | + | 
|  | 35 | +var announceChannel = '#freemyipod'; | 
|  | 36 | +var socketPath = '/tmp/fmibot.sock'; | 
|  | 37 | + | 
|  | 38 | +var config = { | 
|  | 39 | +    autoConnect: false, | 
|  | 40 | +    channels: [ | 
|  | 41 | +        announceChannel | 
|  | 42 | +    ], | 
|  | 43 | +    debug: true, | 
|  | 44 | +    password: nickname + ' ' + nicknamePassword, | 
|  | 45 | +    port: 6697, | 
|  | 46 | +    realName: 'freemyipod IRC bot', | 
|  | 47 | +    secure: true, | 
|  | 48 | +    showErrors: true, | 
|  | 49 | +    userName: 'ircbot' | 
|  | 50 | +}; | 
|  | 51 | + | 
|  | 52 | +var ircbot = new irc.Client(server, nickname, config); | 
|  | 53 | + | 
|  | 54 | +// error handler | 
|  | 55 | +ircbot.addListener('error', function(message) { | 
|  | 56 | +    console.error('IRCBOT', message); | 
|  | 57 | +}); | 
|  | 58 | + | 
|  | 59 | +// whois | 
|  | 60 | +ircbot.addListener('whois', function(info) { | 
|  | 61 | +    console.info(info.nick, 'is', info.user + '@' + info.host, '*', info.realname); | 
|  | 62 | +    console.info(info.nick, 'on', info.channels.join(' ')); | 
|  | 63 | +    console.info(info.nick, 'using', info.server, info.serverinfo); | 
|  | 64 | +    console.info(info.nick, 'End of /WHOIS list.'); | 
|  | 65 | +}); | 
|  | 66 | + | 
|  | 67 | +// help | 
|  | 68 | +ircbot.addListener('raw', function(message) { | 
|  | 69 | +    switch (message.rawCommand) { | 
|  | 70 | +        case '704': | 
|  | 71 | +        case '705': | 
|  | 72 | +        case '706': | 
|  | 73 | +            console.log(message.args[2]); | 
|  | 74 | +        break; | 
|  | 75 | +    } | 
|  | 76 | +}); | 
|  | 77 | + | 
|  | 78 | +// channel list | 
|  | 79 | +ircbot.addListener('channellist_start', function() { | 
|  | 80 | +    console.info('Listing channels...'); | 
|  | 81 | +}); | 
|  | 82 | + | 
|  | 83 | +ircbot.addListener('channellist_item', function(info) { | 
|  | 84 | +    console.info(info.name, info.users, info.topic); | 
|  | 85 | +}); | 
|  | 86 | + | 
|  | 87 | +// control socket | 
|  | 88 | +var controlSocket = new control.Socket(socketPath, function() { | 
|  | 89 | +    ircbot.connect(); | 
|  | 90 | +}, function(cmd) { | 
|  | 91 | +    var args = cmd.split(' '); | 
|  | 92 | +    var cmd = args.shift().toLowerCase(); | 
|  | 93 | + | 
|  | 94 | +    var argsOptional = false; | 
|  | 95 | +    var knownCmd = true; | 
|  | 96 | +    var sendCmd = true; | 
|  | 97 | + | 
|  | 98 | +    switch (cmd) { | 
|  | 99 | +        case 'quote': | 
|  | 100 | +            cmd = 'send'; | 
|  | 101 | +        case 'send': | 
|  | 102 | +            // no need to modify args | 
|  | 103 | +        break; | 
|  | 104 | +        case 'join': | 
|  | 105 | +            args = [ | 
|  | 106 | +                args.slice(0, 2).join(' ') | 
|  | 107 | +            ]; | 
|  | 108 | +        break; | 
|  | 109 | +        case 'part': | 
|  | 110 | +            args.splice(1, args.length - 1, args.slice(1).join(' ')); | 
|  | 111 | +        break; | 
|  | 112 | +        case 'say': | 
|  | 113 | +        case 'action': | 
|  | 114 | +        case 'notice': | 
|  | 115 | +            args.splice(1, args.length - 1, args.slice(1).join(' ')); | 
|  | 116 | +        break; | 
|  | 117 | +        case 'ctcp': | 
|  | 118 | +            args.splice(2, args.length - 2, args.slice(2).join(' ')); | 
|  | 119 | +        break; | 
|  | 120 | +        case 'whois': | 
|  | 121 | +            args.splice(1, args.length - 1); | 
|  | 122 | +        break; | 
|  | 123 | +        case 'list': | 
|  | 124 | +            argsOptional = true; | 
|  | 125 | +        break; | 
|  | 126 | +        case 'connect': | 
|  | 127 | +        case 'activateFloodProtection': | 
|  | 128 | +            argsOptional = true; | 
|  | 129 | + | 
|  | 130 | +            if (0 in args) { | 
|  | 131 | +                args = [ | 
|  | 132 | +                    parseInt(args[0]) | 
|  | 133 | +                ]; | 
|  | 134 | +            } | 
|  | 135 | +        break; | 
|  | 136 | +        case 'disconnect': | 
|  | 137 | +            if (!ircbot.conn) { | 
|  | 138 | +                sendCmd = false; | 
|  | 139 | +                break; | 
|  | 140 | +            } | 
|  | 141 | + | 
|  | 142 | +            argsOptional = true; | 
|  | 143 | +            var message = args.join(' '); | 
|  | 144 | + | 
|  | 145 | +            if (message.length) { | 
|  | 146 | +                args = [ | 
|  | 147 | +                    message | 
|  | 148 | +                ]; | 
|  | 149 | +            } | 
|  | 150 | +            else { | 
|  | 151 | +                args = []; | 
|  | 152 | +            } | 
|  | 153 | +        break; | 
|  | 154 | +        default: | 
|  | 155 | +            sendCmd = false; | 
|  | 156 | + | 
|  | 157 | +            switch (cmd) { | 
|  | 158 | +                case 'test': | 
|  | 159 | +                    ircbot.say(announceChannel, 'test'); | 
|  | 160 | +                break; | 
|  | 161 | +                case 'svn': | 
|  | 162 | +                    var action = args.shift(); | 
|  | 163 | + | 
|  | 164 | +                    switch (action) { | 
|  | 165 | +                        case 'commit': | 
|  | 166 | +                            if (args.length < 3) { | 
|  | 167 | +                                break; | 
|  | 168 | +                            } | 
|  | 169 | + | 
|  | 170 | +                            function announce(msg) { | 
|  | 171 | +                                ircbot.say(announceChannel, msg); | 
|  | 172 | +                            } | 
|  | 173 | + | 
|  | 174 | +                            var who = args.shift(); | 
|  | 175 | +                            var rev = args.shift(); | 
|  | 176 | +                            var message = args.join(' '); | 
|  | 177 | + | 
|  | 178 | +                            var announceMsg = 'New commit by ' + who + ' (' + irc.colors.wrap('bold', 'r' + rev) + '): ' + message; | 
|  | 179 | + | 
|  | 180 | +                            http.get('http://is.gd/create.php?format=simple&url=' + encodeURIComponent('http://websvn.freemyipod.org/revision.php?repname=freemyipod&rev=' + rev), function(res) { | 
|  | 181 | +                                console.log('HTTP STATUS:' + res.statusCode); | 
|  | 182 | + | 
|  | 183 | +                                var response = ''; | 
|  | 184 | + | 
|  | 185 | +                                res.on('data', function(chunk) { | 
|  | 186 | +                                    console.log('HTTP CHUNK:', chunk); | 
|  | 187 | +                                    response += chunk; | 
|  | 188 | +                                }); | 
|  | 189 | + | 
|  | 190 | +                                res.on('end', function() { | 
|  | 191 | +                                    console.log('HTTP RESPONSE:', response); | 
|  | 192 | +                                    announce(announceMsg + ' ' + response); | 
|  | 193 | +                                }) | 
|  | 194 | +                            }).on('error', function(e) { | 
|  | 195 | +                                console.error('HTTP:' + e.message); | 
|  | 196 | +                                announce(announceMsg); | 
|  | 197 | +                            }); | 
|  | 198 | +                        break; | 
|  | 199 | +                        case 'buildresult': | 
|  | 200 | +                            // TODO | 
|  | 201 | +                        break; | 
|  | 202 | +                    } | 
|  | 203 | +                break; | 
|  | 204 | +                case 'exit': | 
|  | 205 | +                    if (ircbot.conn) { | 
|  | 206 | +                        ircbot.disconnect('Exiting by control socket request', function() { | 
|  | 207 | +                            process.exit(); | 
|  | 208 | +                        }); | 
|  | 209 | +                    } | 
|  | 210 | +                    else { | 
|  | 211 | +                        process.exit(); | 
|  | 212 | +                    } | 
|  | 213 | +                break; | 
|  | 214 | +                default: | 
|  | 215 | +                    knownCmd = false; | 
|  | 216 | +                break; | 
|  | 217 | +            } | 
|  | 218 | +        break; | 
|  | 219 | +    } | 
|  | 220 | + | 
|  | 221 | +    if (knownCmd) { | 
|  | 222 | +        console.info('CMD: got CMD', cmd, 'ARGS', args); | 
|  | 223 | + | 
|  | 224 | +        if (sendCmd) { | 
|  | 225 | +            if (args.length === 0 && !argsOptional) { | 
|  | 226 | +                console.warn('CMD: not enough arguments'); | 
|  | 227 | +                return; | 
|  | 228 | +            } | 
|  | 229 | + | 
|  | 230 | +            ircbot[cmd].apply(ircbot, args); | 
|  | 231 | +        } | 
|  | 232 | +    } | 
|  | 233 | +    else { | 
|  | 234 | +        console.error('CMD: unknown CMD', cmd, 'ARGS', args); | 
|  | 235 | +    } | 
|  | 236 | +}); | 
| Index: tools/fmibot | 
| Property changes on: tools/fmibot | 
| ___________________________________________________________________ | 
| Added: svn:ignore | 
| ## -0,0 +1 ## | 
|  | 237 | +nickserv.txt |