]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
More Irc plugin work
authorLuke Fitzgerald <lw.fitzgerald@googlemail.com>
Mon, 26 Jul 2010 18:13:00 +0000 (11:13 -0700)
committerLuke Fitzgerald <lw.fitzgerald@googlemail.com>
Mon, 26 Jul 2010 18:13:00 +0000 (11:13 -0700)
17 files changed:
plugins/Irc/IrcPlugin.php
plugins/Irc/README
plugins/Irc/extlib/phergie/Phergie/Plugin/Beer.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Beer/db.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Censor.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Cocktail.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Cocktail/db.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Cookie.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Cookie/db.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Karma.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Serve.php [new file with mode: 0755]
plugins/Irc/extlib/phergie/Phergie/Plugin/Statusnet.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Wine.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Wine/db.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Process/Async.php
plugins/Irc/extlib/phergie/Phergie/StatusnetBot.php
plugins/Irc/ircmanager.php

index d23f5005c0b9a62ee50a45624843f30268285a6c..dec6d7e8328148b953d32908df7e037e919ae1fb 100644 (file)
@@ -55,12 +55,15 @@ class IrcPlugin extends ImPlugin {
     public $realname = null;
     public $nick = null;
     public $password = null;
+    public $nickservidentifyregexp = null;
     public $nickservpassword = null;
     public $channels = null;
     public $transporttype = null;
     public $encoding = null;
 
     public $regcheck = null;
+    public $unregregexp = null;
+    public $regregexp = null;
 
     public $transport = 'irc';
     public $fake_irc;
@@ -249,21 +252,12 @@ class IrcPlugin extends ImPlugin {
         if (!isset($this->port)) {
             $this->port = 6667;
         }
-        if (!isset($this->password)) {
-            $this->password = '';
-        }
         if (!isset($this->transporttype)) {
             $this->transporttype = 'tcp';
         }
         if (!isset($this->encoding)) {
             $this->encoding = 'UTF-8';
         }
-        if (!isset($this->nickservpassword)) {
-            $this->nickservpassword = '';
-        }
-        if (!isset($this->channels)) {
-            $this->channels = array();
-        }
 
         if (!isset($this->regcheck)) {
             $this->regcheck = true;
index 79ce8ff56af3226b8306f3aa1e7314b9b1110cdb..bc45688f1e6bc3048d90f708bb2679eb4d76ff1a 100644 (file)
@@ -19,6 +19,7 @@ realname*: Real name of bot
 nick*: Nickname of bot
 password: Password
 nickservpassword: NickServ password for identification
+nickservidentifyregexp: Override existing regexp matching request for identification from NickServ
 channels: Channels for bot to idle in
 transporttype: Set to 'ssl' to enable SSL
 encoding: Set to change encoding
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Beer.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Beer.php
new file mode 100644 (file)
index 0000000..7213cde
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Phergie
+ *
+ * PHP version 5
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.
+ * It is also available through the world-wide-web at this URL:
+ * http://phergie.org/license
+ *
+ * @category  Phergie
+ * @package   Phergie_Plugin_Beer
+ * @author    Phergie Development Team <team@phergie.org>
+ * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
+ * @license   http://phergie.org/license New BSD License
+ * @link      http://pear.phergie.org/package/Phergie_Plugin_Beer
+ */
+
+/**
+ * Processes requests to serve users beer.
+ *
+ * @category Phergie
+ * @package  Phergie_Plugin_Beer
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie_Plugin_Beer
+ * @uses     Phergie_Plugin_Command pear.phergie.org
+ * @uses     Phergie_Plugin_Serve pear.phergie.org
+ */
+class Phergie_Plugin_Beer extends Phergie_Plugin_Abstract
+{
+    /**
+     * Checks for dependencies.
+     *
+     * @return void
+     */
+    public function onLoad()
+    {
+        $plugins = $this->plugins;
+        $plugins->getPlugin('Command');
+        $plugins->getPlugin('Serve');
+    }
+
+    /**
+     * Processes requests to serve a user a beer.
+     *
+     * @param string $request Request including the target and an optional
+     *        suggestion of what beer to serve
+     *
+     * @return void
+     */
+    public function onCommandBeer($request)
+    {
+        $format = $this->getConfig(
+            'beer.format',
+            'throws %target% %article% %item%.'
+        );
+
+        $this->plugins->getPlugin('Serve')->serve(
+            dirname(__FILE__) . '/Beer/beer.db',
+            'beer',
+            $format,
+            $request
+        );
+    }
+
+    /**
+     * Adds a "booze" alias for the "beer" command.
+     *
+     * @param string $request Request including the target and an optional
+     *        suggestion of what beer to serve
+     *
+     * @return void
+     */
+    public function onCommandBooze($request)
+    {
+        $this->onCommandBeer($request);
+    }
+}
index 309d389b5561c9b5cb344a26433a3599a14499ef..05ae064ed71fc1f51c7db833928010b19d11a3e3 100644 (file)
@@ -34,7 +34,7 @@ $xpath = new DOMXPath($doc);
 $beers = $xpath->query('//table[@class="beerlist"]/tr/td[1]');
 $db->beginTransaction();
 foreach ($beers as $beer) {
-    $name = $beer->textContent;
+    $name = iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $beer->textContent);
     $link = 'http://beerme.com' . $beer->childNodes->item(1)->getAttribute('href');
     $insert->execute(array($name, $link));
 }
@@ -65,7 +65,7 @@ $columns = fgetcsv($fp, 0, '|');
 $db->beginTransaction();
 while ($line = fgetcsv($fp, 0, '|')) {
     $line = array_combine($columns, $line);
-    $name = $line['name'];
+    $name = iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $line['name']);
     $link = null;
     $insert->execute(array($name, $link));
 }
index 3206bdd288d36817fc0e32bf7f52ea5c935e6119..99c69d873452248604f5caf15a7a133f8cc63950 100755 (executable)
@@ -72,7 +72,19 @@ class Phergie_Plugin_Censor extends Phergie_Plugin_Abstract
             $this->soap = new SoapClient('http://ws.cdyne.com/ProfanityWS/Profanity.asmx?wsdl');
         }
         $params = array('Text' => $string);
-        $response = $this->soap->SimpleProfanityFilter($params);
+        $attempts = 0;
+        while ($attempts < 3) {
+            try {
+                $response = $this->soap->SimpleProfanityFilter($params);
+                break;
+            } catch (SoapFault $e) {
+                $attempts++;
+                sleep(1);
+            }
+        }
+        if ($attempts == 3) {
+            return $string;
+        }
         return $response->SimpleProfanityFilterResult->CleanText;
     }
 
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Cocktail.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Cocktail.php
new file mode 100644 (file)
index 0000000..eafeb65
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Phergie
+ *
+ * PHP version 5
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.
+ * It is also available through the world-wide-web at this URL:
+ * http://phergie.org/license
+ *
+ * @category  Phergie
+ * @package   Phergie_Plugin_Cocktail
+ * @author    Phergie Development Team <team@phergie.org>
+ * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
+ * @license   http://phergie.org/license New BSD License
+ * @link      http://pear.phergie.org/package/Phergie_Plugin_Cocktail
+ */
+
+/**
+ * Processes requests to serve users cocktail.
+ *
+ * @category Phergie
+ * @package  Phergie_Plugin_Cocktail
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie_Plugin_Cocktail
+ * @uses     Phergie_Plugin_Command pear.phergie.org
+ * @uses     Phergie_Plugin_Serve pear.phergie.org
+ */
+class Phergie_Plugin_Cocktail extends Phergie_Plugin_Abstract
+{
+    /**
+     * Checks for dependencies.
+     *
+     * @return void
+     */
+    public function onLoad()
+    {
+        $plugins = $this->plugins;
+        $plugins->getPlugin('Command');
+        $plugins->getPlugin('Serve');
+    }
+
+    /**
+     * Processes requests to serve a user a cocktail.
+     *
+     * @param string $request Request including the target and an optional
+     *        suggestion of what cocktail to serve
+     *
+     * @return void
+     */
+    public function onCommandCocktail($request)
+    {
+        $format = $this->getConfig(
+            'cocktail.format',
+            'throws %target% %article% %item%.'
+        );
+
+        $this->plugins->getPlugin('Serve')->serve(
+            dirname(__FILE__) . '/Cocktail/cocktail.db',
+            'cocktail',
+            $format,
+            $request,
+            true
+        );
+    }
+}
+
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Cocktail/db.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Cocktail/db.php
new file mode 100644 (file)
index 0000000..2e61dd0
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+
+if (!defined('__DIR__')) {
+    define('__DIR__', dirname(__FILE__));
+}
+
+// Create database schema
+echo 'Creating database', PHP_EOL;
+$file = __DIR__ . '/cocktail.db';
+if (file_exists($file)) {
+    unlink($file);
+}
+$db = new PDO('sqlite:' . $file);
+$db->exec('CREATE TABLE cocktail (name VARCHAR(255), link VARCHAR(255))');
+$db->exec('CREATE UNIQUE INDEX cocktail_name ON cocktail (name)');
+$insert = $db->prepare('INSERT INTO cocktail (name, link) VALUES (:name, :link)');
+
+// Get raw webtender.com data set
+echo 'Downloading webtender.com data set', PHP_EOL;
+$start = 1;
+do {
+    $file = __DIR__ . '/' . $start . '.html';
+    if (file_exists($file)) {
+        continue;
+    }
+    copy(
+        'http://www.webtender.com/db/browse?level=2&dir=drinks&char=%2A&start=' . $start,
+        $file
+    );
+    if (!isset($limit)) {
+        $contents = file_get_contents($file);
+        preg_match('/([0-9]+) found/', $contents, $match);
+        $limit = $match[1] + (150 - ($match[1] % 150));
+    }
+    echo 'Got records ', $start, ' - ', min($start + 150, $limit), ' of ', $limit, PHP_EOL;
+    $start += 150;
+} while ($start < $limit);
+
+// Extract data from data set
+$start = 1;
+while ($start < $limit) {
+    echo 'Processing ', $start, ' - ', min($start + 150, $limit), ' of ', $limit, PHP_EOL;
+
+    $file = __DIR__ . '/' . $start . '.html';
+    $contents = file_get_contents($file);
+    $contents = tidy_repair_string($contents);
+    libxml_use_internal_errors(true);
+    $doc = new DOMDocument;
+    $doc->loadHTML($contents);
+    libxml_clear_errors();
+    $xpath = new DOMXPath($doc);
+
+    $cocktails = $xpath->query('//li/a');
+    $db->beginTransaction();
+    foreach ($cocktails as $cocktail) {
+        $name = $cocktail->nodeValue;
+        $name = preg_replace('/ The$|^The |\s*\([^)]+\)\s*| #[0-9]+$/', '', $name);
+        $name = html_entity_decode($name);
+        $link = 'http://www.webtender.com' . $cocktail->getAttribute('href');
+        $insert->execute(array($name, $link));
+    }
+    $db->commit();
+
+    $start += 150;
+}
+
+// Clean up
+echo 'Cleaning up', PHP_EOL;
+$start = 1;
+while ($start < $limit) {
+    $file = __DIR__ . '/' . $start . '.html';
+    unlink($file);
+    $start += 150;
+}
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Cookie.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Cookie.php
new file mode 100644 (file)
index 0000000..4bc2cee
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Phergie
+ *
+ * PHP version 5
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.
+ * It is also available through the world-wide-web at this URL:
+ * http://phergie.org/license
+ *
+ * @category  Phergie
+ * @package   Phergie_Plugin_Cookie
+ * @author    Phergie Development Team <team@phergie.org>
+ * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
+ * @license   http://phergie.org/license New BSD License
+ * @link      http://pear.phergie.org/package/Phergie_Plugin_Cookie
+ */
+
+/**
+ * Processes requests to serve users cookies.
+ *
+ * @category Phergie
+ * @package  Phergie_Plugin_Cookie
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie_Plugin_Cookie
+ * @uses     Phergie_Plugin_Command pear.phergie.org
+ * @uses     Phergie_Plugin_Serve pear.phergie.org
+ */
+class Phergie_Plugin_Cookie extends Phergie_Plugin_Abstract
+{
+    /**
+     * Checks for dependencies.
+     *
+     * @return void
+     */
+    public function onLoad()
+    {
+        $plugins = $this->plugins;
+        $plugins->getPlugin('Command');
+        $plugins->getPlugin('Serve');
+    }
+
+    /**
+     * Processes requests to serve a user a cookie.
+     *
+     * @param string $request Request including the target and an optional
+     *        suggestion of what cookie to serve
+     *
+     * @return void
+     */
+    public function onCommandCookie($request)
+    {
+        $format = $this->getConfig(
+            'cookie.format',
+            'throws %target% %article% %item%.'
+        );
+
+        $this->plugins->getPlugin('Serve')->serve(
+            dirname(__FILE__) . '/Cookie/cookie.db',
+            'cookies',
+            $format,
+            $request
+        );
+    }
+}
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Cookie/db.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Cookie/db.php
new file mode 100644 (file)
index 0000000..4b3d29c
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+if (!defined('__DIR__')) {
+    define('__DIR__', dirname(__FILE__));
+}
+
+// Create database schema
+echo 'Creating database', PHP_EOL;
+$file = __DIR__ . '/cookie.db';
+if (file_exists($file)) {
+    unlink($file);
+}
+$db = new PDO('sqlite:' . $file);
+$db->exec('CREATE TABLE cookies (name VARCHAR(255), link VARCHAR(255))');
+$db->exec('CREATE UNIQUE INDEX cookie_name ON cookies (name)');
+$insert = $db->prepare('INSERT INTO cookies (name, link) VALUES (:name, :link)');
+
+// Get Cookies list from http://en.wikipedia.org/wiki/List_of_cookies
+echo 'Downloading data from Wikipedia', PHP_EOL;
+$file = __DIR__ . '/cookieslist.txt';
+if (!file_exists($file)) {
+    copy('http://en.wikipedia.org/wiki/List_of_cookies', $file);
+}
+$contents = file_get_contents($file);
+
+// Extract data from data set
+echo 'Processing Wikipedia\'s cookies list', PHP_EOL;
+$contents = tidy_repair_string($contents);
+libxml_use_internal_errors(true);
+$doc = new DOMDocument;
+$doc->loadHTML($contents);
+libxml_clear_errors();
+$xpath = new DOMXPath($doc);
+
+$cookies = $xpath->query('//table[@width="90%"]/tr/td[1]/a');
+
+foreach ($cookies as $cookie) {
+    
+    $name = str_replace(array('(',')',"\n", 'cookies'), array('','', ' ', 'cookie' ), trim( $cookie->textContent));
+
+    $link =  'http://en.wikipedia.org' . $cookie->getAttribute('href');
+    $insert->execute(array($name, $link));
+    print 'added ['.$name.'] -> '. $link . PHP_EOL;
+}
+
+// Clean up
+echo 'Cleaning up', PHP_EOL;
+unlink($file);
+
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Karma.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Karma.php
new file mode 100644 (file)
index 0000000..b7ce486
--- /dev/null
@@ -0,0 +1,447 @@
+<?php
+/**
+ * Phergie
+ *
+ * PHP version 5
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.
+ * It is also available through the world-wide-web at this URL:
+ * http://phergie.org/license
+ *
+ * @category  Phergie
+ * @package   Phergie_Plugin_Karma
+ * @author    Phergie Development Team <team@phergie.org>
+ * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
+ * @license   http://phergie.org/license New BSD License
+ * @link      http://pear.phergie.org/package/Phergie_Plugin_Karma
+ */
+
+/**
+ * Handles requests for incrementation or decrementation of a maintained list
+ * of counters for specified terms and antithrottling to prevent extreme
+ * inflation or depression of counters by any single individual.
+ *
+ * @category Phergie
+ * @package  Phergie_Plugin_Karma
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie_Plugin_Karma
+ */
+class Phergie_Plugin_Karma extends Phergie_Plugin_Abstract
+{
+    /**
+     * Stores the SQLite object
+     *
+     * @var resource
+     */
+    protected $db = null;
+
+    /**
+     * Retains the last garbage collection date
+     *
+     * @var array
+     */
+    protected $lastGc = null;
+
+    /**
+     * Logs the karma usages and limits users to one karma change per word
+     * and per day
+     *
+     * @return void
+     */
+    protected $log = array();
+
+    /**
+     * Some fixed karma values, keys must be lowercase
+     *
+     * @var array
+     */
+    protected $fixedKarma;
+
+    /**
+     * A list of blacklisted values
+     *
+     * @var array
+     */
+    protected $karmaBlacklist;
+
+    /**
+     * Answers for correct assertions
+     */
+    protected $positiveAnswers;
+
+    /**
+     * Answers for incorrect assertions
+     */
+    protected $negativeAnswers;
+
+    /**
+     * Prepared PDO statements
+     *
+     * @var PDOStatement
+     */
+    protected $insertKarma;
+    protected $updateKarma;
+    protected $fetchKarma;
+    protected $insertComment;
+
+    /**
+     * Connects to the database containing karma ratings and initializes
+     * class properties.
+     *
+     * @return void
+     */
+    public function onLoad()
+    {
+        $this->db = null;
+        $this->lastGc = null;
+        $this->log = array();
+
+        if(!defined('M_EULER')) {
+            define('M_EULER', '0.57721566490153286061');
+        }
+
+        $this->fixedKarma = array(
+            'phergie'      => '%s has karma of awesome',
+            'pi'           => '%s has karma of ' . M_PI,
+            'Π'            => '%s has karma of ' . M_PI,
+            'Ï€'            => '%s has karma of ' . M_PI,
+            'chucknorris'  => '%s has karma of Warning: Integer out of range',
+            'chuck norris' => '%s has karma of Warning: Integer out of range',
+            'c'            => '%s has karma of 299 792 458 m/s',
+            'e'            => '%s has karma of ' . M_E,
+            'euler'        => '%s has karma of ' . M_EULER,
+            'mole'         => '%s has karma of 6.02214e23 molecules',
+            'avogadro'     => '%s has karma of 6.02214e23 molecules',
+            'spoon'        => '%s has no karma. There is no spoon',
+            'mc^2'         => '%s has karma of E',
+            'mc2'          => '%s has karma of E',
+            'mc²'          => '%s has karma of E',
+            'i'            => '%s haz big karma',
+            'karma' => 'The karma law says that all living creatures are responsible for their karma - their actions and the effects of their actions. You should watch yours.'
+        );
+
+        $this->karmaBlacklist = array(
+            '*',
+            'all',
+            'everything'
+        );
+
+        $this->positiveAnswers = array(
+            'No kidding, %owner% totally kicks %owned%\'s ass !',
+            'True that.',
+            'I concur.',
+            'Yay, %owner% ftw !',
+            '%owner% is made of WIN!',
+            'Nothing can beat %owner%!',
+        );
+
+        $this->negativeAnswers = array(
+            'No sir, not at all.',
+            'You\'re wrong dude, %owner% wins.',
+            'I\'d say %owner% is better than %owned%.',
+            'You must be joking, %owner% ftw!',
+            '%owned% is made of LOSE!',
+            '%owned% = Epic Fail',
+        );
+
+        // Load or initialize the database
+        $class = new ReflectionClass(get_class($this));
+        $dir = dirname($class->getFileName() . '/' . $this->name);
+        $this->db = new PDO('sqlite:' . $dir . 'karma.db');
+
+        // Check to see if the table exists
+        $table = $this->db->query('
+            SELECT COUNT(*)
+            FROM sqlite_master
+            WHERE name = ' . $this->db->quote('karmas')
+        )->fetchColumn();
+
+        // Create database tables if necessary
+        if (!$table) {
+            $this->db->query('
+                CREATE TABLE karmas ( word VARCHAR ( 255 ), karma MEDIUMINT );
+                CREATE UNIQUE INDEX word ON karmas ( word );
+                CREATE INDEX karmaIndex ON karmas ( karma );
+                CREATE TABLE comments ( wordid INT , comment VARCHAR ( 255 ) );
+                CREATE INDEX wordidIndex ON comments ( wordid );
+                CREATE UNIQUE INDEX commentUnique ON comments ( comment );
+            ');
+        }
+
+        $this->insertKarma = $this->db->prepare('
+            INSERT INTO karmas (
+                word,
+                karma
+            )
+            VALUES (
+                :word,
+                :karma
+            )
+        ');
+
+        $this->insertComment = $this->db->prepare('
+            INSERT INTO comments (
+                wordid,
+                comment
+            )
+            VALUES (
+                :wordid,
+                :comment
+            )
+        ');
+
+        $this->fetchKarma = $this->db->prepare('
+            SELECT karma, ROWID id FROM karmas WHERE LOWER(word) = LOWER(:word) LIMIT 1
+        ');
+
+        $this->updateKarma = $this->db->prepare('
+            UPDATE karmas SET karma = :karma WHERE LOWER(word) = LOWER(:word)
+        ');
+    }
+
+    /**
+     * Checks for dependencies.
+     *
+     * @return void
+     */
+    public static function onLoad()
+    {
+       if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
+            $this->fail('PDO and pdo_sqlite extensions must be installed');
+       }
+    }
+
+    /**
+     * Handles requests for incrementation, decrementation, or lookup of karma
+     * ratings sent via messages from users.
+     *
+     * @return void
+     */
+    public function onPrivmsg()
+    {
+        $source = $this->event->getSource();
+        $message = $this->event->getArgument(1);
+        $target = $this->event->getNick();
+
+        // Command prefix check
+        $prefix = preg_quote(trim($this->getConfig('command.prefix')));
+        $bot = preg_quote($this->getConfig('connections.nick'));
+        $exp = '(?:(?:' . $bot . '\s*[:,>]?\s+(?:' . $prefix . ')?)|(?:' . $prefix . '))';
+
+        // Karma status request
+        if (preg_match('#^' . $exp . 'karma\s+(.+)$#i', $message, $m)) {
+            // Return user's value if "me" is requested
+            if (strtolower($m[1]) === 'me') {
+                $m[1] = $target;
+            }
+            // Clean the term
+            $term = $this->doCleanWord($m[1]);
+
+            // Check the blacklist
+            if (is_array($this->karmaBlacklist) && in_array($term, $this->karmaBlacklist)) {
+                $this->doNotice($target, $term . ' is blacklisted');
+                return;
+            }
+
+            // Return fixed value if set
+            if (isset($this->fixedKarma[$term])) {
+                $this->doPrivmsg($source, $target . ': ' . sprintf($this->fixedKarma[$term], $m[1]) . '.');
+                return;
+            }
+
+            // Return current karma or neutral if not set yet
+            $this->fetchKarma->execute(array(':word'=>$term));
+            $res = $this->fetchKarma->fetch(PDO::FETCH_ASSOC);
+
+            // Sanity check if someone if someone prefixed their conversation with karma
+            if (!$res && substr_count($term, ' ') > 1 && !(substr($m[1], 0, 1) === '(' && substr($m[1], -1) === ')')) {
+                return;
+            }
+
+            // Clean the raw term if it was contained within brackets
+            if (substr($m[1], 0, 1) === '(' && substr($m[1], -1) === ')') {
+                $m[1] = substr($m[1], 1, -1);
+            }
+
+            if ($res && $res['karma'] != 0) {
+                $this->doPrivmsg($source, $target . ': ' . $m[1] . ' has karma of ' . $res['karma'] . '.');
+            } else {
+                $this->doPrivmsg($source, $target . ': ' . $m[1] . ' has neutral karma.');
+            }
+        // Incrementation/decrementation request
+        } elseif (preg_match('{^' . $exp . '?(?:(\+{2,2}|-{2,2})(\S+?|\(.+?\)+)|(\S+?|\(.+?\)+)(\+{2,2}|-{2,2}))(?:\s+(.*))?$}ix', $message, $m)) {
+            if (!empty($m[4])) {
+                $m[1] = $m[4]; // Increment/Decrement
+                $m[2] = $m[3]; // Word
+            }
+            $m[3] = (isset($m[5]) ? $m[5] : null); // Comment
+            unset($m[4], $m[5]);
+            list(, $sign, $word, $comment) = array_pad($m, 4, null);
+
+            // Clean the word
+            $word = strtolower($this->doCleanWord($word));
+            if (empty($word)) {
+                return;
+            }
+
+            // Do nothing if the karma is fixed or blacklisted
+            if (isset($this->fixedKarma[$word]) ||
+                is_array($this->karmaBlacklist) && in_array($word, $this->karmaBlacklist)) {
+                return;
+            }
+
+            // Force a decrementation if someone tries to update his own karma
+            if ($word == strtolower($target) && $sign != '--' && !$this->fromAdmin(true)) {
+                $this->doNotice($target, 'Bad ' . $target . '! You can not modify your own Karma. Shame on you!');
+                $sign = '--';
+            }
+
+            // Antithrottling check
+            $host = $this->event->getHost();
+            $limit = $this->getConfig('karma.limit');
+            // This is waiting on the Acl plugin from Elazar, being bypassed for now
+            //if ($limit > 0 && !$this->fromAdmin()) {
+            if ($limit > 0) {
+                if (isset($this->log[$host][$word]) && $this->log[$host][$word] >= $limit) {
+                    // Three strikes, you're out, so lets decrement their karma for spammage
+                    if ($this->log[$host][$word] == ($limit+3)) {
+                        $this->doNotice($target, 'Bad ' . $target . '! Didn\'t I tell you that you reached your limit already?');
+                        $this->log[$host][$word] = $limit;
+                        $word = $target;
+                        $sign = '--';
+                    // Toss a notice to the user if they reached their limit
+                    } else {
+                        $this->doNotice($target, 'You have currently reached your limit in modifying ' . $word . ' for this day, please wait a bit.');
+                        $this->log[$host][$word]++;
+                        return;
+                    }
+                } else {
+                    if (isset($this->log[$host][$word])) {
+                        $this->log[$host][$word]++;
+                    } else {
+                        $this->log[$host][$word] = 1;
+                    }
+                }
+            }
+
+            // Get the current value then update or create entry
+            $this->fetchKarma->execute(array(':word'=>$word));
+            $res = $this->fetchKarma->fetch(PDO::FETCH_ASSOC);
+            if ($res) {
+                $karma = ($res['karma'] + ($sign == '++' ? 1 : -1));
+                $args = array(
+                    ':word' => $word,
+                    ':karma' => $karma
+                );
+                $this->updateKarma->execute($args);
+            } else {
+                $karma = ($sign == '++' ? '1' : '-1');
+                $args = array(
+                    ':word' => $word,
+                    ':karma' => $karma
+                );
+                $this->insertKarma->execute($args);
+                $this->fetchKarma->execute(array(':word'=>$word));
+                $res = $this->fetchKarma->fetch(PDO::FETCH_ASSOC);
+            }
+            $id = $res['id'];
+            // Add comment
+            $comment = preg_replace('{(?:^//(.*)|^#(.*)|^/\*(.*?)\*/$)}', '$1$2$3', $comment);
+            if (!empty($comment)) {
+                $this->insertComment->execute(array(':wordid' => $id, ':comment' => $comment));
+            }
+            // Perform garbage collection on the antithrottling log if needed
+            if (date('d') !== $this->lastGc) {
+                $this->doGc();
+            }
+        // Assertion request
+        } elseif (preg_match('#^' . $exp . '?([^><]+)(<|>)([^><]+)$#', $message, $m)) {
+            // Trim words
+            $word1 = strtolower($this->doCleanWord($m[1]));
+            $word2 = strtolower($this->doCleanWord($m[3]));
+            $operator = $m[2];
+
+            // Do nothing if the karma is fixed
+            if (isset($this->fixedKarma[$word1]) || isset($this->fixedKarma[$word2]) ||
+                empty($word1) || empty($word2)) {
+                return;
+            }
+
+            // Fetch first word
+            if ($word1 === '*' || $word1 === 'all' || $word1 === 'everything') {
+                $res = array('karma' => 0);
+                $word1 = 'everything';
+            } else {
+                $this->fetchKarma->execute(array(':word'=>$word1));
+                $res = $this->fetchKarma->fetch(PDO::FETCH_ASSOC);
+            }
+            // If it exists, fetch second word
+            if ($res) {
+                if ($word2 === '*' || $word2 === 'all' || $word2 === 'everything') {
+                    $res2 = array('karma' => 0);
+                    $word2 = 'everything';
+                } else {
+                    $this->fetchKarma->execute(array(':word'=>$word2));
+                    $res2 = $this->fetchKarma->fetch(PDO::FETCH_ASSOC);
+                }
+                // If it exists, compare and return value
+                if ($res2 && $res['karma'] != $res2['karma']) {
+                    $assertion = ($operator === '<' && $res['karma'] < $res2['karma']) || ($operator === '>' && $res['karma'] > $res2['karma']);
+                    // Switch arguments if they are in the wrong order
+                    if ($operator === '<') {
+                        $tmp = $word2;
+                        $word2 = $word1;
+                        $word1 = $tmp;
+                    }
+                    $this->doPrivmsg($source, $assertion ? $this->fetchPositiveAnswer($word1, $word2) : $this->fetchNegativeAnswer($word1, $word2));
+                    // If someone asserts that something is greater or lesser than everything, we increment/decrement that something at the same time
+                    if ($word2 === 'everything') {
+                        $this->event = clone$this->event;
+                        $this->event->setArguments(array($this->event->getArgument(0), '++'.$word1));
+                        $this->onPrivmsg();
+                    } elseif ($word1 === 'everything') {
+                        $this->event = clone$this->event;
+                        $this->event->setArguments(array($this->event->getArgument(0), '--'.$word2));
+                        $this->onPrivmsg();
+                    }
+                }
+            }
+        }
+    }
+
+    protected function fetchPositiveAnswer($owner, $owned)
+    {
+        return str_replace(array('%owner%','%owned%'), array($owner, $owned), $this->positiveAnswers[array_rand($this->positiveAnswers,1)]);
+    }
+
+    protected function fetchNegativeAnswer($owned, $owner)
+    {
+        return str_replace(array('%owner%','%owned%'), array($owner, $owned), $this->negativeAnswers[array_rand($this->negativeAnswers,1)]);
+    }
+
+    protected function doCleanWord($word)
+    {
+        $word = trim($word);
+        if (substr($word, 0, 1) === '(' && substr($word, -1) === ')') {
+            $word = trim(substr($word, 1, -1));
+        }
+        $word = preg_replace('#\s+#', ' ', strtolower(trim($word)));
+        return $word;
+    }
+
+    /**
+     * Performs garbage collection on the antithrottling log.
+     *
+     * @return void
+     */
+    public function doGc()
+    {
+        unset($this->log);
+        $this->log = array();
+        $this->lastGc = date('d');
+    }
+}
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Serve.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Serve.php
new file mode 100755 (executable)
index 0000000..19ecb0c
--- /dev/null
@@ -0,0 +1,159 @@
+<?php
+/**
+ * Phergie
+ *
+ * PHP version 5
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.
+ * It is also available through the world-wide-web at this URL:
+ * http://phergie.org/license
+ *
+ * @category  Phergie
+ * @package   Phergie_Plugin_Serve
+ * @author    Phergie Development Team <team@phergie.org>
+ * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
+ * @license   http://phergie.org/license New BSD License
+ * @link      http://pear.phergie.org/package/Phergie_Plugin_Serve
+ */
+
+/**
+ * Processes requests to serve a user something from a database.
+ *
+ * @category Phergie
+ * @package  Phergie_Plugin_Serve
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie_Plugin_Serve
+ * @uses     extension pdo
+ * @uses     extension pdo_sqlite
+ */
+class Phergie_Plugin_Serve extends Phergie_Plugin_Abstract
+{
+    /**
+     * Checks for dependencies.
+     *
+     * @return void
+     */
+    public function onLoad()
+    {
+        if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
+            $this->fail('PDO and pdo_sqlite extensions must be installed');
+        }
+    }
+
+    /**
+     * Retrieves a random item from the database table.
+     *
+     * @param string $database Path to the SQLite database file
+     * @param string $table    Name of the database table
+     * @param array  $request  Parsed request
+     *
+     * @return object Retrieved item
+     */
+    protected function getItem($database, $table, array $request)
+    {
+        $db = new PDO('sqlite:' . $database);
+        if (!empty($request['suggestion'])) {
+            $query = 'SELECT * FROM ' . $table . ' WHERE name LIKE ? ORDER BY RANDOM() LIMIT 1';
+            $stmt = $db->prepare($query);
+            $stmt->execute(array('%' . $request['suggestion'] . '%'));
+            $item = $stmt->fetchObject();
+            if (!$item) {
+                $item = new stdClass;
+                $item->name = $request['suggestion'];
+                $item->link = null;
+            }
+        } else {
+            $query = 'SELECT * FROM ' . $table . ' ORDER BY RANDOM() LIMIT 1';
+            $stmt = $db->query($query);
+            $item = $stmt->fetchObject();
+        }
+        return $item;
+    }
+
+    /**
+     * Processes a request to serve a user something.
+     *
+     * @param string $database Path to the SQLite database file
+     * @param string $table    Name of the database table
+     * @param string $format   Format of the response where %target%,
+     *        %item%, %article%', and %link will be replaced with their
+     *        respective data
+     * @param string $request  Request string including the target and an
+     *        optional suggestion of the item to fetch
+     * @param boolean $censor  TRUE to integrate with the Censor plugin,
+     *        defaults to FALSE
+     *
+     * @return boolean TRUE if the request was processed successfully, FALSE
+     *         otherwise
+     */
+    public function serve($database, $table, $format, $request, $censor = false)
+    {
+        // Parse the request
+        $result = preg_match(
+            '/(?P<target>[^\s]+)(\s+an?\s+)?(?P<suggestion>.*)?/',
+            $request,
+            $match
+        );
+
+        if (!$result) {
+            return false;
+        }
+
+        // Resolve the target
+        $target = $match['target'];
+        if ($target == 'me') {
+            $target = $this->event->getNick();
+        }
+
+        // Process the request
+        $item = $this->getItem($database, $table, $match);
+
+        // Reprocess the request for censorship if required
+        $attempts = 0;
+        while ($censor && $attempts < 3) {
+            $plugin = $this->plugins->getPlugin('Censor');
+            $clean = $plugin->cleanString($item->name);
+            if ($item->name != $clean) {
+                $attempts++;
+                $item = $this->getItem($database, $table, $match);
+            } else {
+                $censor = false;
+            }
+        }
+
+        if ($censor && $attempts == 3) {
+            $this->doAction($this->event->getSource(), 'shrugs.');
+        }
+
+        // Derive the proper article for the item
+        if (preg_match('/^[aeiou]/i', $item->name)) {
+            $article = 'an';
+        } else {
+            $article = 'a';
+        }
+
+        // Format the message
+        $replacements = array(
+            'target' => $target,
+            'item' => $item->name,
+            'link' => $item->link,
+            'article' => $article
+        );
+
+        $msg = $format;
+        foreach ($replacements as $placeholder => $value) {
+            $msg = str_replace(
+                '%' . $placeholder . '%',
+                $value,
+                $msg
+            );
+        }
+
+        // Send the message
+        $this->doAction($this->event->getSource(), $msg);
+    }
+}
index f0cee28184603f4ca2d2058f0372749b0f1e3aec..3da5fdf4fc7b1f1405698b533e3e9fd323504f33 100644 (file)
@@ -59,15 +59,8 @@ class Phergie_Plugin_Statusnet extends Phergie_Plugin_Abstract {
             $this->regCallback = NULL;\r
         }\r
 \r
-        $this->unregRegexp = $this->config['statusnet.unregregexp'];\r
-        if (!$this->unregRegexp) {\r
-            $this->unregRegexp = '/\x02(.*?)\x02 (?:isn\'t|is not) registered/i';\r
-        }\r
-\r
-        $this->regRegexp = $this->config['statusnet.regregexp'];\r
-        if (!$this->regRegexp) {\r
-            $this->regRegexp = '/(?:\A|\x02)(\w+?)\x02? (?:\(account|is \w+?\z)/i';\r
-        }\r
+        $this->unregRegexp = $this->getConfig('statusnet.unregregexp', '/\x02(.*?)\x02 (?:isn\'t|is not) registered/i');\r
+        $this->regRegexp = $this->getConfig('statusnet.regregexp', '/(?:\A|\x02)(\w+?)\x02? (?:\(account|is \w+?\z)/i');\r
     }\r
 \r
     /**\r
@@ -81,6 +74,10 @@ class Phergie_Plugin_Statusnet extends Phergie_Plugin_Abstract {
             $source = $event->getSource();\r
             $message = trim($event->getText());\r
 \r
+            if ($source == '#statustest') {\r
+                $this->doPrivmsg('#statustest', "\001Line1\020nLine2");\r
+            }\r
+\r
             call_user_func($this->messageCallback, array('sender' => $source, 'message' => $message));\r
         }\r
     }\r
@@ -103,4 +100,8 @@ class Phergie_Plugin_Statusnet extends Phergie_Plugin_Abstract {
             }\r
         }\r
     }\r
+\r
+    public function onTick() {\r
+        echo "\nTICK!\n";\r
+    }\r
 }\r
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Wine.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Wine.php
new file mode 100644 (file)
index 0000000..9aa0845
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Phergie
+ *
+ * PHP version 5
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.
+ * It is also available through the world-wide-web at this URL:
+ * http://phergie.org/license
+ *
+ * @category  Phergie
+ * @package   Phergie_Plugin_Wine
+ * @author    Phergie Development Team <team@phergie.org>
+ * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
+ * @license   http://phergie.org/license New BSD License
+ * @link      http://pear.phergie.org/package/Phergie_Plugin_Wine
+ */
+
+/**
+ * Processes requests to serve users wine.
+ *
+ * @category Phergie
+ * @package  Phergie_Plugin_Wine
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie_Plugin_Wine
+ * @uses     Phergie_Plugin_Command pear.phergie.org
+ * @uses     Phergie_Plugin_Serve pear.phergie.org
+ */
+class Phergie_Plugin_Wine extends Phergie_Plugin_Abstract
+{
+    /**
+     * Checks for dependencies.
+     *
+     * @return void
+     */
+    public function onLoad()
+    {
+        $plugins = $this->plugins;
+        $plugins->getPlugin('Command');
+        $plugins->getPlugin('Serve');
+    }
+
+    /**
+     * Processes requests to serve a user a wine.
+     *
+     * @param string $request Request including the target and an optional
+     *        suggestion of what wine to serve
+     *
+     * @return void
+     */
+    public function onCommandWine($request)
+    {
+        $format = $this->getConfig(
+            'wine.format',
+            'serves %target% a glass of %item%.'
+        );
+
+        $this->plugins->getPlugin('Serve')->serve(
+            dirname(__FILE__) . '/Wine/wine.db',
+            'wine',
+            $format,
+            $request
+        );
+    }
+}
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Wine/db.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Wine/db.php
new file mode 100644 (file)
index 0000000..ce01c2d
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+// Create database schema
+echo 'Creating database', PHP_EOL;
+$file = __DIR__ . '/wine.db';
+if (file_exists($file)) {
+    unlink($file);
+}
+$db = new PDO('sqlite:' . $file);
+$db->exec('CREATE TABLE wine (name VARCHAR(255), link VARCHAR(255))');
+$db->exec('CREATE UNIQUE INDEX wine_name ON wine (name)');
+$insert = $db->prepare('INSERT INTO wine (name, link) VALUES (:name, :link)');
+
+// Get and decompress lcboapi.com data set
+$outer = __DIR__ . '/current.zip';
+if (!file_exists($outer)) {
+    echo 'Downloading lcboapi.com data set', PHP_EOL;
+    copy('http://lcboapi.com/download/current.zip', $outer);
+}
+
+echo 'Decompressing lcboapi.com data set', PHP_EOL;
+$zip = new ZipArchive;
+$zip->open($outer);
+$stat = $zip->statIndex(0);
+$inner = __DIR__ . '/' . $stat['name'];
+$zip->extractTo(__DIR__);
+$zip->close();
+$zip = new ZipArchive;
+$zip->open($inner);
+$stat = $zip->statIndex(0);
+$file = __DIR__ . '/' . $stat['name'];
+$zip->extractTo(__DIR__);
+$zip->close();
+
+// Aggregate data set into the database
+$lcbo = new PDO('sqlite:' . $file);
+$result = $lcbo->query('SELECT product_no, name FROM products WHERE primary_category = "Wine"');
+$wines = $result->fetchAll();
+echo 'Processing lcboapi.com data - ', number_format(count($wines), 0), ' records', PHP_EOL;
+$db->beginTransaction();
+foreach ($wines as $wine) {
+    $name = $wine['name'];
+    $link = 'http://lcboapi.com/products/' . $wine['product_no'];
+    $insert->execute(array($name, $link));
+}
+$db->commit();
+
+// Clean up
+echo 'Cleaning up', PHP_EOL;
+unset($lcbo);
+unlink($outer);
+unlink($inner);
+unlink($file);
index 4946152bb30c37ae0cb33b1d4446519e5be7ba01..e553ad5a8252850d9de50ecec3ef05a047150e74 100644 (file)
@@ -37,14 +37,14 @@ class Phergie_Process_Async extends Phergie_Process_Abstract
      *
      * @var int
      */
-    protected $sec;
+    protected $sec = 0;
 
     /**
      * Length of time to poll for stream activity (microseconds)
      *
      * @var int
      */
-    protected $usec;
+    protected $usec = 200000;
 
     /**
      * Length of time to wait between ticks.
@@ -87,7 +87,7 @@ class Phergie_Process_Async extends Phergie_Process_Abstract
             }
         }
 
-        if (isset($this->sec) && isset($this->usec)) {
+        if (!isset($this->sec) && !isset($this->usec)) {
             throw new Phergie_Process_Exception(
                 'One of the processor options "sec" or "usec" must be specified'
             );
index 5fe65444b17d0079ad1fd7469d75fe68bb3b464e..9c1b3a6f18e305101a33fd38eaad9d3dd17af82c 100644 (file)
@@ -62,7 +62,7 @@ class Phergie_StatusnetBot extends Phergie_Bot {
     *\r
     * @return void\r
     */\r
-    public function receive() {\r
+    public function handleEvents() {\r
         $this->getProcessor()->handleEvents();\r
     }\r
 \r
index 8c04da68fcba19fb0a8dbb28d9dce02713f3de0b..933cc0387887fae3b9adeed8bf012234dfff571a 100644 (file)
@@ -64,6 +64,19 @@ class IrcManager extends ImManager {
         }
     }
 
+    /**
+     * Idle processing for io manager's execution loop.
+     * Send keepalive pings to server.
+     *
+     * @return void
+     */
+    public function idle() {
+        // Call Phergie's doTick methods if necessary
+        echo "BEGIN IDLE\n";
+        $this->conn->handleEvents();
+        echo "END IDLE\n";
+    }
+
     /**
      * Process IRC events that have come in over the wire.
      *
@@ -73,7 +86,7 @@ class IrcManager extends ImManager {
     public function handleInput($socket) {
         common_log(LOG_DEBUG, 'Servicing the IRC queue.');
         $this->stats('irc_process');
-        $this->conn->receive();
+        $this->conn->handleEvents();
     }
 
     /**
@@ -91,7 +104,7 @@ class IrcManager extends ImManager {
                     'connections' => array(
                         array(
                             'host' => $this->plugin->host,
-                            'port' => $port,
+                            'port' => $this->plugin->port,
                             'username' => $this->plugin->username,
                             'realname' => $this->plugin->realname,
                             'nick' => $this->plugin->nick,
@@ -104,7 +117,7 @@ class IrcManager extends ImManager {
                     'driver' => 'statusnet',
 
                     'processor' => 'async',
-                    'processor.options' => array('usec' => 0),
+                    'processor.options' => array('sec' => 0, 'usec' => 0),
 
                     'plugins' => array(
                         'Pong',
@@ -118,9 +131,14 @@ class IrcManager extends ImManager {
                     'ui.enabled' => true,
 
                     'nickserv.password' => $this->plugin->nickservpassword,
+                    'nickserv.identify_message' => $this->plugin->nickservidentifyregexp,
+
                     'autojoin.channels' => $this->plugin->channels,
+
                     'statusnet.messagecallback' => array($this, 'handle_irc_message'),
-                    'statusnet.regcallback' => array($this, 'handle_reg_response')
+                    'statusnet.regcallback' => array($this, 'handle_reg_response'),
+                    'statusnet.unregregexp' => $this->plugin->unregregexp,
+                    'statusnet.regregexp' => $this->plugin->regregexp
                 )
             );
 
@@ -215,8 +233,12 @@ class IrcManager extends ImManager {
             $this->regchecksLookup[$usernick] = $screenname;
         }
 
+        $args = $data['data']['args'];
+        $lines = explode("\n", $args[1]);
         try {
-            $this->conn->send($data['data']['command'], $data['data']['args']);
+            foreach ($lines as $line) {
+                $this->conn->send($data['data']['command'], array($args[0], $line));
+            }
         } catch (Phergie_Driver_Exception $e) {
             $this->conn->reconnect();
             return false;