]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merged in Phergie changes
authorLuke Fitzgerald <lw.fitzgerald@googlemail.com>
Tue, 3 Aug 2010 16:42:02 +0000 (09:42 -0700)
committerLuke Fitzgerald <lw.fitzgerald@googlemail.com>
Tue, 3 Aug 2010 16:42:02 +0000 (09:42 -0700)
30 files changed:
plugins/Irc/extlib/phergie/Phergie/Beer/db.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Connection.php
plugins/Irc/extlib/phergie/Phergie/Connection/Exception.php
plugins/Irc/extlib/phergie/Phergie/Driver/Streams.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Acl.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Caffeine.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Caffeine/db.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Command.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Cookie/db.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Daddy.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Google.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Handler.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Help.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Http.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Ideone.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Iterator.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Karma.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Message.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Ping.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Quit.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Reload.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Serve.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Tea.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/Tea/db.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Phergie/Plugin/TheFuckingWeather.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Tld.php
plugins/Irc/extlib/phergie/Phergie/Plugin/Youtube.php
plugins/Irc/extlib/phergie/Phergie/Process/Abstract.php
plugins/Irc/extlib/phergie/Phergie/Process/Async.php
plugins/Irc/extlib/phergie/Phergie/Process/Standard.php

diff --git a/plugins/Irc/extlib/phergie/Phergie/Beer/db.php b/plugins/Irc/extlib/phergie/Phergie/Beer/db.php
new file mode 100644 (file)
index 0000000..c7921e5
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+
+if (!defined('__DIR__')) {
+    define('__DIR__', dirname(__FILE__));
+}
+
+// Create database schema
+echo 'Creating database', PHP_EOL;
+$file = __DIR__ . '/beer.db';
+if (file_exists($file)) {
+    unlink($file);
+}
+$db = new PDO('sqlite:' . $file);
+$db->exec('CREATE TABLE beer (name VARCHAR(255), link VARCHAR(255))');
+$db->exec('CREATE UNIQUE INDEX beer_name ON beer (name)');
+$insert = $db->prepare('INSERT INTO beer (name, link) VALUES (:name, :link)');
+
+// Get raw beerme.com data set
+echo 'Downloading beerme.com data set', PHP_EOL;
+$file = __DIR__ . '/beerlist.txt';
+if (!file_exists($file)) {
+    copy('http://beerme.com/beerlist.php', $file);
+}
+$contents = file_get_contents($file);
+
+// Extract data from data set
+echo 'Processing beerme.com data', 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);
+$beers = $xpath->query('//table[@class="beerlist"]/tr/td[1]');
+$db->beginTransaction();
+foreach ($beers as $beer) {
+    $name = iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $beer->textContent);
+    $name = preg_replace('/\h*\v+\h*/', '', $name);
+    $link = 'http://beerme.com' . $beer->childNodes->item(1)->getAttribute('href');
+    $insert->execute(array($name, $link));
+}
+$db->commit();
+
+// Clean up
+echo 'Cleaning up', PHP_EOL;
+unlink($file);
+
+// Get and decompress openbeerdb.com data set
+$archive = __DIR__ . '/beers.zip';
+if (!file_exists($archive)) {
+    echo 'Downloading openbeerdb.com data set', PHP_EOL;
+    copy('http://openbeerdb.googlecode.com/files/beers.zip', $archive);
+}
+
+echo 'Decompressing openbeerdb.com data set', PHP_EOL;
+$zip = new ZipArchive;
+$zip->open($archive);
+$zip->extractTo(__DIR__, 'beers/beers.csv');
+$zip->close();
+$file = __DIR__ . '/beers/beers.csv';
+
+// Extract data from data set
+echo 'Processing openbeerdb.com data', PHP_EOL;
+$fp = fopen($file, 'r');
+$columns = fgetcsv($fp, 0, '|');
+$db->beginTransaction();
+while ($line = fgetcsv($fp, 0, '|')) {
+    $line = array_combine($columns, $line);
+    $name = iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $line['name']);
+    $name = preg_replace('/\h*\v+\h*/', '', $name);
+    $link = null;
+    $insert->execute(array($name, $link));
+}
+$db->commit();
+fclose($fp);
+
+// Clean up
+echo 'Cleaning up', PHP_EOL;
+unlink($file);
+unlink($archive);
+rmdir(__DIR__ . '/beers');
index d6c89ea8018159172f28bc0bf44386dacdd28401..b3f0acf83d41971c36c6ec65c22e9e9b2e12dba4 100755 (executable)
@@ -254,7 +254,7 @@ class Phergie_Connection
         if (!in_array($this->encoding, mb_list_encodings())) {
             throw new Phergie_Connection_Exception(
                 'Encoding ' . $this->encoding . ' is not supported',
-                Phergie_Connection_Exception::ENCODING_NOT_SUPPORTED
+                Phergie_Connection_Exception::ERR_ENCODING_NOT_SUPPORTED
             );
         }
 
index a750e1d8607146259e93ae15079f624e56bf224a..aec1cd8e0ff9779bc1cf5f33495d219fdae383de 100644 (file)
@@ -41,4 +41,10 @@ class Phergie_Connection_Exception extends Phergie_Exception
      * but that transport is not supported by the current PHP installation
      */
     const ERR_TRANSPORT_NOT_SUPPORTED = 2;
+
+    /**
+     * Error indicating that a connection is configured to use an encoding,
+     * but that encoding is not supported by the current PHP installation
+     */
+    const ERR_ENCODING_NOT_SUPPORTED = 3;
 }
index 3f2ce052b1fc780f60d2427881c73f001137d8d8..73c0230c714c5d74452a2055fc42478a14aeb404 100755 (executable)
@@ -243,6 +243,7 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
 
             // Parse the command and arguments
             list($cmd, $args) = array_pad(explode(' ', $buffer, 2), 2, null);
+            $hostmask = new Phergie_Hostmask(null, null, $this->connection->getHost());
 
         } else {
             // If the event could be from the server or a user...
index 9738df60e052b0651f2477560b2c12646ed20135..e209e32e142ee8cb729707a7b62af90a0c793dbb 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Phergie 
+ * Phergie
  *
  * PHP version 5
  *
@@ -11,7 +11,7 @@
  * It is also available through the world-wide-web at this URL:
  * http://phergie.org/license
  *
- * @category  Phergie 
+ * @category  Phergie
  * @package   Phergie_Plugin_Acl
  * @author    Phergie Development Team <team@phergie.org>
  * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
  */
 
 /**
- * Provides an access control system to limit reponses to events based on 
+ * Provides an access control system to limit reponses to events based on
  * the users who originate them.
  *
- * @category Phergie 
+ * Configuration settings:
+ * acl.whitelist - mapping of user hostmask patterns (optionally by host) to
+ *                 plugins and methods where those plugins and methods will
+ *                 only be accessible to those users (i.e. and inaccessible
+ *                 to other users)
+ * acl.blacklist - mapping of user hostmasks (optionally by host) to plugins
+ *                 and methods where where those plugins and methods will be
+ *                 inaccessible to those users but accessible to other users
+ * acl.ops       - TRUE to automatically give access to whitelisted plugins
+ *                 and methods to users with ops for events they initiate in
+ *                 channels where they have ops
+ *
+ * The whitelist and blacklist settings are formatted like so:
+ * <code>
+ * 'acl.whitelist' => array(
+ *     'hostname1' => array(
+ *         'pattern1' => array(
+ *             'plugins' => array(
+ *                 'ShortPluginName'
+ *             ),
+ *             'methods' => array(
+ *                 'methodName'
+ *             )
+ *         ),
+ *     )
+ * ),
+ * </code>
+ *
+ * The hostname array dimension is optional; if not used, rules will be
+ * applied across all connections. The pattern is a user hostmask pattern
+ * where asterisks (*) are used for wildcards. Plugins and methods do not
+ * need to be set to empty arrays if they are not used; simply exclude them.
+ *
+ * @category Phergie
  * @package  Phergie_Plugin_Acl
  * @author   Phergie Development Team <team@phergie.org>
  * @license  http://phergie.org/license New BSD License
  * @link     http://pear.phergie.org/package/Phergie_Plugin_Acl
+ * @uses     Phergie_Plugin_UserInfo pear.phergie.org
  */
 class Phergie_Plugin_Acl extends Phergie_Plugin_Abstract
 {
@@ -38,6 +72,8 @@ class Phergie_Plugin_Acl extends Phergie_Plugin_Abstract
      */
     public function onLoad()
     {
+        $this->plugins->getPlugin('UserInfo');
+
         if (!$this->getConfig('acl.blacklist')
             && !$this->getConfig('acl.whitelist')
         ) {
@@ -46,47 +82,105 @@ class Phergie_Plugin_Acl extends Phergie_Plugin_Abstract
     }
 
     /**
-     * Checks permission settings and short-circuits event processing for 
+     * Applies a set of rules to a plugin handler iterator.
+     *
+     * @param Phergie_Plugin_Iterator $iterator Iterator to receive rules
+     * @param array                   $rules    Associate array containing
+     *        either a 'plugins' key pointing to an array containing plugin
+     *        short names to filter, a 'methods' key pointing to an array
+     *        containing method names to filter, or both
+     *
+     * @return void
+     */
+    protected function applyRules(Phergie_Plugin_Iterator $iterator, array $rules)
+    {
+        if (!empty($rules['plugins'])) {
+            $iterator->addPluginFilter($rules['plugins']);
+        }
+        if (!empty($rules['methods'])) {
+            $iterator->addMethodFilter($rules['methods']);
+        }
+    }
+
+    /**
+     * Checks permission settings and short-circuits event processing for
      * blacklisted users.
      *
-     * @return bool FALSE to short-circuit event processing if the user is 
-     *         blacklisted, TRUE otherwise
+     * @return void
      */
     public function preEvent()
     {
         // Ignore server responses
         if ($this->event instanceof Phergie_Event_Response) {
-            return true;
+            return;
         }
 
         // Ignore server-initiated events
         if (!$this->event->isFromUser()) {
-            return true;
+            return;
         }
 
-        // Determine whether a whitelist or blacklist is being used
-        $list = $this->getConfig('acl.whitelist');
-        $matches = true;
-        if (!$list) {
-            $list = $this->getConfig('acl.blacklist');
-            $matches = false;
-        }
+        // Get the iterator used to filter plugins when processing events
+        $iterator = $this->plugins->getIterator();
+
+        // Get configuration setting values
+        $whitelist = $this->getConfig('acl.whitelist', array());
+        $blacklist = $this->getConfig('acl.blacklist', array());
+        $ops = $this->getConfig('acl.ops', false);
 
-        // Support host-specific lists 
+        // Support host-specific lists
         $host = $this->connection->getHost();
-        if (isset($list[$host])) {
-            $list = $list[$host];
+        foreach (array('whitelist', 'blacklist') as $var) {
+            foreach ($$var as $pattern => $rules) {
+                $regex = '/^' . str_replace('*', '.*', $pattern) . '$/i';
+                if (preg_match($regex, $host)) {
+                    ${$var} = ${$var}[$pattern];
+                    break;
+                }
+            }
         }
 
-        // Short-circuit event processing if appropriate 
+        // Get information on the user initiating the current event
         $hostmask = $this->event->getHostmask();
-        foreach ($list as $pattern) {
+        $isOp = $ops
+              && $this->event->isInChannel()
+              && $this->plugins->userInfo->isOp(
+                $this->event->getNick(),
+                $this->event->getSource()
+              );
+
+        // Filter whitelisted commands if the user is not on the whitelist
+        if (!$isOp) {
+            $whitelisted = false;
+            foreach ($whitelist as $pattern => $rules) {
+                if ($hostmask->matches($pattern)) {
+                    $whitelisted = true;
+                }
+            }
+            if (!$whitelisted) {
+                foreach ($whitelist as $pattern => $rules) {
+                    $this->applyRules($iterator, $rules);
+                }
+            }
+        }
+
+        // Filter blacklisted commands if the user is on the blacklist
+        $blacklisted = false;
+        foreach ($blacklist as $pattern => $rules) {
             if ($hostmask->matches($pattern)) {
-                return $matches;
+                $this->applyRules($iterator, $rules);
+                break;
             }
         }
+    }
 
-        // Allow event processing if appropriate 
-        return !$matches;
+    /**
+     * Clears filters on the plugin handler iterator.
+     *
+     * @return void
+     */
+    public function postDispatch()
+    {
+        $this->plugins->getIterator()->clearFilters();
     }
 }
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Caffeine.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Caffeine.php
new file mode 100644 (file)
index 0000000..2b76bd3
--- /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_Caffeine
+ * @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_Caffeine
+ */
+
+/**
+ * Processes requests to serve users caffeinated beverages.
+ *
+ * @category Phergie
+ * @package  Phergie_Plugin_Caffeine
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie_Plugin_Caffeine
+ * @uses     Phergie_Plugin_Command pear.phergie.org
+ * @uses     Phergie_Plugin_Serve pear.phergie.org
+ */
+class Phergie_Plugin_Caffeine 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 caffeinated beverage.
+     *
+     * @param string $request Request including the target and an optional
+     *        suggestion of what caffeinated beverage to serve
+     *
+     * @return void
+     */
+    public function onCommandCaffeine($request)
+    {
+        $format = $this->getConfig(
+            'beer.format',
+            'throws %target% %article% %item%.'
+        );
+
+        $this->plugins->getPlugin('Serve')->serve(
+            dirname(__FILE__) . '/Caffeine/caffeine.db',
+            'caffeine',
+            $format,
+            $request
+        );
+    }
+}
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Caffeine/db.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Caffeine/db.php
new file mode 100644 (file)
index 0000000..cdff52f
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+
+if (!defined('__DIR__')) {
+    define('__DIR__', dirname(__FILE__));
+}
+
+// Create database schema
+echo 'Creating database', PHP_EOL;
+$file = __DIR__ . '/caffeine.db';
+if (file_exists($file)) {
+    unlink($file);
+}
+$db = new PDO('sqlite:' . $file);
+$db->exec('CREATE TABLE caffeine (name VARCHAR(255), link VARCHAR(255))');
+$db->exec('CREATE UNIQUE INDEX caffeine_name ON caffeine (name)');
+$insert = $db->prepare('INSERT INTO caffeine (name, link) VALUES (:name, :link)');
+
+// Get raw energyfiend.com data set
+echo 'Downloading energyfiend.com data set', PHP_EOL;
+$file = __DIR__ . '/the-caffeine-database.html';
+if (!file_exists($file)) {
+    copy('http://www.energyfiend.com/the-caffeine-database', $file);
+}
+$contents = file_get_contents($file);
+
+// Extract data from data set
+echo 'Processing energyfiend.com data', 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);
+$caffeine = $xpath->query('//table[@id="caffeinedb"]//tr/td[1]');
+$db->beginTransaction();
+foreach ($caffeine as $drink) {
+    $name = iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $drink->textContent);
+    $name = preg_replace('/\s*\v+\s*/', ' ', $name);
+    if ($drink->firstChild->nodeName == 'a') {
+        $link = 'http://energyfiend.com'
+              . $drink->firstChild->getAttribute('href');
+    } else {
+        $link = null;
+    }
+    $insert->execute(array($name, $link));
+}
+$db->commit();
+
+// Clean up
+echo 'Cleaning up', PHP_EOL;
+unlink($file);
index 2ab5b69d1d6a50684379c9a9e97696aa292e7d57..48352b15dd3d8835be01b46d5a0afedf815c3d36 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Phergie 
+ * Phergie
  *
  * PHP version 5
  *
@@ -11,7 +11,7 @@
  * It is also available through the world-wide-web at this URL:
  * http://phergie.org/license
  *
- * @category  Phergie 
+ * @category  Phergie
  * @package   Phergie_Plugin_Command
  * @author    Phergie Development Team <team@phergie.org>
  * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
  */
 
 /**
- * Handles parsing and execution of commands sent by users via messages sent 
+ * Handles parsing and execution of commands sent by users via messages sent
  * to channels in which the bot is present or directly to the bot.
  *
- * @category Phergie 
+ * @category Phergie
  * @package  Phergie_Plugin_Command
  * @author   Phergie Development Team <team@phergie.org>
  * @license  http://phergie.org/license New BSD License
  * @link     http://pear.phergie.org/package/Phergie_Plugin_Command
  * @uses     extension reflection
+ * @uses     Phergie_Plugin_Message pear.phergie.org
  */
 class Phergie_Plugin_Command extends Phergie_Plugin_Abstract
 {
     /**
-     * Cache for command lookups used to confirm that methods exist and 
+     * Prefix for command method names
+     *
+     * @var string
+     */
+    const METHOD_PREFIX = 'onCommand';
+
+    /**
+     * Cache for command lookups used to confirm that methods exist and
      * parameter counts match
      *
      * @var array
@@ -41,24 +49,28 @@ class Phergie_Plugin_Command extends Phergie_Plugin_Abstract
     protected $methods = array();
 
     /**
-     * Prefix for command method names
+     * Load the Message plugin
      *
-     * @var string
+     * @return void
      */
-    protected $methodPrefix = 'onCommand';
+    public function onLoad()
+    {
+        $plugins = $this->getPluginHandler();
+        $plugins->getPlugin('Message');
+    }
 
     /**
      * Populates the methods cache.
      *
      * @return void
      */
-    protected function populateMethodCache()
+    public function populateMethodCache()
     {
         foreach ($this->getPluginHandler() as $plugin) {
             $reflector = new ReflectionClass($plugin);
             foreach ($reflector->getMethods() as $method) {
                 $name = $method->getName();
-                if (strpos($name, $this->methodPrefix) === 0 
+                if (strpos($name, self::METHOD_PREFIX) === 0
                     && !isset($this->methods[$name])
                 ) {
                     $this->methods[$name] = array(
@@ -84,26 +96,26 @@ class Phergie_Plugin_Command extends Phergie_Plugin_Abstract
             $this->populateMethodCache();
         }
 
-        // Get the content of the message
-        $event = $this->getEvent();
-        $msg = trim($event->getText());
-        $prefix = $this->getConfig('command.prefix');
-
-        // Check for the command prefix if one is set and needed
-        if ($prefix && $event->isInChannel()) {
-            if (strpos($msg, $prefix) !== 0) {
-                return;
-            } else {
-                $msg = substr($msg, strlen($prefix));
-            }
+        // Check for a prefixed message
+        $msg = $this->plugins->message->getMessage();
+        if ($msg === false) {
+            return;
         }
 
         // Separate the command and arguments
         $parsed = preg_split('/\s+/', $msg, 2);
-        $method = $this->methodPrefix . ucfirst(strtolower(array_shift($parsed))); 
+        $command = strtolower(array_shift($parsed));
         $args = count($parsed) ? array_shift($parsed) : '';
 
+        // Resolve aliases to their corresponding commands
+        $aliases = $this->getConfig('command.aliases', array());
+        $result = preg_grep('/^' . $command . '$/i', array_keys($aliases));
+        if ($result) {
+            $command = $aliases[array_shift($result)];
+        }
+
         // Check to ensure the command exists
+        $method = self::METHOD_PREFIX . ucfirst($command);
         if (empty($this->methods[$method])) {
             return;
         }
@@ -122,7 +134,7 @@ class Phergie_Plugin_Command extends Phergie_Plugin_Abstract
             // Parse the arguments
             $args = preg_split('/\s+/', $args, $this->methods[$method]['total']);
 
-            // If the minimum arguments are passed, call the method 
+            // If the minimum arguments are passed, call the method
             if ($this->methods[$method]['required'] <= count($args)) {
                 call_user_func_array(
                     array($this->getPluginHandler(), $method),
index 91d375ca6d714bd6f14eecf96345e2fe5f089775..27763159cc11ce246a5abfff5e71925ea7ba510f 100644 (file)
@@ -36,9 +36,6 @@ $cookies = $xpath->query('//table[@width="90%"]/tr/td[1]/a');
 
 foreach ($cookies as $cookie) {
     $name = $cookie->textContent;
-    foreach (range(0, mb_strlen($name) - 1) as $index) {
-        echo mb_strcut($name, $index, 1), PHP_EOL;
-    }
     $name = str_replace(
         array('(',')',"\n", 'cookies'),
         array('','', ' ', 'cookie'),
index d47c3c41d30509f3e32866a7321c2fca6bfe369e..ed258e10ffda6e28e2b294ea4fe5c5547e55842c 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Phergie 
+ * Phergie
  *
  * PHP version 5
  *
@@ -11,7 +11,7 @@
  * It is also available through the world-wide-web at this URL:
  * http://phergie.org/license
  *
- * @category  Phergie 
+ * @category  Phergie
  * @package   Phergie_Plugin_Daddy
  * @author    Phergie Development Team <team@phergie.org>
  * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
@@ -23,7 +23,7 @@
  * Simply responds to messages addressed to the bot that contain the phrase
  * "Who's your daddy?" and related variations.
  *
- * @category Phergie 
+ * @category Phergie
  * @package  Phergie_Plugin_Daddy
  * @author   Phergie Development Team <team@phergie.org>
  * @license  http://phergie.org/license New BSD License
@@ -45,15 +45,11 @@ class Phergie_Plugin_Daddy extends Phergie_Plugin_Abstract
         $text = $event->getArgument(1);
         $target = $event->getNick();
         $source = $event->getSource();
-        $pattern 
-            = '/' . preg_quote($prefix) . 
+        $pattern
+            = '/' . preg_quote($prefix) .
             '\s*?who\'?s y(?:our|a) ([^?]+)\??/iAD';
         if (preg_match($pattern, $text, $m)) {
-            if ($config['daddy.curses'] && mt_rand(0, 5) === 5) {
-                $msg = $target . ': I am your ' . $m[1] . ', bitch!';
-            } else {
-                $msg = 'You\'re my ' . $m[1] . ', ' . $target . '!';
-            }
+            $msg = 'You\'re my ' . $m[1] . ', ' . $target . '!';
             $this->doPrivmsg($source, $msg);
         }
     }
index faa98f926abe0f089040bba8265a12c4566b0026..d2a9d4dce991854c248ab4067ac7e5b0a00fbf1b 100644 (file)
  * @uses     Phergie_Plugin_Command pear.phergie.org
  * @uses     Phergie_Plugin_Http pear.phergie.org
  * @uses     Phergie_Plugin_Temperature pear.phergie.org
- *
- * @pluginDesc Provide access to some Google services
  */
 class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
 {
-
-    /**
-     * HTTP plugin
-     *
-     * @var Phergie_Plugin_Http
-     */
-    protected $http;
-
-    /**
-     * Language for Google Services
-     */
-    protected $lang;
-
     /**
      * Checks for dependencies.
      *
@@ -59,11 +44,8 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
     {
         $plugins = $this->getPluginHandler();
         $plugins->getPlugin('Command');
-        $this->http = $plugins->getPlugin('Http');
-        $plugins->getPlugin('Help')->register($this);
+        $plugins->getPlugin('Http');
         $plugins->getPlugin('Weather');
-
-        $this->lang = $this->getConfig('google.lang', 'en');
     }
 
     /**
@@ -73,8 +55,6 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
      *
      * @return void
      * @todo Implement use of URL shortening here
-     *
-     * @pluginCmd [query] do a search on google
      */
     public function onCommandG($query)
     {
@@ -83,7 +63,7 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
             'v' => '1.0',
             'q' => $query
         );
-        $response = $this->http->get($url, $params);
+        $response = $this->plugins->http->get($url, $params);
         $json = $response->getContent()->responseData;
         $event = $this->getEvent();
         $source = $event->getSource();
@@ -110,8 +90,6 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
      * @param string $query Search term
      *
      * @return void
-     *
-     * @pluginCmd [query] Do a search on Google and count the results
      */
     public function onCommandGc($query)
     {
@@ -120,7 +98,7 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
             'v' => '1.0',
             'q' => $query
         );
-        $response = $this->http->get($url, $params);
+        $response = $this->plugins->http->get($url, $params);
         $json = $response->getContent()->responseData->cursor;
         $count = $json->estimatedResultCount;
         $event = $this->getEvent();
@@ -146,8 +124,6 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
      * @param string $query Term to translate
      *
      * @return void
-     *
-     * @pluginCmd [from language] [to language] [text to translate] Do a translation on Google
      */
     public function onCommandGt($from, $to, $query)
     {
@@ -157,7 +133,7 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
             'q' => $query,
             'langpair' => $from . '|' . $to
         );
-        $response = $this->http->get($url, $params);
+        $response = $this->plugins->http->get($url, $params);
         $json = $response->getContent();
         $event = $this->getEvent();
         $source = $event->getSource();
@@ -180,18 +156,16 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
      *        between 0 and 3 to get the forecast
      *
      * @return void
-     *
-     * @pluginCmd [location] Show the weather for the specified location
      */
     public function onCommandGw($location, $offset = null)
     {
         $url = 'http://www.google.com/ig/api';
         $params = array(
             'weather' => $location,
-            'hl' => $this->lang,
+            'hl' => $this->getConfig('google.lang', 'en'),
             'oe' => 'UTF-8'
         );
-        $response = $this->http->get($url, $params);
+        $response = $this->plugins->http->get($url, $params);
         $xml = $response->getContent()->weather;
 
         $event = $this->getEvent();
@@ -280,8 +254,6 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
      * @param string $location Location to search for
      *
      * @return void
-     *
-     * @pluginCmd [location] Get the location from Google Maps to the location specified
      */
     public function onCommandGmap($location)
     {
@@ -294,13 +266,13 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
         $params = array(
             'q' => $location,
             'output' => 'json',
-            'gl' => $this->lang,
+            'gl' => $this->getConfig('google.lang', 'en'),
             'sensor' => 'false',
             'oe' => 'utf8',
             'mrt' => 'all',
             'key' => $this->getConfig('google.key')
         );
-        $response = $this->http->get($url, $params);
+        $response = $this->plugins->http->get($url, $params);
         $json =  $response->getContent();
         if (!empty($json)) {
             $qtd = count($json->Placemark);
@@ -345,8 +317,6 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
      * @param string $to    Destination metric
      *
      * @return void
-     *
-     * @pluginCmd [value] [currency from] [currency to] Converts a monetary value from one currency to another
      */
     public function onCommandGconvert($value, $from, $to)
     {
@@ -356,29 +326,21 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
             'from' => $from,
             'to' => $to
         );
-        $response = $this->http->get($url, $params);
+        $response = $this->plugins->http->get($url, $params);
         $contents = $response->getContent();
         $event = $this->getEvent();
         $source = $event->getSource();
         $nick = $event->getNick();
         if ($contents) {
-            preg_match(
-                '#<span class=bld>.*? ' . $to . '</span>#im',
-                $contents,
-                $matches
-            );
-            if (!$matches[0]) {
-                $this->doPrivmsg($source, $nick . ', I can\'t do that.');
-            } else {
-                $str = str_replace('<span class=bld>', '', $matches[0]);
-                $str = str_replace($to . '</span>', '', $str);
-                $text
-                    = number_format($value, 2, ',', '.') . ' ' . $from .
-                    ' => ' . number_format($str, 2, ',', '.') . ' ' . $to;
-                $this->doPrivmsg($source, $text);
-            }
-        } else {
-            $this->doPrivmsg($source, $nick . ', we had a problem.');
+            libxml_use_internal_errors(true);
+            $doc = new DOMDocument;
+            $doc->loadHTML($contents);
+            libxml_clear_errors();
+            $xpath = new DOMXPath($doc);
+            $result = $xpath->query('//div[@id="currency_converter_result"]');
+            $div = $result->item(0);
+            $text = rtrim($div->textContent);
+            $this->doPrivmsg($source, $text);
         }
     }
 
@@ -395,7 +357,7 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
     public function onCommandConvert($query)
     {
         $url = 'http://www.google.com/search?q=' . urlencode($query);
-        $response = $this->http->get($url);
+        $response = $this->plugins->http->get($url);
         $contents = $response->getContent();
         $event = $this->getEvent();
         $source = $event->getSource();
@@ -434,49 +396,61 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
      *
      * @return void
      * @todo Implement use of URL shortening here
-     *
-     * @pluginCmd [query] do a search of a definition on Google Dictionary
      */
     public function onCommandDefine($query)
     {
-        $query = urlencode($query);
-        $url = 'http://www.google.com/dictionary/json?callback=result'.
-               '&q='.$query.'&sl='.$this->lang.'&tl='.$this->lang.
-               '&restrict=pr,de';
-        $json = file_get_contents($url);
-
-        //Remove some garbage from the json
-        $json = str_replace(array("result(", ",200,null)"), "", $json);
+        $lang = $this->getConfig('google.lang', 'en');
+        $url = 'http://www.google.com/dictionary/json';
+        $params = array(
+            'callback' => 'result',
+            'q' => $query,
+            'sl' => $lang,
+            'tl' => $lang,
+            'restrict' => 'pr,de'
+        );
+        $response = $this->plugins->http->get($url, $params);
+        $json = $response->getContent();
 
-        //Awesome workaround to remove a lot of slashes from json
+        // Remove some garbage from the JSON and decode it
+        $json = str_replace(array('result(', ',200,null)'), '', $json);
         $json = str_replace('"', '¿?¿', $json);
         $json = strip_tags(stripcslashes($json));
         $json = str_replace('"', "'", $json);
         $json = str_replace('¿?¿', '"', $json);
-
         $json = json_decode($json);
 
         $event = $this->getEvent();
         $source = $event->getSource();
         $nick = $event->getNick();
-        if (!empty($json->webDefinitions)){
-            $results = count($json->webDefinitions[0]->entries);
-            $more = $results > 1 ? ($results-1).' ' : NULL;
-            $lang_code = substr($this->lang, 0, 2);
-            $msg =
-                $nick . ': ' .
-                $json->webDefinitions[0]->entries[0]->terms[0]->text .
-                ' - You can find more '.$more.'results at '.
-                'http://www.google.com/dictionary?aq=f&langpair='.
-                $lang_code.'%7C'.$lang_code.'&q='.$query.'&hl='.$lang_code;
+        if (!empty($json->webDefinitions)) {
+            $results = 0;
+            foreach ($json->primaries[0]->entries as $entry) {
+                if ($entry->type == 'meaning') {
+                    $results++;
+                    if (empty($text)) {
+                        foreach ($entry->terms as $term) {
+                            if ($term->type == 'text') {
+                                $text = trim($term->text);
+                            }
+                        }
+                    }
+                }
+            }
+            $more = $results > 1 ? ($results - 1) . ' ' : '';
+            $lang_code = substr($lang, 0, 2);
+            $msg = $nick . ': ' . $text
+                 . ' - You can find ' . $more . 'more results at '
+                 . 'http://www.google.com/dictionary'
+                 . '?aq=f'
+                 . '&langpair=' . $lang_code . '%7C' . $lang_code
+                 . '&q=' . $query
+                 . '&hl=' . $lang_code;
             $this->doPrivmsg($source, $msg);
-        }else{
-            if ($this->lang != 'en'){
-               $temp = $this->lang;
-               $this->lang = 'en';
+        } else {
+            if ($lang != 'en'){
+               $lang = 'en';
                $this->onCommandDefine($query);
-               $this->lang = $temp;
-            }else{
+            } else {
                $msg = $nick . ': No results for this query.';
                $this->doPrivmsg($source, $msg);
             }
index b2ef089b44cee0071f08126996dcda039216a138..4304bef99e3c7214817ffb95fb3bab588378fccc 100755 (executable)
@@ -68,6 +68,14 @@ class Phergie_Plugin_Handler implements IteratorAggregate, Countable
      */
     protected $events;
 
+    /**
+     * Iterator used for selectively proxying method calls to contained
+     * plugins
+     *
+     * @var Iterator
+     */
+    protected $iterator;
+
     /**
      * Constructor to initialize class properties and add the path for core
      * plugins.
@@ -416,26 +424,39 @@ class Phergie_Plugin_Handler implements IteratorAggregate, Countable
      */
     public function getIterator()
     {
-        return new ArrayIterator($this->plugins);
+        if (empty($this->iterator)) {
+            $this->iterator = new Phergie_Plugin_Iterator(
+                new ArrayIterator($this->plugins)
+            );
+        }
+        return $this->iterator;
     }
 
     /**
-     * Proxies method calls to all plugins containing the called method. An
-     * individual plugin may short-circuit this process by explicitly
-     * returning FALSE.
+     * Sets the iterator for all currently loaded plugin instances.
+     *
+     * @param Iterator $iterator Plugin iterator
+     *
+     * @return Phergie_Plugin_Handler Provides a fluent interface
+     */
+    public function setIterator(Iterator $iterator)
+    {
+        $this->iterator = $iterator;
+        return $this;
+    }
+
+    /**
+     * Proxies method calls to all plugins containing the called method.
      *
      * @param string $name Name of the method called
      * @param array  $args Arguments passed in the method call
      *
-     * @return bool FALSE if a plugin short-circuits processing by returning
-     *         FALSE, TRUE otherwise
+     * @return void
      */
     public function __call($name, array $args)
     {
-        foreach ($this->plugins as $plugin) {
-            if (call_user_func_array(array($plugin, $name), $args) === false) {
-                return false;
-            }
+        foreach ($this->getIterator() as $plugin) {
+            call_user_func_array(array($plugin, $name), $args);
         }
         return true;
     }
index 7cc8349571656e34b2f551ccad0e24f78208ec63..4c2c49b31480e297fc4e89b0c05a495ff449bf52 100644 (file)
  * @license  http://phergie.org/license New BSD License
  * @link     http://pear.phergie.org/package/Phergie_Plugin_Help
  * @uses     Phergie_Plugin_Command pear.phergie.org
- *
- * @pluginDesc Provides access to plugin help information
  */
 class Phergie_Plugin_Help extends Phergie_Plugin_Abstract
 {
-
     /**
-     * Holds the registry of help data indexed by plugin name
+     * Registry of help data indexed by plugin name
      *
      * @var array
      */
     protected $registry;
 
-    /**
-     * Whether the registry has been alpha sorted
-     *
-     * @var bool
-     */
-    protected $registry_sorted = false;
-
     /**
      * Checks for dependencies.
      *
@@ -56,143 +46,175 @@ class Phergie_Plugin_Help extends Phergie_Plugin_Abstract
     public function onLoad()
     {
         $this->getPluginHandler()->getPlugin('Command');
-        $this->register($this);
     }
 
     /**
-     * Displays a list of plugins with help information available or
-     * commands available for a specific plugin.
-     *
-     * @param string $plugin Short name of the plugin for which commands
-     *        should be returned, else a list of plugins with help
-     *        information available is returned
+     * Creates a registry of plugin metadata on connect.
      *
      * @return void
+     */
+    public function onConnect()
+    {
+        $this->populateRegistry();
+    }
+
+    /**
+     * Creates a registry of plugin metadata.
      *
-     * @pluginCmd Show all active plugins with help available
-     * @pluginCmd [plugin] Shows commands line for a specific plugin
+     * @return void
      */
-    public function onCommandHelp($plugin = null)
+    public function populateRegistry()
     {
-        $nick = $this->getEvent()->getNick();
+        $this->registry = array();
 
-        if (!$plugin) {
-            // protect from sorting the registry each time help is called
-            if (!$this->registry_sorted) {
-                asort($this->registry);
-                $this->registry_sorted = true;
+        foreach ($this->plugins as $plugin) {
+            $class = new ReflectionClass($plugin);
+            $pluginName = strtolower($plugin->getName());
+
+            // Parse the plugin description
+            $docblock = $class->getDocComment();
+            $annotations = $this->getAnnotations($docblock);
+            if (isset($annotations['pluginDesc'])) {
+                $pluginDesc = implode(' ', $annotations['pluginDesc']);
+            } else {
+                $pluginDesc = $this->parseShortDescription($docblock);
             }
+            $this->registry[$pluginName] = array(
+                'desc' => $pluginDesc,
+                'cmds' => array()
+            );
+
+            // Parse command method descriptions
+            $methodPrefix = Phergie_Plugin_Command::METHOD_PREFIX;
+            $methodPrefixLength = strlen($methodPrefix);
+            foreach ($class->getMethods() as $method) {
+                if (strpos($method->getName(), $methodPrefix) !== 0) {
+                    continue;
+                }
 
-            $msg = 'These plugins below have help information available.';
-            $this->doPrivMsg($nick, $msg);
+                $cmd = strtolower(substr($method->getName(), $methodPrefixLength));
+                $docblock = $method->getDocComment();
+                $annotations = $this->getAnnotations($docblock);
 
-            foreach ($this->registry as $plugin => $data) {
-                $this->doPrivMsg($nick, "{$plugin} - {$data['desc']}");
-            }
-        } else {
-            if (isset($this->getPluginHandler()->{$plugin})
-                && isset($this->registry[strtolower($plugin)]['cmd'])
-            ) {
-                $msg
-                    = 'The ' .
-                    $plugin .
-                    ' plugin exposes the commands shown below.';
-                $this->doPrivMsg($nick, $msg);
-                if ($this->getConfig('command.prefix')) {
-                    $msg
-                        = 'Note that these commands must be prefixed with "' .
-                        $this->getConfig('command.prefix') .
-                        '" (without quotes) when issued in a public channel.';
-                    $this->doPrivMsg($nick, $msg);
+                if (isset($annotations['pluginCmd'])) {
+                    $cmdDesc = implode(' ', $annotations['pluginCmd']);
+                } else {
+                    $cmdDesc = $this->parseShortDescription($docblock);
                 }
 
-                foreach ($this->registry[strtolower($plugin)]['cmd']
-                    as $cmd => $descs
-                ) {
-                    foreach ($descs as $desc) {
-                        $this->doPrivMsg($nick, "{$cmd} {$desc}");
+                $cmdParams = array();
+                if (!empty($annotations['param'])) {
+                    foreach ($annotations['param'] as $param) {
+                        $match = null;
+                        if (preg_match('/\h+\$([^\h]+)\h+/', $param, $match)) {
+                            $cmdParams[] = $match[1];
+                        }
                     }
                 }
 
-            } else {
-                $this->doPrivMsg($nick, 'That plugin is not loaded.');
+                $this->registry[$pluginName]['cmds'][$cmd] = array(
+                    'desc' => $cmdDesc,
+                    'params' => $cmdParams
+                );
+            }
+
+            if (empty($this->registry[$pluginName]['cmds'])) {
+                unset($this->registry[$pluginName]);
             }
         }
     }
 
     /**
-     * Sets the description for the plugin instance
+     * Displays a list of plugins with help information available or
+     * commands available for a specific plugin.
      *
-     * @param Phergie_Plugin_Abstract $plugin      plugin instance
-     * @param string                  $description plugin description
+     * @param string $query Optional short name of a plugin for which commands
+     *        should be returned or a command; if unspecified, a list of
+     *        plugins with help information available is returned
      *
      * @return void
      */
-    public function setPluginDescription(
-        Phergie_Plugin_Abstract $plugin,
-        $description
-    ) {
-        $this->registry[strtolower($plugin->getName())]
-                ['desc'] = $description;
-    }
+    public function onCommandHelp($query = null)
+    {
+        if ($query == 'refresh') {
+            $this->populateRegistry();
+        }
 
-    /**
-     * Sets the description for the command on the plugin instance
-     *
-     * @param Phergie_Plugin_Abstract $plugin      plugin instance
-     * @param string                  $command     from onCommand method
-     * @param string                  $description command description
-     *
-     * @return void
-     */
-    public function setCommandDescription(
-        Phergie_Plugin_Abstract $plugin,
-        $command,
-        array $description
-    ) {
-        $this->registry[strtolower($plugin->getName())]
-            ['cmd'][$command] = $description;
+        $nick = $this->getEvent()->getNick();
+        $delay = $this->getConfig('help.delay', 2);
+
+        // Handle requests for a plugin list
+        if (!$query) {
+            $msg = 'These plugins have help information available: '
+                 . implode(', ', array_keys($this->registry));
+            $this->doPrivmsg($nick, $msg);
+            return;
+        }
+
+        // Handle requests for plugin information
+        $query = strtolower($query);
+        if (isset($this->registry[$query])
+            && empty($this->registry[$query]['cmds'][$query])) {
+            $msg = $query . ' - ' . $this->registry[$query]['desc'];
+            $this->doPrivmsg($nick, $msg);
+
+            $msg = 'Available commands - '
+                 . implode(', ', array_keys($this->registry[$query]['cmds']));
+            $this->doPrivmsg($nick, $msg);
+
+            if ($this->getConfig('command.prefix')) {
+                $msg
+                    = 'Note that these commands must be prefixed with "'
+                    . $this->getConfig('command.prefix')
+                    . '" (without quotes) when issued in a public channel.';
+                $this->doPrivmsg($nick, $msg);
+            }
+
+            return;
+        }
+
+        // Handle requests for command information
+        foreach ($this->registry as $plugin => $data) {
+            if (empty($data['cmds'])) {
+                continue;
+            }
+
+            $result = preg_grep('/^' . $query . '$/i', array_keys($data['cmds']));
+            if (!$result) {
+                continue;
+            }
+
+            $cmd = $data['cmds'][array_shift($result)];
+            $msg = $query;
+            if (!empty($cmd['params'])) {
+                $msg .= ' [' . implode('] [', $cmd['params']) . ']';
+            }
+            $msg .= ' - ' . $cmd['desc'];
+            $this->doPrivmsg($nick, $msg);
+        }
     }
 
     /**
-     * registers the plugin with the help plugin. this will parse the docblocks
-     * for specific annotations that this plugin will respond with when
-     * queried.
+     * Parses and returns the short description from a docblock.
      *
-     * @param Phergie_Plugin_Abstract $plugin plugin instance
+     * @param string $docblock Docblock comment code
      *
-     * @return void
+     * @return string Short description (i.e. content from the start of the
+     *         docblock up to the first double-newline)
      */
-    public function register(Phergie_Plugin_Abstract $plugin)
+    protected function parseShortDescription($docblock)
     {
-        $class = new ReflectionClass($plugin);
-
-        $annotations = self::parseAnnotations($class->getDocComment());
-        if (isset($annotations['pluginDesc'])) {
-            $this->setPluginDescription(
-                $plugin,
-                join(' ', $annotations['pluginDesc'])
-            );
-        }
-
-        foreach ($class->getMethods() as $method) {
-            if (strpos($method->getName(), 'onCommand') !== false) {
-                $annotations = self::parseAnnotations($method->getDocComment());
-                if (isset($annotations['pluginCmd'])) {
-                    $cmd = strtolower(substr($method->getName(), 9));
-                    $this->setCommandDescription(
-                        $plugin,
-                        $cmd,
-                        $annotations['pluginCmd']
-                    );
-                }
-            }
-        }
+        $desc = preg_replace(
+            array('#^\h*\*\h*#m', '#^/\*\*\h*\v+\h*#', '#(?:\r?\n){2,}.*#s', '#\s*\v+\s*#'),
+            array('', '', '', ' '),
+            $docblock
+        );
+        return $desc;
     }
 
     /**
-     * Taken from PHPUnit/Util/Test.php:243 and modified to fix an issue
-     * with tag content spanning multiple lines.
+     * Taken from PHPUnit/Util/Test.php and modified to fix an issue with
+     * tag content spanning multiple lines.
      *
      * PHPUnit
      *
@@ -232,7 +254,7 @@ class Phergie_Plugin_Help extends Phergie_Plugin_Abstract
      *
      * @return array
      */
-    protected static function parseAnnotations($docblock)
+    protected function getAnnotations($docblock)
     {
         $annotations = array();
 
index 43c69eb8797f9bd94af86ecdb4fc3cd223b18792..7c5c8704c2b23e08dbe8805f367faea216ea5b45 100644 (file)
@@ -184,7 +184,10 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
             $type = $this->response->getHeaders('content-type');
             foreach ($this->handlers as $expr => $handler) {
                 if (preg_match('#^' . $expr . '$#i', $type)) {
-                    $body = call_user_func($handler, $body);
+                    $handled = call_user_func($handler, $body);
+                    if (!empty($handled)) {
+                        $body = $handled;
+                    }
                 }
             }
 
@@ -256,7 +259,7 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
     public function post($url, array $query = array(),
         array $post = array(), array $context = array()
     ) {
-        if (!empty($params)) {
+        if (!empty($query)) {
             $url .= '?' . http_build_query($query);
         }
 
@@ -278,4 +281,4 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
 
         return $this->request($url, $context);
     }
-}
+}
\ No newline at end of file
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Ideone.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Ideone.php
new file mode 100644 (file)
index 0000000..3af88dd
--- /dev/null
@@ -0,0 +1,180 @@
+<?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_Ideone
+ * @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_Ideone
+ */
+
+/**
+ * Interfaces with ideone.com to execute code and return the result.
+ *
+ * @category Phergie
+ * @package  Phergie_Plugin_Ideone
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie_Plugin_Ideone
+ * @uses     Phergie_Plugin_Command pear.phergie.org
+ */
+class Phergie_Plugin_Ideone extends Phergie_Plugin_Abstract
+{
+    /**
+     * Checks for dependencies.
+     *
+     * @return void
+     */
+    public function onLoad()
+    {
+        $this->plugins->getPlugin('Command');
+    }
+
+    /**
+     * Checks a service response for an error, sends a notice to the event
+     * source if an error has occurred, and returns whether an error was found.
+     *
+     * @param array $result Associative array representing the service response
+     *
+     * @return boolean TRUE if an error is found, FALSE otherwise
+     */
+    protected function isError($result)
+    {
+        if ($result['error'] != 'OK') {
+            $this->doNotice($this->event->getNick(), 'ideone error: ' . $result['error']);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Executes a source code sequence in a specified language and returns
+     * the result.
+     *
+     * @param string $language Programming language the source code is in
+     * @param string $code     Source code to execute
+     *
+     * @return void
+     */
+    public function onCommandIdeone($language, $code)
+    {
+        $source = $this->event->getSource();
+        $nick = $this->event->getNick();
+
+        // Get authentication credentials
+        $user = $this->getConfig('ideone.user', 'test');
+        $pass = $this->getConfig('ideone.pass', 'test');
+
+        // Normalize the command parameters
+        $language = strtolower($language);
+
+        // Massage PHP code to allow for convenient shorthand
+        if ($language == 'php') {
+            if (!preg_match('/^<\?(?:php)?/', $code)) {
+                $code = '<?php ' . $code;
+            }
+            switch (substr($code, -1)) {
+                case '}':
+                case ';':
+                    break;
+                default:
+                    $code .= ';';
+                    break;
+            }
+        }
+
+        // Identify the language to use
+        $client = new SoapClient('http://ideone.com/api/1/service.wsdl');
+        $response = $client->getLanguages($user, $pass);
+        if ($this->isError($response)) {
+            return;
+        }
+        $languageLength = strlen($language);
+        foreach ($response['languages'] as $languageId => $languageName) {
+            if (strncasecmp($language, $languageName, $languageLength) == 0) {
+                break;
+            }
+        }
+
+        // Send the paste data
+        $response = $client->createSubmission(
+            $user,
+            $pass,
+            $code,
+            $languageId,
+            null, // string input - data from stdin
+            true, // boolean run - TRUE to execute the code
+            false // boolean private - FALSE to make the paste public
+        );
+        if ($this->isError($response)) {
+            return;
+        }
+        $link = $response['link'];
+
+        // Wait until the paste data is processed or the service fails
+        $attempts = $this->getConfig('ideone.attempts', 10);
+        foreach (range(1, $attempts) as $attempt) {
+            $response = $client->getSubmissionStatus($user, $pass, $link);
+            if ($this->isError($response)) {
+                return;
+            }
+            if ($response['status'] == 0) {
+                $result = $response['result'];
+                break;
+            } else {
+                $result = null;
+                sleep(1);
+            }
+        }
+        if ($result == null) {
+            $this->doNotice($nick, 'ideone error: Timed out');
+            return;
+        }
+        if ($result != 15) {
+            $this->doNotice($nick, 'ideone error: Status code ' . $result);
+            return;
+        }
+
+        // Get details for the created paste
+        $response = $client->getSubmissionDetails(
+            $user,
+            $pass,
+            $link,
+            false, // boolean withSource - FALSE to not return the source code
+            false, // boolean withInput - FALSE to not return stdin data
+            true,  // boolean withOutput - TRUE to include output
+            true,  // boolean withStderr - TRUE to return stderr data
+            false  // boolean withCmpinfo - TRUE to return compilation info
+        );
+        if ($this->isError($response)) {
+            return;
+        }
+
+        // Replace the output if it exceeds a specified maximum length
+        $outputLimit = $this->getConfig('ideone.output_limit', 100);
+        var_dump($response);
+        if ($outputLimit && strlen($response['output']) > $outputLimit) {
+            $response['output'] = 'Output is too long to post';
+        }
+
+        // Format the message
+        $msg = $this->getConfig('ideone.format', '%nick%: [ %link% ] %output%');
+        $response['nick'] = $nick;
+        $response['link'] = 'http://ideone.com/' . $link;
+        foreach ($response as $key => $value) {
+            $msg = str_replace('%' . $key . '%', $value, $msg);
+        }
+        $this->doPrivmsg($source, $msg);
+    }
+}
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Iterator.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Iterator.php
new file mode 100644 (file)
index 0000000..5963300
--- /dev/null
@@ -0,0 +1,126 @@
+<?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
+ * @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
+ */
+
+/**
+ * Implements a filtering iterator for limiting executing of methods across
+ * a group of plugins.
+ *
+ * @category Phergie
+ * @package  Phergie
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie
+ */
+class Phergie_Plugin_Iterator extends FilterIterator
+{
+    /**
+     * List of short names of plugins to exclude when iterating
+     *
+     * @var array
+     */
+    protected $plugins = array();
+
+    /**
+     * List of method names where plugins with these methods will be
+     * excluded when iterating
+     *
+     * @var array
+     */
+    protected $methods = array();
+
+    /**
+     * Adds to a list of plugins to exclude when iterating.
+     *
+     * @param mixed $plugins String containing the short name of a single
+     *        plugin to exclude or an array of short names of multiple
+     *        plugins to exclude
+     *
+     * @return Phergie_Plugin_Iterator Provides a fluent interface
+     */
+    public function addPluginFilter($plugins)
+    {
+        if (is_array($plugins)) {
+            $this->plugins = array_unique(
+                array_merge($this->plugins, $plugins)
+            );
+        } else {
+            $this->plugins[] = $plugins;
+        }
+        return $this;
+    }
+
+    /**
+     * Adds to a list of method names where plugins defining these methods
+     * will be excluded when iterating.
+     *
+     * @param mixed $methods String containing the name of a single method
+     *        or an array containing the name of multiple methods
+     *
+     * @return Phergie_Plugin_Iterator Provides a fluent interface
+     */
+    public function addMethodFilter($methods)
+    {
+        if (is_array($methods)) {
+            $this->methods = array_merge($this->methods, $methods);
+        } else {
+            $this->methods[]= $methods;
+        }
+        return $this;
+    }
+
+    /**
+     * Clears any existing plugin and methods filters.
+     *
+     * @return Phergie_Plugin_Iterator Provides a fluent interface
+     */
+    public function clearFilters()
+    {
+        $this->plugins = array();
+        $this->methods = array();
+    }
+
+    /**
+     * Implements FilterIterator::accept().
+     *
+     * @return boolean TRUE to include the current item in those by returned
+     *         during iteration, FALSE otherwise
+     */
+    public function accept()
+    {
+        if (!$this->plugins && !$this->methods) {
+            return true;
+        }
+
+        $current = $this->current();
+
+        if (in_array($current->getName(), $this->plugins)) {
+            return false;
+        }
+
+        foreach ($this->methods as $method) {
+            if (method_exists($current, $method)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
index b7ce48685a330f4b4cb3879cea68b6fccb3efed0..f55f8d6edf78fb9297ea0048c558ded6105b79af 100644 (file)
 
 /**
  * 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.
+ * of counters for specified terms.
  *
  * @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
+ * @uses     extension PDO
+ * @uses     extension pdo_sqlite
+ * @uses     Phergie_Plugin_Command pear.phergie.org
+ * @uses     Phergie_Plugin_Message pear.phergie.org
  */
 class Phergie_Plugin_Karma extends Phergie_Plugin_Abstract
 {
     /**
-     * Stores the SQLite object
+     * SQLite object
      *
      * @var resource
      */
     protected $db = null;
 
     /**
-     * Retains the last garbage collection date
+     * Prepared statement to add a new karma record
      *
-     * @var array
+     * @var PDOStatement
      */
-    protected $lastGc = null;
+    protected $insertKarma;
 
     /**
-     * Logs the karma usages and limits users to one karma change per word
-     * and per day
+     * Prepared statement to update an existing karma record
      *
-     * @return void
+     * @var PDOStatement
      */
-    protected $log = array();
+    protected $updateKarma;
 
     /**
-     * Some fixed karma values, keys must be lowercase
+     * Retrieves an existing karma record
      *
-     * @var array
+     * @var PDOStatement
      */
-    protected $fixedKarma;
+    protected $fetchKarma;
 
     /**
-     * A list of blacklisted values
+     * Retrieves an existing fixed karma record
      *
-     * @var array
-     */
-    protected $karmaBlacklist;
-
-    /**
-     * Answers for correct assertions
+     * @var PDOStatement
      */
-    protected $positiveAnswers;
+    protected $fetchFixedKarma;
 
     /**
-     * Answers for incorrect assertions
+     * Retrieves a positive answer for a karma comparison
+     *
+     * @var PDOStatement
      */
-    protected $negativeAnswers;
+    protected $fetchPositiveAnswer;
 
     /**
-     * Prepared PDO statements
+     * Retrieves a negative answer for a karma comparison
      *
      * @var PDOStatement
      */
-    protected $insertKarma;
-    protected $updateKarma;
-    protected $fetchKarma;
-    protected $insertComment;
+    protected $fetchNegativeAnswer;
 
     /**
-     * Connects to the database containing karma ratings and initializes
-     * class properties.
+     * Check for dependencies and initializes a database connection and
+     * prepared statements.
      *
      * @return void
      */
     public function onLoad()
     {
-        $this->db = null;
-        $this->lastGc = null;
-        $this->log = array();
+        $plugins = $this->getPluginHandler();
+        $plugins->getPlugin('Command');
+        $plugins->getPlugin('Message');
 
-        if(!defined('M_EULER')) {
-            define('M_EULER', '0.57721566490153286061');
-        }
+        $file = dirname(__FILE__) . '/Karma/karma.db';
+        $this->db = new PDO('sqlite:' . $file);
 
-        $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->fetchKarma = $this->db->prepare('
+            SELECT karma
+            FROM karmas
+            WHERE term = :term
+            LIMIT 1
+        ');
 
         $this->insertKarma = $this->db->prepare('
-            INSERT INTO karmas (
-                word,
-                karma
-            )
-            VALUES (
-                :word,
-                :karma
-            )
+            INSERT INTO karmas (term, karma)
+            VALUES (:term, :karma)
         ');
 
-        $this->insertComment = $this->db->prepare('
-            INSERT INTO comments (
-                wordid,
-                comment
-            )
-            VALUES (
-                :wordid,
-                :comment
-            )
+        $this->updateKarma = $this->db->prepare('
+            UPDATE karmas
+            SET karma = :karma
+            WHERE term = :term
         ');
 
-        $this->fetchKarma = $this->db->prepare('
-            SELECT karma, ROWID id FROM karmas WHERE LOWER(word) = LOWER(:word) LIMIT 1
+        $this->fetchFixedKarma = $this->db->prepare('
+            SELECT karma
+            FROM fixed_karmas
+            WHERE term = :term
+            LIMIT 1
         ');
 
-        $this->updateKarma = $this->db->prepare('
-            UPDATE karmas SET karma = :karma WHERE LOWER(word) = LOWER(:word)
+        $this->fetchPositiveAnswer = $this->db->prepare('
+            SELECT answer
+            FROM positive_answers
+            ORDER BY RANDOM()
+            LIMIT 1
+        ');
+
+        $this->fetchNegativeAnswer = $this->db->prepare('
+            SELECT answer
+            FROM negative_answers
+            ORDER BY RANDOM()
+            LIMIT 1
         ');
     }
 
     /**
-     * Checks for dependencies.
+     * Get the canonical form of a given term.
      *
-     * @return void
+     * In the canonical form all sequences of whitespace
+     * are replaced by a single space and all characters
+     * are lowercased.
+     *
+     * @param string $term Term for which a canonical form is required
+     *
+     * @return string Canonical term
      */
-    public static function onLoad()
+    protected function getCanonicalTerm($term)
     {
-       if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
-            $this->fail('PDO and pdo_sqlite extensions must be installed');
-       }
+        $canonicalTerm = strtolower(preg_replace('|\s+|', ' ', trim($term, '()')));
+        switch ($canonicalTerm) {
+            case 'me':
+                $canonicalTerm = strtolower($this->event->getNick());
+                break;
+            case 'all':
+            case '*':
+            case 'everything':
+                $canonicalTerm = 'everything';
+                break;
+        }
+        return $canonicalTerm;
     }
 
     /**
-     * Handles requests for incrementation, decrementation, or lookup of karma
-     * ratings sent via messages from users.
+     * Intercepts a message and processes any contained recognized commands.
      *
      * @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();
-                    }
-                }
-            }
+        $message = $this->getEvent()->getText();
+
+        $termPattern = '\S+?|\([^<>]+?\)+';
+        $actionPattern = '(?P<action>\+\+|--)';
+
+        $modifyPattern = <<<REGEX
+               {^
+               (?J) # allow overwriting capture names
+               \s*  # ignore leading whitespace
+
+               (?:  # start with ++ or -- before the term
+            $actionPattern
+            (?P<term>$termPattern)
+               |   # follow the term with ++ or --
+            (?P<term>$termPattern)
+                       $actionPattern # allow no whitespace between the term and the action
+               )
+               $}ix
+REGEX;
+
+        $versusPattern = <<<REGEX
+        {^
+               (?P<term0>$termPattern)
+                       \s+(?P<method><|>)\s+
+               (?P<term1>$termPattern)$#
+        $}ix
+REGEX;
+
+        $match = null;
+
+        if (preg_match($modifyPattern, $message, $match)) {
+            $action = $match['action'];
+            $term = $this->getCanonicalTerm($match['term']);
+            $this->modifyKarma($term, $action);
+        } elseif (preg_match($versusPattern, $message, $match)) {
+            $term0 = trim($match['term0']);
+            $term1 = trim($match['term1']);
+            $method = $match['method'];
+            $this->compareKarma($term0, $term1, $method);
         }
     }
 
-    protected function fetchPositiveAnswer($owner, $owned)
+    /**
+     * Get the karma rating for a given term.
+     *
+     * @param string $term Term for which the karma rating needs to be
+     *        retrieved
+     *
+     * @return void
+     */
+    public function onCommandKarma($term)
     {
-        return str_replace(array('%owner%','%owned%'), array($owner, $owned), $this->positiveAnswers[array_rand($this->positiveAnswers,1)]);
+        $source = $this->getEvent()->getSource();
+        $nick = $this->getEvent()->getNick();
+
+        if (empty($term)) {
+            return;
+        }
+
+        $canonicalTerm = $this->getCanonicalTerm($term);
+
+        $fixedKarma = $this->fetchFixedKarma($canonicalTerm);
+        if ($fixedKarma) {
+            $message = $nick . ': ' . $term . $fixedKarma . '.';
+            $this->doPrivmsg($source, $message);
+            return;
+        }
+
+        $karma = $this->fetchKarma($canonicalTerm);
+
+        $message = $nick . ': ';
+
+        if ($term == 'me') {
+            $message .= 'You have';
+        } else {
+            $message .= $term . ' has';
+        }
+
+        $message .= ' ';
+
+        if ($karma) {
+            $message .= 'karma of ' . $karma;
+        } else {
+            $message .= 'neutral karma';
+        }
+
+        $message .= '.';
+
+        $this->doPrivmsg($source, $message);
     }
 
-    protected function fetchNegativeAnswer($owned, $owner)
+    /**
+     * Resets the karma for a term to 0.
+     *
+     * @param string $term Term for which to reset the karma rating
+     *
+     * @return void
+     */
+    public function onCommandReincarnate($term)
     {
-        return str_replace(array('%owner%','%owned%'), array($owner, $owned), $this->negativeAnswers[array_rand($this->negativeAnswers,1)]);
+        $data = array(
+            ':term' => $term,
+            ':karma' => 0
+        );
+        $this->updateKarma->execute($data);
     }
 
-    protected function doCleanWord($word)
+    /**
+     * Compares the karma between two terms. Optionally increases/decreases
+     * the karma of either term.
+     *
+     * @param string $term0  First term
+     * @param string $term1  Second term
+     * @param string $method Comparison method (< or >)
+     *
+     * @return void
+     */
+    protected function compareKarma($term0, $term1, $method)
     {
-        $word = trim($word);
-        if (substr($word, 0, 1) === '(' && substr($word, -1) === ')') {
-            $word = trim(substr($word, 1, -1));
+        $event = $this->getEvent();
+        $nick = $event->getNick();
+        $source = $event->getSource();
+
+        $canonicalTerm0 = $this->getCanonicalTerm($term0);
+        $canonicalTerm1 = $this->getCanonicalTerm($term1);
+
+        $fixedKarma0 = $this->fetchFixedKarma($canonicalTerm0);
+        $fixedKarma1 = $this->fetchFixedKarma($canonicalTerm1);
+
+        if ($fixedKarma0
+            || $fixedKarma1
+            || empty($canonicalTerm0)
+            || empty($canonicalTerm1)
+        ) {
+            return;
+        }
+
+        if ($canonicalTerm0 == 'everything') {
+            $change = $method == '<' ? '++' : '--';
+            $this->modifyKarma($canonicalTerm1, $change);
+            $karma0 = 0;
+            $karma1 = $this->fetchKarma($canonicalTerm1);
+        } elseif ($canonicalTerm1 == 'everything') {
+            $change = $method == '<' ? '--' : '++';
+            $this->modifyKarma($canonicalTerm0, $change);
+            $karma0 = $this->fetchKarma($canonicalTerm1);
+            $karma1 = 0;
+        } else {
+            $karma0 = $this->fetchKarma($canonicalTerm0);
+            $karma1 = $this->fetchKarma($canonicalTerm1);
         }
-        $word = preg_replace('#\s+#', ' ', strtolower(trim($word)));
-        return $word;
+
+        if (($method == '<'
+            && $karma0 < $karma1)
+            || ($method == '>'
+            && $karma0 > $karma1)) {
+            $replies = $this->fetchPositiveAnswer;
+        } else {
+            $replies = $this->fetchNegativeAnswer;
+        }
+        $replies->execute();
+        $reply = $replies->fetchColumn();
+
+        if (max($karma0, $karma1) == $karma1) {
+            list($canonicalTerm0, $canonicalTerm1) =
+                array($canonicalTerm1, $canonicalTerm0);
+        }
+
+        $message = str_replace(
+            array('%owner%','%owned%'),
+            array($canonicalTerm0, $canonicalTerm1),
+            $reply
+        );
+
+        $this->doPrivmsg($source, $message);
     }
 
     /**
-     * Performs garbage collection on the antithrottling log.
+     * Modifes a term's karma.
+     *
+     * @param string $term   Term to modify
+     * @param string $action Karma action (either ++ or --)
      *
      * @return void
      */
-    public function doGc()
+    protected function modifyKarma($term, $action)
     {
-        unset($this->log);
-        $this->log = array();
-        $this->lastGc = date('d');
+        if (empty($term)) {
+            return;
+        }
+
+        $karma = $this->fetchKarma($term);
+        if ($karma !== false) {
+            $statement = $this->updateKarma;
+        } else {
+            $statement = $this->insertKarma;
+        }
+
+        $karma += ($action == '++') ? 1 : -1;
+
+        $args = array(
+            ':term'  => $term,
+            ':karma' => $karma
+        );
+        $statement->execute($args);
+    }
+
+    /**
+     * Returns the karma rating for a specified term for which the karma
+     * rating can be modified.
+     *
+     * @param string $term Term for which to fetch the corresponding karma
+     *        rating
+     *
+     * @return integer|boolean Integer value denoting the term's karma or
+     *         FALSE if there is the specified term has no associated karma
+     *         rating
+     */
+    protected function fetchKarma($term)
+    {
+        $this->fetchKarma->execute(array(':term' => $term));
+        $result = $this->fetchKarma->fetch(PDO::FETCH_ASSOC);
+
+        if ($result === false) {
+            return false;
+        }
+
+        return (int) $result['karma'];
+    }
+
+    /**
+     * Returns a phrase describing the karma rating for a specified term for
+     * which the karma rating is fixed.
+     *
+     * @param string $term Term for which to fetch the corresponding karma
+     *        rating
+     *
+     * @return string Phrase describing the karma rating, which may be append
+     *         to the term to form a complete response
+     */
+    protected function fetchFixedKarma($term)
+    {
+        $this->fetchFixedKarma->execute(array(':term' => $term));
+        $result = $this->fetchFixedKarma->fetch(PDO::FETCH_ASSOC);
+
+        if ($result === false) {
+            return false;
+        }
+
+        return $result['karma'];
     }
 }
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Message.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Message.php
new file mode 100644 (file)
index 0000000..af8fc72
--- /dev/null
@@ -0,0 +1,112 @@
+<?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_Message
+ * @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_Message
+ */
+
+/**
+ * Generalized plugin providing utility methods for
+ * prefix and bot named based message extraction.
+ *
+ * @category Phergie
+ * @package  Phergie_Plugin_Message
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie_Plugin_Message
+ */
+class Phergie_Plugin_Message extends Phergie_Plugin_Abstract
+{
+
+    /**
+     * Check whether a message is specifically targeted at the bot.
+     * This is the case when the message starts with the bot's name
+     * followed by [,:>] or when it is a private message.
+     *
+     * @return boolean true when the message is specifically targeted at the bot,
+     *                 false otherwise.
+     */
+    public function isTargetedMessage()
+    {
+        $event = $this->getEvent();
+
+        $self = preg_quote($this->connection->getNick());
+
+        $targetPattern = <<<REGEX
+        {^
+        \s*{$self}\s*[:>,].* # expect the bots name, followed by a [:>,]
+        $}ix
+REGEX;
+
+        return !$event->isInChannel() 
+            || preg_match($targetPattern, $event->getText()) > 0;
+    }
+
+    /**
+     * Allow for prefix and bot name aware extraction of a message
+     *
+     * @return string|bool $message The message, which is possibly targeted at the 
+     *                              bot or false if a prefix requirement failed
+     */
+    public function getMessage()
+    {
+        $event = $this->getEvent();
+
+        $prefix = preg_quote($this->getConfig('command.prefix'));
+        $self = preg_quote($this->connection->getNick());
+        $message = $event->getText();
+
+        // $prefixPattern matches : Phergie, do command <parameters>
+        // where $prefix = 'do'   : do command <parameters>
+        //                        : Phergie, command <parameters>
+        $prefixPattern = <<<REGEX
+        {^
+        (?:
+               \s*{$self}\s*[:>,]\s* # start with bot name
+                       (?:{$prefix})?        # which is optionally followed by the prefix
+        |
+               \s*{$prefix}          # or start with the prefix
+        )
+        \s*(.*)                   # always end with the message
+        $}ix
+REGEX;
+
+        // $noPrefixPattern matches : Phergie, command <parameters>
+        //                          : command <parameters>
+        $noPrefixPattern = <<<REGEX
+        {^
+        \s*(?:{$self}\s*[:>,]\s*)? # optionally start with the bot name
+        (.*?)                      # always end with the message
+        $}ix
+REGEX;
+
+        $pattern = $noPrefixPattern;
+
+        // If a prefix is set, force it as a requirement
+        if ($prefix && $event->isInChannel()) {
+            $pattern = $prefixPattern;
+        }
+
+        $match = null;
+
+        if (!preg_match($pattern, $message, $match)) {
+            return false;
+        }
+
+        return $match[1];
+    }
+}
\ No newline at end of file
index 29ac69f4645171c8d6b735d3036ef31e9bdbd06e..021670d97dfd649f8c17929bc20487410ee1a5e6 100755 (executable)
@@ -87,7 +87,7 @@ class Phergie_Plugin_Ping extends Phergie_Plugin_Abstract
     {
         $time = time();
         if (!empty($this->lastPing)) {
-            if ($time - $this->lastPing > $this->getConfig('ping.ping', 10)) {
+            if ($time - $this->lastPing > $this->getConfig('ping.ping', 20)) {
                 $this->doQuit();
             }
         } elseif (
@@ -112,7 +112,7 @@ class Phergie_Plugin_Ping extends Phergie_Plugin_Abstract
     /**
      * Set the last ping time
      * lastPing needs to be exposed for unit testing
-     * 
+     *
      * @param int|null $ping timestamp of last ping
      *
      * @return self
index cacd77d3f34d57c0f042857c5c3000c974b7d368..eca22a98e3c7851aa2ab2e3cb85d656c906067c6 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Phergie 
+ * Phergie
  *
  * PHP version 5
  *
@@ -11,7 +11,7 @@
  * It is also available through the world-wide-web at this URL:
  * http://phergie.org/license
  *
- * @category  Phergie 
+ * @category  Phergie
  * @package   Phergie_Plugin_Quit
  * @author    Phergie Development Team <team@phergie.org>
  * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
 /**
  * Terminates the current connection upon command.
  *
- * @category Phergie 
+ * @category Phergie
  * @package  Phergie_Plugin_Quit
  * @author   Phergie Development Team <team@phergie.org>
  * @license  http://phergie.org/license New BSD License
  * @link     http://pear.phergie.org/package/Phergie_Plugin_Quit
  * @uses     Phergie_Plugin_Command pear.phergie.org
- *
- * @pluginDesc Terminates the current connection upon command.
  */
 class Phergie_Plugin_Quit extends Phergie_Plugin_Abstract
 {
@@ -41,17 +39,13 @@ class Phergie_Plugin_Quit extends Phergie_Plugin_Abstract
     public function onLoad()
     {
         $this->getPluginHandler()->getPlugin('Command');
-        $help = $this->getPluginHandler()->getPlugin('Help');
-        $help->register($this);
     }
 
     /**
-     * Issues a quit command when a message is received requesting that the 
+     * Issues a quit command when a message is received requesting that the
      * bot terminate the current connection.
      *
      * @return void
-     *
-     * @pluginCmd terminates the connection
      */
     public function onCommandQuit()
     {
index a2d680d7aa368bf9123bb4afad75e777a6dc2d3c..90e3adcd527a1aea0d88c31cb981b11fea925029 100755 (executable)
@@ -57,6 +57,7 @@ class Phergie_Plugin_Reload extends Phergie_Plugin_Abstract
         if (!$this->plugins->hasPlugin($plugin)) {
             echo 'DEBUG(Reload): ' . ucfirst($plugin) . ' is not loaded yet, loading', PHP_EOL;
             $this->plugins->getPlugin($plugin);
+            $this->plugins->command->populateMethodCache();
             return;
         }
 
@@ -79,7 +80,7 @@ class Phergie_Plugin_Reload extends Phergie_Plugin_Abstract
         }
 
         $contents = preg_replace(
-            array('/<\?(?:php)?/', '/class\s+' . $class . '/i'),
+            array('/^<\?(?:php)?/', '/class\s+' . $class . '/i'),
             array('', 'class ' . $newClass),
             $contents
         );
@@ -87,10 +88,16 @@ class Phergie_Plugin_Reload extends Phergie_Plugin_Abstract
 
         $instance = new $newClass;
         $instance->setName($plugin);
+        $instance->setEvent($this->event);
         $this->plugins
             ->removePlugin($plugin)
             ->addPlugin($instance);
 
+        $this->plugins->command->populateMethodCache();
+        if ($this->plugins->hasPlugin('Help')) {
+            $this->plugins->help->populateRegistry();
+        }
+
         echo 'DEBUG(Reload): Reloaded ', $class, ' to ', $newClass, PHP_EOL;
     }
 }
index 19ecb0c7e4a01856f3c7c6706dcc339e5cb7ec99..cdb8f7f9198115b070c9243e330ff9e9c544f816 100755 (executable)
@@ -113,20 +113,21 @@ class Phergie_Plugin_Serve extends Phergie_Plugin_Abstract
         $item = $this->getItem($database, $table, $match);
 
         // Reprocess the request for censorship if required
-        $attempts = 0;
-        while ($censor && $attempts < 3) {
+        if ($this->plugins->hasPlugin('Censor')) {
             $plugin = $this->plugins->getPlugin('Censor');
-            $clean = $plugin->cleanString($item->name);
-            if ($item->name != $clean) {
-                $attempts++;
-                $item = $this->getItem($database, $table, $match);
-            } else {
-                $censor = false;
+            $attempts = 0;
+            while ($censor && $attempts < 3) {
+                $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.');
             }
-        }
-
-        if ($censor && $attempts == 3) {
-            $this->doAction($this->event->getSource(), 'shrugs.');
         }
 
         // Derive the proper article for the item
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Tea.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Tea.php
new file mode 100644 (file)
index 0000000..c645356
--- /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_Tea
+ * @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_Tea
+ */
+
+/**
+ * Processes requests to serve users tea.
+ *
+ * @category Phergie
+ * @package  Phergie_Plugin_Tea
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie_Plugin_Tea
+ * @uses     Phergie_Plugin_Command pear.phergie.org
+ * @uses     Phergie_Plugin_Serve pear.phergie.org
+ */
+class Phergie_Plugin_Tea 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 tea.
+     *
+     * @param string $request Request including the target and an optional
+     *        suggestion of what tea to serve
+     *
+     * @return void
+     */
+    public function onCommandTea($request)
+    {
+        $format = $this->getConfig(
+            'tea.format',
+            'serves %target% a cup of %item% tea.'
+        );
+
+        $this->plugins->getPlugin('Serve')->serve(
+            dirname(__FILE__) . '/Tea/tea.db',
+            'tea',
+            $format,
+            $request
+        );
+    }
+}
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Tea/db.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Tea/db.php
new file mode 100644 (file)
index 0000000..21fe195
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+if (!defined('__DIR__')) {
+    define('__DIR__', dirname(__FILE__));
+}
+
+// Create database schema
+echo 'Creating database', PHP_EOL;
+$file = __DIR__ . '/tea.db';
+if (file_exists($file)) {
+    unlink($file);
+}
+$db = new PDO('sqlite:' . $file);
+$db->exec('CREATE TABLE tea (name VARCHAR(255), link VARCHAR(255))');
+$db->exec('CREATE UNIQUE INDEX tea_name ON tea (name)');
+$insert = $db->prepare('INSERT INTO tea (name, link) VALUES (:name, :link)');
+
+// Get raw teacuppa.com data set
+echo 'Downloading teacuppa.com data set', PHP_EOL;
+$file = __DIR__ . '/tea-list.html';
+if (!file_exists($file)) {
+    copy('http://www.teacuppa.com/tea-list.asp', $file);
+}
+$contents = file_get_contents($file);
+
+// Extract data from data set
+echo 'Processing teacuppa.com data', 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);
+$teas = $xpath->query('//p[@class="page_title"]/following-sibling::table//a');
+$db->beginTransaction();
+foreach ($teas as $tea) {
+    $name = preg_replace(
+        array('/\s*\v+\s*/', '/\s+tea\s*$/i'),
+        array(' ', ''),
+        $tea->textContent
+    );
+    $link = 'http://teacuppa.com/' . $tea->getAttribute('href');
+    $insert->execute(array($name, $link));
+}
+$db->commit();
+
+// Clean up
+echo 'Cleaning up', PHP_EOL;
+unlink($file);
index e8a02860b2c7ec68f19ab7e727f0f663b554cb40..8559426b6189160280bbbb44dd683ab9ee1155a6 100644 (file)
@@ -31,9 +31,6 @@
  * @link     http://thefuckingweather.com
  * @uses     Phergie_Plugin_Command pear.phergie.org
  * @uses     Phergie_Plugin_Http pear.phergie.org
- *
- * @pluginDesc Detects and responds to requests for current weather 
- *             conditions in a particular location.
  */
 
 class Phergie_Plugin_TheFuckingWeather extends Phergie_Plugin_Abstract
@@ -71,8 +68,6 @@ class Phergie_Plugin_TheFuckingWeather extends Phergie_Plugin_Abstract
      *
      * @return void
      * @todo Implement use of URL shortening here
-     * @pluginCmd [location] Detects and responds to requests for current 
-     *            weather conditions in a particular location.
      */
     public function onCommandThefuckingweather($location)
     {
@@ -92,7 +87,6 @@ class Phergie_Plugin_TheFuckingWeather extends Phergie_Plugin_Abstract
     * @param string $location Location term
     *
     * @return void
-    * @pluginCmd [location] Alias for thefuckingweather command.
     */
     public function onCommandTfw($location)
     {
index 21993f73c58fbde3efdb18ff5fc99d64ec24d0ca..d7d64a4717a35843a1fcc9c1139063f5ce8916f8 100644 (file)
  * @link     http://pear.phergie.org/package/Phergie_Plugin_Tld
  * @uses     extension PDO
  * @uses     extension pdo_sqlite
- *
- * @pluginDesc Provides information for a top level domain.
  */
 class Phergie_Plugin_Tld extends Phergie_Plugin_Abstract
 {
     /**
-     * connection to the database
+     * Connection to the database
+     *
      * @var PDO
      */
     protected $db;
 
     /**
-     * Prepared statement for selecting a single tld
+     * Prepared statement for selecting a single TLD
+     *
      * @var PDOStatement
      */
     protected $select;
 
     /**
-     * Prepared statement for selecting all tlds
+     * Prepared statement for selecting all TLDs
+     *
      * @var PDOStatement
      */
     protected $selectAll;
 
     /**
-     * Checks for dependencies, sets up database and hard coded values
+     * Checks for dependencies and sets up the database and hard-coded values.
      *
      * @return void
      */
@@ -65,9 +66,6 @@ class Phergie_Plugin_Tld extends Phergie_Plugin_Abstract
             $this->fail('PDO and pdo_sqlite extensions must be installed');
         }
 
-        $help = $this->getPluginHandler()->getPlugin('Help');
-        $help->register($this);
-
         $dbFile = dirname(__FILE__) . '/Tld/tld.db';
         try {
             $this->db = new PDO('sqlite:' . $dbFile);
@@ -93,8 +91,6 @@ class Phergie_Plugin_Tld extends Phergie_Plugin_Abstract
      * @param string $tld tld to process
      *
      * @return null
-     *
-     * @pluginCmd .[tld] request details about the tld
      */
     public function onCommandTld($tld)
     {
index b19e9d5aefb3d46c52852dc187925d6dec4121b2..e06ea5640bf9b4bcf819ae638b482d181ab7e136 100644 (file)
@@ -148,7 +148,7 @@ class Phergie_Plugin_Youtube extends Phergie_Plugin_Abstract
     {
         switch ($parsed['host']) {
             case 'youtu.be':
-                $v = ltrim('/', $parsed['path']);
+                $v = ltrim($parsed['path'], '/');
                 break;
             case 'youtube.com':
             case 'www.youtube.com':
index 68d45289e8587a9f897a4aaa65111d9c64b877f6..0ec3569feb070afda8015597e9f9841edcb1de6f 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Phergie 
+ * Phergie
  *
  * PHP version 5
  *
@@ -11,7 +11,7 @@
  * It is also available through the world-wide-web at this URL:
  * http://phergie.org/license
  *
- * @category  Phergie 
+ * @category  Phergie
  * @package   Phergie
  * @author    Phergie Development Team <team@phergie.org>
  * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
@@ -22,7 +22,7 @@
 /**
  * Base class for obtaining and processing incoming events.
  *
- * @category Phergie 
+ * @category Phergie
  * @package  Phergie
  * @author   Phergie Development Team <team@phergie.org>
  * @license  http://phergie.org/license New BSD License
@@ -38,9 +38,9 @@ abstract class Phergie_Process_Abstract
     protected $driver;
 
     /**
-     * Current connection handler instance 
+     * Current connection handler instance
      *
-     * @var Phergie_Connection_Handler 
+     * @var Phergie_Connection_Handler
      */
     protected $connections;
 
@@ -75,9 +75,9 @@ abstract class Phergie_Process_Abstract
     /**
      * Gets the required class refences from Phergie_Bot.
      *
-     * @param Phergie_Bot $bot     Current bot instance in use 
+     * @param Phergie_Bot $bot     Current bot instance in use
      * @param array       $options Optional processor arguments
-     *      
+     *
      * @return void
      */
     public function __construct(Phergie_Bot $bot, array $options = array())
@@ -99,8 +99,8 @@ abstract class Phergie_Process_Abstract
      */
     protected function processEvents(Phergie_Connection $connection)
     {
+        $this->plugins->preDispatch();
         if (count($this->events)) {
-            $this->plugins->preDispatch();
             foreach ($this->events as $event) {
                 $this->ui->onCommand($event, $connection);
 
@@ -110,15 +110,15 @@ abstract class Phergie_Process_Abstract
                     $event->getArguments()
                 );
             }
-            $this->plugins->postDispatch();
-
-            if ($this->events->hasEventOfType(Phergie_Event_Request::TYPE_QUIT)) {
-                $this->ui->onQuit($connection);
-                $this->connections->removeConnection($connection);
-            }
+        }
+        $this->plugins->postDispatch();
 
-            $this->events->clearEvents();
+        if ($this->events->hasEventOfType(Phergie_Event_Request::TYPE_QUIT)) {
+            $this->ui->onQuit($connection);
+            $this->connections->removeConnection($connection);
         }
+
+        $this->events->clearEvents();
     }
 
     /**
index e553ad5a8252850d9de50ecec3ef05a047150e74..78d5959144cf976e04a77f0024b52b4ee1d59664 100644 (file)
@@ -117,11 +117,7 @@ class Phergie_Process_Async extends Phergie_Process_Abstract
             if ($event = $this->driver->getEvent()) {
                 $this->ui->onEvent($event, $connection);
                 $this->plugins->setEvent($event);
-
-                if (!$this->plugins->preEvent()) {
-                    continue;
-                }
-
+                $this->plugins->preEvent();
                 $this->plugins->{'on' . ucfirst($event->getType())}();
             }
 
index 385c65fa221bcf5f0082575b11acb3a8bdf344cb..24adbaf991840a4607fabba913c6fc0c19b7c511 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Phergie 
+ * Phergie
  *
  * PHP version 5
  *
@@ -11,7 +11,7 @@
  * It is also available through the world-wide-web at this URL:
  * http://phergie.org/license
  *
- * @category  Phergie 
+ * @category  Phergie
  * @package   Phergie
  * @author    Phergie Development Team <team@phergie.org>
  * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
@@ -23,7 +23,7 @@
  * Connection data processor which reads all connections looking
  * for a response.
  *
- * @category Phergie 
+ * @category Phergie
  * @package  Phergie
  * @author   Phergie Development Team <team@phergie.org>
  * @license  http://phergie.org/license New BSD License
@@ -32,7 +32,7 @@
 class Phergie_Process_Standard extends Phergie_Process_Abstract
 {
     /**
-     * Obtains and processes incoming events, then sends resulting outgoing 
+     * Obtains and processes incoming events, then sends resulting outgoing
      * events.
      *
      * @return void
@@ -47,11 +47,7 @@ class Phergie_Process_Standard extends Phergie_Process_Abstract
             if ($event = $this->driver->getEvent()) {
                 $this->ui->onEvent($event, $connection);
                 $this->plugins->setEvent($event);
-
-                if (!$this->plugins->preEvent()) {
-                    continue;
-                }
-
+                $this->plugins->preEvent();
                 $this->plugins->{'on' . ucfirst($event->getType())}();
             }