All pastes #584900 Raw Edit

Miscellany

public text v1 · immutable
·published 2007-06-22 23:32 UTC
rendered paste body
<?php

error_reporting(E_ALL);

if (!file_exists('SVNBot.ini')) die('Cannot find configuration file "SVNBot.ini".');
$_CONF = parse_ini_file('SVNBot.ini', true);
$admin = $_CONF['config']['admin'];
$autorejoin = (substr(strtolower($_CONF['config']['autorejoin']), 0, 1) == 'y');
$channels = $_CONF['channels'];
$interval = (empty($_CONF['config']['interval']) ? 1000 : $_CONF['config']['interval']);
$nick = $_CONF['config']['nick'];
$pass = $_CONF['config']['pass'];
$repos = $_CONF['repos'];
$subversion = $_CONF['config']['svn'];
$trigger = (empty($_CONF['config']['trigger']) ? ':' : $_CONF['config']['trigger']);
$err = '';
if (empty($channels)) $err .= 'You must specify at least one channel.' . chr(10);
if (empty($nick)) $err .= 'You must specify a nick for the bot.' . chr(10);
if (empty($subversion)) $err .= 'You must specify the path to your Subversion\'s /bin directory.' . chr(10);
if (!empty($err)) die($err);

include('SmartIRC.php');
$irc = new Net_SmartIRC();

class SVNbot {
        var $rev;
        function onLoad() {
                global $repos, $subversion;
                $this->rev = array();
                foreach ($repos as $repo => $path) {
                        if (is_file($path . 'format') && strpos($path, ' ') === false) {
                                $tmp[str_replace(' ', '_', $repo)] = $path;
                        } else {
                                echo 'I cannot watch repository "' . $repo . '".';
                                ob_flush();
                        }
                }
                if (empty($tmp)) {
                        echo 'I will not be watching any repositories.' . chr(10);
                        ob_flush();
                }
                $repos = $tmp;
                if (!empty($repos)) {
                        foreach ($repos as $repo => $path) {
                                $this->rev[$repo] = 0;
                                if (is_file($path . 'format')) {
                                        exec('"' . $subversion . 'svnlook" youngest ' . $path, $svninfo);
                                        $this->rev[$repo] = $svninfo[0];
                                        unset($svninfo);
                                }
                        }
                }
        }
        function command(&$irc, &$data) {
                global $repos, $trigger;
                $message = explode(' ', $data->message);
                if (strtolower($message[0]) == strtolower($trigger) . 'svn') {
                        if (count($message) == 1) {
                                $reply = 'I am currently watching the following repositor';
                                if (count($repos) == 1) {
                                        $reply .= 'y: ';
                                } else {
                                        $reply .= 'ies: ';
                                }
                                foreach ($repos as $repo => $path) {
                                        $reply .= $repo . ' ';
                                }
                                $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel, trim($reply));
                        } else {
                                if (array_key_exists($message[1], $repos)) {
                                        $msg = $message;
                                        $rev = -1;
                                        if (count($msg) > 2) {
                                                if (is_numeric($msg[2]) && intval($msg[2]) == $msg[2] && $msg[2] <= $this->rev[$msg[1]] && $msg[2] > 
-1) {
                                                        $rev = $msg[2];
                                                } else {
                                                        $rev = $this->rev[$msg[1]];
                                                }
                                        } else {
                                                $rev = $this->rev[$msg[1]];
                                        }
                                        $info = $this->getRepoInfo($repos[$message[1]], $rev);
                                        if ($info !== false) {
                                                list($blank, $author, $date, $log, $added, $deleted, $updated, $diff) = $info;
                                                $message = str_replace('_', ' ', $msg[1]) . ' Revision ' . $rev . ' - ';
                                                $message .= 'Author: ' . $author . ' - ';
                                                $message .= 'Date: ' . date('m/d/y H:i:s', $date) . ' - ';
                                                if (count($added) + count($deleted) + count($updated) > 0) {
                                                        if (count($added) + count($deleted) + count($updated) > 5) {
                                                                if (count($added) > 0) $message .= count($added) . ' added, ';
                                                                if (count($deleted) > 0) $message .= count($deleted) . ' deleted, ';
                                                                if (count($updated) > 0) $message .= count($updated) . ' updated, ';
                                                        } else {
                                                                for ($i = 0; $i < count($added); $i++) {
                                                                        $message .= $added[$i];
                                                                        if ($i == count($added) - 1) {
                                                                                $message .= ' added, ';
                                                                        } else if ($i == count($added) - 2) {
                                                                                if (count($added) != 2) {
                                                                                        $message .= ',';
                                                                                }
                                                                                $message .= ' & ';
                                                                        } else {
                                                                                $message .= ', ';
                                                                        }
                                                                }
                                                                for ($i = 0; $i < count($deleted); $i++) {
                                                                        $message .= $deleted[$i];
                                                                        if ($i == count($deleted) - 1) {
                                                                                $message .= ' deleted, ';
                                                                        } else if ($i == count($deleted) - 2) {
                                                                                if (count($deleted) != 2) {
                                                                                        $message .= ',';
                                                                                }
                                                                                $message .= ' & ';
                                                                        } else {
                                                                                $message .= ', ';
                                                                        }
                                                                }
                                                                for ($i = 0; $i < count($updated); $i++) {
                                                                        $message .= $updated[$i];
                                                                        if ($i == count($updated) - 1) {
                                                                                $message .= ' updated, ';
                                                                        } else if ($i == count($updated) - 2) {
                                                                                if (count($updated) != 2) {
                                                                                        $message .= ',';
                                                                                }
                                                                                $message .= ' & ';
                                                                        } else {
                                                                                $message .= ', ';
                                                                        }
                                                                }
                                                        }
                                                        $message = trim(substr($message, 0, -2)) . ' - ';
                                                } else {
                                                        $message .= 'no changes - ';
                                                }
                                                $log = str_replace(chr(10), ' ', $log);
                                                if (strlen($log) > 300) {
                                                        $log = substr($log, 0, 295) . '[...]';
                                                }
                                                $message .= 'Log: ' . $log;
                                        }
                                        $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel, $message);
                                } else {
                                        $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel, 'I am not watching repository "' . $message[1] . '".');
                                }
                        }
                }
        }
        function timer(&$irc) {
                global $autorejoin, $channels, $repos, $subversion;
                foreach ($repos as $repo => $path) {
                        if (is_file($path . 'format')) {
                                exec('"' . $subversion . 'svnlook" youngest ' . $path, $svninfo);
                                $rev = $svninfo[0];
                                unset($svninfo);
                                if ($rev > $this->rev[$repo]) {
                                        $info = $this->getRepoInfo($path);
                                        if ($info !== false) {
                                                list($blank, $author, $date, $log, $added, $deleted, $updated, $diff) = $info;
                                                $revision = $this->rev[$repo] = $rev;
                                                $message = str_replace('_', ' ', $repo) . ' Commit - ';
                                                $message .= 'Author: ' . $author . ' - ';
                                                $message .= 'Revision: ' . $revision . ' - ';
                                                if (count($added) + count($deleted) + count($updated) > 0) {
                                                        if (count($added) + count($deleted) + count($updated) > 3) {
                                                                if (count($added) > 0) $message .= count($added) . ' added, ';
                                                                if (count($deleted) > 0) $message .= count($deleted) . ' deleted, ';
                                                                if (count($updated) > 0) $message .= count($updated) . ' updated, ';
                                                        } else {
                                                                for ($i = 0; $i < count($added); $i++) {
                                                                        $message .= $added[$i];
                                                                        if ($i == count($added) - 1) {
                                                                                $message .= ' added, ';
                                                                        } else if ($i == count($added) - 2) {
                                                                                if (count($added) != 2) {
                                                                                        $message .= ',';
                                                                                }
                                                                                $message .= ' & ';
                                                                        } else {
                                                                                $message .= ', ';
                                                                        }
                                                                }
                                                                for ($i = 0; $i < count($deleted); $i++) {
                                                                        $message .= $deleted[$i];
                                                                        if ($i == count($deleted) - 1) {
                                                                                $message .= ' deleted, ';
                                                                        } else if ($i == count($deleted) - 2) {
                                                                                if (count($deleted) != 2) {
                                                                                        $message .= ',';
                                                                                }
                                                                                $message .= ' & ';
                                                                        } else {
                                                                                $message .= ', ';
                                                                        }
                                                                }
                                                                for ($i = 0; $i < count($updated); $i++) {
                                                                        $message .= $updated[$i];
                                                                        if ($i == count($updated) - 1) {
                                                                                $message .= ' updated, ';
                                                                        } else if ($i == count($updated) - 2) {
                                                                                if (count($updated) != 2) {
                                                                                        $message .= ',';
                                                                                }
                                                                                $message .= ' & ';
                                                                        } else {
                                                                                $message .= ', ';
                                                                        }
                                                                }
                                                        }
                                                        $message = trim(substr($message, 0, -2)) . ' - ';
                                                } else {
                                                        $message .= 'no changes - ';
                                                }
                                                $log = str_replace(chr(10), ' ', $log);
                                                if (strlen($log) > 200) {
                                                        $log = substr($log, 0, 195) . '[...]';
                                                }
                                                $message .= 'Log: ' . $log;
                                                foreach ($channels as $channel) {
                                                        if ($irc->channel($channel) === false) {
                                                                if ($autorejoin) {
                                                                        $irc->join($channel);
                                                                } else {
                                                                        $channellist = array();
                                                                        foreach ($channels as $chan) {
                                                                                if ($chan != $channel) $channellist[] = $chan;
                                                                        }
                                                                        $channels = $channellist;
                                                                        continue;
                                                                }
                                                        }
                                                        $irc->message(SMARTIRC_TYPE_CHANNEL, $channel, $message);
                                                }
                                        }
                                }
                        }
                }
        }
        function getRepoInfo($path, $revision = -1) {
                global $subversion;
                if ($revision > -1) {
                        $rev = ' -r ' . $revision;
                } else {
                        $rev = '';
                }
                if (is_dir($path)) {
                        exec('"' . $subversion . 'svnlook" info ' . $path . $rev, $svninfo);
                        $author = trim($svninfo[0]);
                        $date = strtotime(substr($svninfo[1], 0, 25));
                        $log = '';
                        for ($i = 3; $i < count($svninfo); $i++) {
                                $log .= $svninfo[$i] . chr(10);
                        }
                        $log = trim($log);
                        unset($svninfo);
                        exec('"' . $subversion . 'svnlook" changed ' . $path . $rev, $svninfo);
                        $added = array();
                        $deleted = array();
                        $updated = array();
                        foreach ($svninfo as $line) {
                                if (empty($line)) {
                                        continue;
                                } else if (strtoupper(substr($line, 0, 1)) == 'A') {
                                        $added[] = trim(substr($line, 1));
                                } else if (strtoupper(substr($line, 0, 1)) == 'D') {
                                        $deleted[] = trim(substr($line, 1));
                                } else if (strtoupper(substr($line, 0, 1)) == 'U') {
                                        $updated[] = trim(substr($line, 1));
                                }
                        }
                        unset($svninfo);
                        exec('"' . $subversion . 'svnlook" diff ' . $path . $rev . ' --no-diff-deleted', $svninfo);
                        $diff = implode(chr(10), $svninfo);
                        unset($svninfo);
                        return array('', $author, $date, $log, $added, $deleted, $updated, $diff);
                }
        }
        function invite(&$irc, &$data) {
                global $channels;
                $channels[] = $data->message;
                $irc->join($data->message);
                $irc->message(SMARTIRC_TYPE_CHANNEL, $data->message, 'Thanks for inviting me, ' . $data->nick . '!');
        }
        function quit(&$irc, &$data) {
                global $admin;
                if (strtolower($data->nick) == strtolower($admin)) {
                        exit();
                }
        }
}
$svnbot = new SVNbot();
$svnbot->onLoad();

$tmpdata = &new Net_SmartIRC_data();
$tmpdata->nick = $admin;
register_shutdown_function(array($svnbot, 'quit'), $irc, $tmpdata);

$temp_arr = array('nick', $admin);
register_shutdown_function(array($svnbot, 'quit'), $irc, $temp_arr);
$irc->setCtcpVersion('SVNBot (by Theme97) running on PHP ' . current(explode('.', phpversion())));
$irc->registerActionhandler(SMARTIRC_TYPE_CHANNEL, '/^' . $trigger . 'svn.*/i', $svnbot, 'command');
$irc->registerActionhandler(SMARTIRC_TYPE_CHANNEL, '/^' . $trigger . 'quit/i', $svnbot, 'quit');
$irc->registerActionhandler(SMARTIRC_TYPE_INVITE, '.*', $svnbot, 'invite');
if (!empty($repos)) $irc->registerTimehandler($interval, $svnbot, 'timer');
$irc->connect('irc.freenode.net', 6667);
if ($pass == '') $pass = null;
$irc->login($nick, $nick, 0, $nick, $pass);
$irc->join($channels);
$irc->listen();
$irc->disconnect();

?>