wiki.techinc.nl/irc/rc2irc.php
2004-06-05 07:34:49 +00:00

192 lines
4.2 KiB
PHP

<?php
$ircNick = "wikipedia_rc";
$rooms = array("en" => 1, "fr" => 1, "de" => 1);
$ircServer = "irc.freenode.net";
$ircSockName = "tcp://$ircServer";
$ircPort = 6667;
$minDelay = 0.5;
$ircReadTimeout = 200000; # us
$ircWriteTimeout = 30; # s
$fmB = chr(2);
$fmU = chr(31);
$queueId = 337055475;
$maxMessageSize = 16384;
#-----------------------------------------------------------------------------
# Get queue
$ircPassword = mt_rand(0xffffffff);
$hostname = getenv('SERVER_NAME');
$queue = msg_get_queue($queueId);
if ( !$queue ) {
print "Could not open RC message queue\n";
exit;
}
emptyQueue( $queue );
# Initialise the IRC connection
$sockIRC = fsockopen( $ircSockName, $ircPort );
if ( !$sockIRC ) {
print "Could not open IRC connection\n";
exit;
}
stream_set_timeout($sockIRC, 0, $ircWriteTimeout);
fwrite( $sockIRC,
"PASS $ircPassword\r\n" .
"NICK $ircNick\r\n" .
"USER recentchanges $hostname $ircServer Wikipedia RC->IRC bot\r\n"
);
foreach ( $rooms as $room => $v ) {
joinRoom( $sockIRC, $room );
}
$readObjs = array( $sockIRC, $queue );
# Main input loop
$die = false;
while ( !$die ) {
# RC input
$msgType = 0;
$entry = false;
if (!msg_receive($queue, 0, $msgType, $maxMessageSize, $entry, true, MSG_IPC_NOWAIT)) {
$entry = false;
}
if (is_array( $entry )) {
$out = getIrcOutput( $sockIRC, $entry );
fwrite( $sockIRC, $out );
}
# IRC input
stream_set_timeout($sockIRC, 0, $ircReadTimeout);
$line = rtrim(fgets( $sockIRC ));
stream_set_timeout($sockIRC, 0, $ircWriteTimeout);
if ( $line ) {
$die = processIrcInput( $sockIRC, $line );
}
}
exit();
#--------------------------------------------------------------
function delayMin()
{
static $lastTime = 0;
global $minDelay;
if ( !$lastTime ) {
$lastTime = getMicroTime();
}
$curTime = getMicroTime();
$timeDifference = $curTime - $lastTime;
if ( $timeDifference < $minDelay ) {
usleep( ($minDelay - $timeDifference) *1000000 );
}
$lastTime = $curTime;
}
function getMicroTime()
{
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
function getIrcOutput( $socket, $in )
{
global $rooms;
delayMin();
$bad = array("\n", "\r");
$empty = array("", "");
$comment = $in['comment'];
$title = $in['prefixedDBkey'];
$user = $in['userText'];
$lastid = IntVal($in['lastOldid']);
$flag = ($in['minor'] ? "M" : "") . ($in['new'] ? "N" : "");
$lang = $in['lang'];
if ( $lang == "w" ) {
$lang = "en";
}
if ( !array_key_exists( $rooms, $lang ) ) {
return "";
}
$room = "#{$lang}rc.wikipedia";
if ( $in['new'] ) {
$url = "http://$lang.wikipedia.org/wiki/" . urlencode($title);
} else {
$url = "http://$lang.wikipedia.org/w/wiki.phtml?title=" . urlencode($title) .
"&diff=0&oldid=$lastid";
}
$spaceTitle = str_replace("_", " ", $title);
$beep = "";
if ( $patterns ) {
foreach ( $patterns as $pattern ) {
if ( preg_match( $pattern, $comment ) ) {
$beep = chr(7);
break;
}
}
}
if ( $comment !== "" ) {
$comment = "($comment)";
}
$fullString = str_replace($bad, $empty,
"$beep$fmB$spaceTitle$fmB $flag $url $user $comment");
$fullString = "PRIVMSG $room :$fullString\r\n";
return $fullString;
}
function joinRoom( $sock, $room )
{
global $rooms;
$rooms[$room] = 1;
fwrite( $sock, "JOIN #{$room}rc.wikipedia\r\n" );
}
function partRoom( $sock, $room )
{
global $rooms;
unset( $rooms[$room] );
fwrite( $sock, "PART #{$room}rc.wikipedia\r\n" );
}
function processIrcInput( $sock, $line )
{
global $rooms;
$die = false;
$args = explode( " ", $line );
if ( $args[0] == "PING" ) {
fwrite( $sock, "PONG {$args[1]}\r\n" );
} elseif ( $args[0]{0} == ":" ) {
$name = array_shift( $args );
$name = substr($name, 1);
$cmd = array_shift( $args );
if ( $cmd == "PRIVMSG" ) {
$msgRoom = array_shift( $args );
if ( $args[0] == "die" ) {
$die = true;
} elseif ( $args[0] == "join" ) {
joinRoom( $args[1] );
} elseif ( $args[0] == "part" ) {
partRoom( $args[1] );
}
}
}
}
function emptyQueue( $id )
{
while ( msg_receive($queue, 0, $msgType, $maxMessageSize, $entry, true, MSG_IPC_NOWAIT));
}
?>