Merged in Phergie changes

This commit is contained in:
Luke Fitzgerald 2010-07-25 16:04:12 -07:00
parent 2645133c43
commit 950685a466
16 changed files with 1226 additions and 660 deletions

View 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)
@ -22,7 +22,7 @@
/**
* Exception related to driver operations.
*
* @category Phergie
* @category Phergie
* @package Phergie
* @author Phergie Development Team <team@phergie.org>
* @license http://phergie.org/license New BSD License
@ -31,13 +31,13 @@
class Phergie_Driver_Exception extends Phergie_Exception
{
/**
* Error indicating that an operation was requested requiring an active
* Error indicating that an operation was requested requiring an active
* connection before one had been set
*/
const ERR_NO_ACTIVE_CONNECTION = 1;
/**
* Error indicating that an operation was requested requiring an active
* Error indicating that an operation was requested requiring an active
* connection where one had been set but not initiated
*/
const ERR_NO_INITIATED_CONNECTION = 2;
@ -51,4 +51,9 @@ class Phergie_Driver_Exception extends Phergie_Exception
* Error indicating that an attempt to send data via a connection failed
*/
const ERR_CONNECTION_WRITE_FAILED = 4;
/**
* Error indicating that an attempt to read data via a connection failed
*/
const ERR_CONNECTION_READ_FAILED = 5;
}

View File

@ -221,6 +221,12 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
{
// Check for a new event on the current connection
$buffer = fgets($this->socket, 512);
if ($buffer === false) {
throw new Phergie_Driver_Exception(
'Unable to read from socket',
Phergie_Driver_Exception::ERR_CONNECTION_READ_FAILED
);
}
// If no new event was found, return NULL
if (empty($buffer)) {
@ -263,8 +269,9 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
case 'privmsg':
case 'notice':
$ctcp = substr(strstr($args, ':'), 1);
if (substr($ctcp, 0, 1) === "\x01" && substr($ctcp, -1) === "\x01") {
$args = $this->parseArguments($args, 2);
list($source, $ctcp) = $args;
if (substr($ctcp, 0, 1) === "\001" && substr($ctcp, -1) === "\001") {
$ctcp = substr($ctcp, 1, -1);
$reply = ($cmd == 'notice');
list($cmd, $args) = array_pad(explode(' ', $ctcp, 2), 2, null);
@ -285,7 +292,7 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
}
break;
case 'action':
$args = array($this->getConnection()->getNick(), $args);
$args = array($source, $args);
break;
default:
@ -293,11 +300,9 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
if ($reply) {
$cmd .= 'Response';
}
$args = array($this->getConnection()->getNick(), $ctcp);
$args = array($source, $args);
break;
}
} else {
$args = $this->parseArguments($args, 2);
}
break;

View File

@ -0,0 +1,79 @@
<?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 = $beer->textContent;
$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 = $line['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');

View File

@ -0,0 +1,182 @@
<?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_Encoding
* @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_Encoding
*/
/**
* Handles decoding markup entities and converting text between character
* encodings.
*
* @category Phergie
* @package Phergie_Plugin_Encoding
* @author Phergie Development Team <team@phergie.org>
* @license http://phergie.org/license New BSD License
* @link http://pear.phergie.org/package/Phergie_Plugin_Encoding
*/
class Phergie_Plugin_Encoding extends Phergie_Plugin_Abstract
{
/**
* Lookup table for entity conversions not supported by
* html_entity_decode()
*
* @var array
* @link http://us.php.net/manual/en/function.get-html-translation-table.php#73409
* @link http://us.php.net/manual/en/function.get-html-translation-table.php#73410
*/
protected static $entities = array(
'&alpha;' => 913,
'&apos;' => 39,
'&beta;' => 914,
'&bull;' => 149,
'&chi;' => 935,
'&circ;' => 94,
'&delta;' => 916,
'&epsilon;' => 917,
'&eta;' => 919,
'&fnof;' => 402,
'&gamma;' => 915,
'&iota;' => 921,
'&kappa;' => 922,
'&lambda;' => 923,
'&ldquo;' => 147,
'&lsaquo;' => 139,
'&lsquo;' => 145,
'&mdash;' => 151,
'&minus;' => 45,
'&mu;' => 924,
'&ndash;' => 150,
'&nu;' => 925,
'&oelig;' => 140,
'&omega;' => 937,
'&omicron;' => 927,
'&phi;' => 934,
'&pi;' => 928,
'&piv;' => 982,
'&psi;' => 936,
'&rdquo;' => 148,
'&rho;' => 929,
'&rsaquo;' => 155,
'&rsquo;' => 146,
'&scaron;' => 138,
'&sigma;' => 931,
'&sigmaf;' => 962,
'&tau;' => 932,
'&theta;' => 920,
'&thetasym;' => 977,
'&tilde;' => 126,
'&trade;' => 153,
'&upsih;' => 978,
'&upsilon;' => 933,
'&xi;' => 926,
'&yuml;' => 159,
'&zeta;' => 918,
);
/**
* Decodes markup entities in a given string.
*
* @param string $string String containing markup entities
* @param string $charset Optional character set name to use in decoding
* entities, defaults to UTF-8
*
* @return string String with markup entities decoded
*/
public function decodeEntities($string, $charset = 'UTF-8')
{
$string = str_ireplace(
array_keys(self::$entities),
array_map('chr', self::$entities),
$string
);
$string = html_entity_decode($string, ENT_QUOTES, $charset);
$string = preg_replace(
array('/&#0*([0-9]+);/me', '/&#x0*([a-f0-9]+);/mei'),
array('$this->codeToUtf(\\1)', '$this->codeToUtf(hexdec(\\1))'),
$string
);
return $string;
}
/**
* Converts a given unicode to its UTF-8 equivalent.
*
* @param int $code Code to convert
* @return string Character corresponding to code
*/
public function codeToUtf8($code)
{
$code = (int) $code;
switch ($code) {
// 1 byte, 7 bits
case 0:
return chr(0);
case ($code & 0x7F):
return chr($code);
// 2 bytes, 11 bits
case ($code & 0x7FF):
return chr(0xC0 | (($code >> 6) & 0x1F)) .
chr(0x80 | ($code & 0x3F));
// 3 bytes, 16 bits
case ($code & 0xFFFF):
return chr(0xE0 | (($code >> 12) & 0x0F)) .
chr(0x80 | (($code >> 6) & 0x3F)) .
chr(0x80 | ($code & 0x3F));
// 4 bytes, 21 bits
case ($code & 0x1FFFFF):
return chr(0xF0 | ($code >> 18)) .
chr(0x80 | (($code >> 12) & 0x3F)) .
chr(0x80 | (($code >> 6) & 0x3F)) .
chr(0x80 | ($code & 0x3F));
}
}
/**
* Transliterates characters in a given string where possible.
*
* @param string $string String containing characters to
* transliterate
* @param string $charsetFrom Optional character set of the string,
* defaults to UTF-8
* @param string $charsetTo Optional character set to which the string
* should be converted, defaults to ISO-8859-1
*
* @return string String with characters transliterated or the original
* string if transliteration was not possible
*/
public function transliterate($string, $charsetFrom = 'UTF-8', $charsetTo = 'ISO-8859-1')
{
// @link http://pecl.php.net/package/translit
if (function_exists('transliterate')) {
$string = transliterate($string, array('han_transliterate', 'diacritical_remove'), $charsetFrom, $charsetTo);
} elseif (function_exists('iconv')) {
$string = iconv($charsetFrom, $charsetTo . '//TRANSLIT', $string);
} else {
// @link http://stackoverflow.com/questions/1284535/php-transliteration/1285491#1285491
$string = preg_replace(
'~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i',
'$1',
htmlentities($string, ENT_COMPAT, $charsetFrom)
);
}
return $string;
}
}

View 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_Google
* @author Phergie Development Team <team@phergie.org>
* @copyright 2008-2010 Phergie Development Team (http://phergie.org)
@ -20,17 +20,18 @@
*/
/**
* Provides commands used to access several services offered by Google
* including search, translation, weather, maps, and currency and general
* Provides commands used to access several services offered by Google
* including search, translation, weather, maps, and currency and general
* value unit conversion.
*
* @category Phergie
* @category Phergie
* @package Phergie_Plugin_Google
* @author Phergie Development Team <team@phergie.org>
* @license http://phergie.org/license New BSD License
* @link http://pear.phergie.org/package/Phergie_Plugin_Google
* @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
*/
@ -44,6 +45,11 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
*/
protected $http;
/**
* Language for Google Services
*/
protected $lang;
/**
* Checks for dependencies.
*
@ -55,6 +61,9 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
$plugins->getPlugin('Command');
$this->http = $plugins->getPlugin('Http');
$plugins->getPlugin('Help')->register($this);
$plugins->getPlugin('Weather');
$this->lang = $this->getConfig('google.lang', 'en');
}
/**
@ -119,8 +128,8 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
$nick = $event->getNick();
if ($count) {
$msg
= $nick . ': ' .
number_format($count, 0) .
= $nick . ': ' .
number_format($count, 0) .
' estimated results for ' . $query;
$this->doPrivmsg($source, $msg);
} else {
@ -132,7 +141,7 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
* Performs a Google Translate search for the given term.
*
* @param string $from Language of the search term
* @param string $to Language to which the search term should be
* @param string $to Language to which the search term should be
* translated
* @param string $query Term to translate
*
@ -157,7 +166,7 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
$this->doPrivmsg($source, $nick . ': ' . $json->responseDetails);
} else {
$this->doPrivmsg(
$source,
$source,
$nick . ': ' . $json->responseData->translatedText
);
}
@ -165,51 +174,104 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
/**
* Performs a Google Weather search for the given term.
*
*
* @param string $location Location to search for
* @param int $offset Optional day offset from the current date
* between 0 and 3 to get the forecast
*
* @return void
*
* @pluginCmd [location] Show the weather for the specified location
*/
public function onCommandGw($location)
public function onCommandGw($location, $offset = null)
{
$url = 'http://www.google.com/ig/api';
$params = array(
'weather' => $location,
'hl' => 'pt-br',
'hl' => $this->lang,
'oe' => 'UTF-8'
);
$response = $this->http->get($url, $params);
$xml = $response->getContent()->weather;
$source = $this->getEvent()->getSource();
if (!isset($xml->problem_cause)) {
$city = $xml->forecast_information->city->attributes()->data[0];
$time = $xml->forecast_information->current_date_time->attributes()
->data[0];
$condition = $xml->current_conditions->condition->attributes()->data[0];
$temp = $xml->current_conditions->temp_c->attributes()->data[0]
. '<27> C';
$humidity = $xml->current_conditions->humidity->attributes()->data[0];
$wind = $xml->current_conditions->wind_condition->attributes()->data[0];
$msg = implode(' - ', array($city, $temp, $condition, $humidity, $wind));
$this->doPrivmsg($source, $msg);
foreach ($xml->forecast_conditions as $key => $linha) {
$day = ucfirst($linha->day_of_week->attributes()->data[0]);
$min = $linha->low->attributes()->data[0];
$max = $linha->high->attributes()->data[0];
$condition = $linha->condition->attributes()->data[0];
$msg
= 'Forecast: ' . $day .
' - Min: ' . $min . '<27> C' .
' - Max: ' . $max . '<27> C' .
' - ' . $condition;
$this->doPrivmsg($source, $msg);
}
} else {
$this->doPrivmsg($source, $xml->problem_cause->attributes()->data[0]);
$event = $this->getEvent();
$source = $event->getSource();
$msg = '';
if ($event->isInChannel()) {
$msg .= $event->getNick() . ': ';
}
if (isset($xml->problem_cause)) {
$msg .= $xml->problem_cause->attributes()->data[0];
$this->doPrivmsg($source, $msg);
return;
}
$temperature = $this->plugins->getPlugin('Temperature');
$forecast = $xml->forecast_information;
$city = $forecast->city->attributes()->data[0];
$zip = $forecast->postal_code->attributes()->data[0];
if ($offset !== null) {
$offset = (int) $offset;
if ($offset < 0) {
$this->doNotice($source, 'Past weather data is not available');
return;
} elseif ($offset > 3) {
$this->doNotice($source, 'Future weather data is limited to 3 days from today');
return;
}
$linha = $xml->forecast_conditions[$offset];
$low = $linha->low->attributes()->data[0];
$high = $linha->high->attributes()->data[0];
$units = $forecast->unit_system->attributes()->data[0];
$condition = $linha->condition->attributes()->data[0];
$day = $linha->day_of_week->attributes()->data[0];
$date = ($offset == 0) ? time() : strtotime('next ' . $day);
$day = ucfirst($day) . ' ' . date('n/j/y', $date);
if ($units == 'US') {
$lowF = $low;
$lowC = $temperature->convertFahrenheitToCelsius($low);
$highF = $high;
$highC = $temperature->convertFahrenheitToCelsius($high);
} else {
$lowC = $low;
$lowF = $temperature->convertCelsiusToFahrenheit($lowC);
$highC = $high;
$highF = $temperature->convertCelsiusToFahrenheit($high);
}
$msg .= 'Forecast for ' . $city . ' (' . $zip . ')'
. ' on ' . $day . ' ::'
. ' Low: ' . $lowF . 'F/' . $lowC . 'C,'
. ' High: ' . $highF . 'F/' . $highC . 'C,'
. ' Conditions: ' . $condition;
} else {
$conditions = $xml->current_conditions;
$condition = $conditions->condition->attributes()->data[0];
$tempF = $conditions->temp_f->attributes()->data[0];
$tempC = $conditions->temp_c->attributes()->data[0];
$humidity = $conditions->humidity->attributes()->data[0];
$wind = $conditions->wind_condition->attributes()->data[0];
$time = $forecast->current_date_time->attributes()->data[0];
$time = date('n/j/y g:i A', strtotime($time)) . ' +0000';
$hiF = $temperature->getHeatIndex($tempF, $humidity);
$hiC = $temperature->convertFahrenheitToCelsius($hiF);
$msg .= 'Weather for ' . $city . ' (' . $zip . ') -'
. ' Temperature: ' . $tempF . 'F/' . $tempC . 'C,'
. ' ' . $humidity . ','
. ' Heat Index: ' . $hiF . 'F/' . $hiC . 'C,'
. ' Conditions: ' . $condition . ','
. ' Updated: ' . $time;
}
$this->doPrivmsg($source, $msg);
}
/**
@ -222,23 +284,23 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
* @pluginCmd [location] Get the location from Google Maps to the location specified
*/
public function onCommandGmap($location)
{
{
$event = $this->getEvent();
$source = $event->getSource();
$nick = $event->getNick();
$location = utf8_encode($location);
$url = 'http://maps.google.com/maps/geo';
$params = array(
'q' => $location,
'output' => 'json',
'gl' => 'br',
'gl' => $this->lang,
'sensor' => 'false',
'oe' => 'utf8',
'mrt' => 'all',
'key' => $this->getConfig('google.key')
);
$response = $this->http->get($url, $params);
$response = $this->http->get($url, $params);
$json = $response->getContent();
if (!empty($json)) {
$qtd = count($json->Placemark);
@ -247,22 +309,22 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
foreach ($json->Placemark as $places) {
$xy = $places->Point->coordinates;
$address = utf8_decode($places->address);
$url = 'http://maps.google.com/maps?sll=' . $xy[1] . ','
$url = 'http://maps.google.com/maps?sll=' . $xy[1] . ','
. $xy[0] . '&z=15';
$msg = $nick . ' -> ' . $address . ' - ' . $url;
$this->doPrivmsg($source, $msg);
}
} else {
$msg
= $nick .
', there are a lot of places with that query.' .
= $nick .
', there are a lot of places with that query.' .
' Try to be more specific!';
$this->doPrivmsg($source, $msg);
}
} elseif ($qtd == 1) {
$xy = $json->Placemark[0]->Point->coordinates;
$address = utf8_decode($json->Placemark[0]->address);
$url = 'http://maps.google.com/maps?sll=' . $xy[1] . ',' . $xy[0]
$url = 'http://maps.google.com/maps?sll=' . $xy[1] . ',' . $xy[0]
. '&z=15';
$msg = $nick . ' -> ' . $address . ' - ' . $url;
$this->doPrivmsg($source, $msg);
@ -275,7 +337,7 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
}
/**
* Perform a Google Convert query to convert a value from one metric to
* Perform a Google Convert query to convert a value from one metric to
* another.
*
* @param string $value Value to convert
@ -310,8 +372,8 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
} else {
$str = str_replace('<span class=bld>', '', $matches[0]);
$str = str_replace($to . '</span>', '', $str);
$text
= number_format($value, 2, ',', '.') . ' ' . $from .
$text
= number_format($value, 2, ',', '.') . ' ' . $from .
' => ' . number_format($str, 2, ',', '.') . ' ' . $to;
$this->doPrivmsg($source, $text);
}
@ -327,7 +389,7 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
*
* @return void
*
* @pluginCmd [quantity] [unit] to [unit2] Convert a value from one
* @pluginCmd [quantity] [unit] to [unit2] Convert a value from one
* metric to another
*/
public function onCommandConvert($query)
@ -363,4 +425,61 @@ class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
$this->doNotice($nick, 'Sorry I couldn\'t find an answer.');
}
}
/**
* Returns the first definition of a Google Dictionary search.
*
* @param string $query Word to get the definition
*
* @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);
//Awesome workaround to remove a lot of slashes from 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;
$this->doPrivmsg($source, $msg);
}else{
if ($this->lang != 'en'){
$temp = $this->lang;
$this->lang = 'en';
$this->onCommandDefine($query);
$this->lang = $temp;
}else{
$msg = $nick . ': No results for this query.';
$this->doPrivmsg($source, $msg);
}
}
}
}

View 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_Http
* @author Phergie Development Team <team@phergie.org>
* @copyright 2008-2010 Phergie Development Team (http://phergie.org)
@ -20,10 +20,10 @@
*/
/**
* Provides an HTTP client for plugins to use in contacting web services or
* Provides an HTTP client for plugins to use in contacting web services or
* retrieving feeds or web pages.
*
* @category Phergie
* @category Phergie
* @package Phergie_Plugin_Http
* @author Phergie Development Team <team@phergie.org>
* @license http://phergie.org/license New BSD License
@ -46,7 +46,7 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
* @var array
*/
protected $handlers;
/**
* Initializes the handler lookup table.
*
@ -55,8 +55,10 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
public function onLoad()
{
$this->handlers = array(
'(?:application|text)/xml(?:;.*)?' => 'simplexml_load_string',
'(?:(?:application|text)/(?:x-)?json)|text/javascript.*' => 'json_decode',
'(?:application|text)/xml(?:;.*)?'
=> 'simplexml_load_string',
'(?:(?:application|text)/(?:x-)?json)|text/javascript.*'
=> 'json_decode',
);
if (is_array($this->config['http.handlers'])) {
@ -68,10 +70,10 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
}
/**
* Sets a handler callback for a content type, which is called when a
* response of that content type is received to perform any needed
* transformations on the response body content before storing it in the
* response object. Note that the calling plugin is responsible for
* Sets a handler callback for a content type, which is called when a
* response of that content type is received to perform any needed
* transformations on the response body content before storing it in the
* response object. Note that the calling plugin is responsible for
* indicating any dependencies related to specified handler callbacks.
*
* @param string $type PCRE regular expression (without delimiters) that
@ -96,12 +98,12 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
}
/**
* Supporting method that parses the status line of an HTTP response
* Supporting method that parses the status line of an HTTP response
* message.
*
* @param string $status Status line
*
* @return array Associative array containing the HTTP version, response
* @return array Associative array containing the HTTP version, response
* code, and response description
*/
protected function parseStatusLine($status)
@ -116,7 +118,7 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
}
/**
* Supporting method that acts as an error handler to intercept HTTP
* Supporting method that acts as an error handler to intercept HTTP
* responses resulting in PHP-level errors.
*
* @param int $errno Level of the error raised
@ -124,13 +126,13 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
* @param string $errfile Name of the file in which the error was raised
* @param string $errline Line number on which the error was raised
*
* @return bool Always returns TRUE to allow normal execution to
* @return bool Always returns TRUE to allow normal execution to
* continue once this method terminates
*/
protected function handleError($errno, $errstr, $errfile, $errline)
public function handleError($errno, $errstr, $errfile, $errline)
{
if ($httperr = strstr($errstr, 'HTTP/')) {
$parts = $this->parseStatusLine($httperr);
$parts = $this->parseStatusLine($httperr);
$this->response
->setCode($parts['code'])
->setMessage($parts['message']);
@ -143,9 +145,9 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
* Supporting method that executes a request and handles the response.
*
* @param string $url URL to request
* @param array $context Associative array of stream context parameters
* @param array $context Associative array of stream context parameters
*
* @return Phergie_Plugin_Http_Response Object representing the response
* @return Phergie_Plugin_Http_Response Object representing the response
* resulting from the request
*/
public function request($url, array $context)
@ -164,6 +166,9 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
$message = $status['message'];
$headers = array();
foreach (array_slice($meta['wrapper_data'], 1) as $header) {
if (!strpos($header, ':')) {
continue;
}
list($name, $value) = explode(': ', $header, 2);
$headers[$name] = $value;
}
@ -174,7 +179,7 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
->setMessage($message)
->setHeaders($headers)
->setMeta($meta);
$body = stream_get_contents($stream);
$type = $this->response->getHeaders('content-type');
foreach ($this->handlers as $expr => $handler) {
@ -218,7 +223,7 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
* @param string $url URL for the request
* @param array $query Optional associative array of parameters
* constituting the URL query string if $url has none
* @param array $context Optional associative array of additional stream
* @param array $context Optional associative array of additional stream
* context parameters
*
* @return Phergie_Plugin_Http_Response Received response data
@ -238,25 +243,26 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
* Performs a POST request.
*
* @param string $url URL for the request
* @param array $query Optional associative array of parameters
* @param array $query Optional associative array of parameters
* constituting the URL query string if $url has none
* @param array $post Optional associative array of parameters
* constituting the POST request body if it is using the
* @param array $post Optional associative array of parameters
* constituting the POST request body if it is using the
* traditional URL-encoded format
* @param array $context Optional associative array of additional stream
* @param array $context Optional associative array of additional stream
* context parameters
*
* @return Phergie_Plugin_Http_Response Received response data
*/
public function post($url, array $query = array(), array $post = array(), array $context = array())
{
public function post($url, array $query = array(),
array $post = array(), array $context = array()
) {
if (!empty($params)) {
$url .= '?' . http_build_query($query);
}
$context['method'] = 'POST';
if (!empty($post)
if (!empty($post)
&& (!empty($context['header'])
xor stripos($context['header'], 'Content-Type'))
) {
@ -265,7 +271,7 @@ class Phergie_Plugin_Http extends Phergie_Plugin_Abstract
} else {
$context['header'] = '';
}
$context['header'] .=
$context['header'] .=
'Content-Type: application/x-www-form-urlencoded';
$context['content'] = http_build_query($post);
}

View 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_Http
* @author Phergie Development Team <team@phergie.org>
* @copyright 2008-2010 Phergie Development Team (http://phergie.org)
@ -20,9 +20,9 @@
*/
/**
* Data structure for HTTP response information.
* Data structure for HTTP response information.
*
* @category Phergie
* @category Phergie
* @package Phergie_Plugin_Http
* @author Phergie Development Team <team@phergie.org>
* @license http://phergie.org/license New BSD License
@ -33,7 +33,7 @@ class Phergie_Plugin_Http_Response
/**
* HTTP response code or 0 if no HTTP response was received
*
* @var string
* @var string
*/
protected $code;
@ -42,7 +42,7 @@ class Phergie_Plugin_Http_Response
*
* @var array
*/
protected $codeStrings = array(
protected static $codeStrings = array(
0 => 'No Response',
100 => 'Continue',
200 => 'OK',
@ -75,7 +75,7 @@ class Phergie_Plugin_Http_Response
);
/**
* Description of the HTTP response code or the error message if no HTTP
* Description of the HTTP response code or the error message if no HTTP
* response was received
*
* @var string
@ -135,11 +135,11 @@ class Phergie_Plugin_Http_Response
{
$code = $this->code;
if (!isset($this->codeStrings[$code])) {
if (!isset(self::$codeStrings[$code])) {
return 'Unkown HTTP Status';
}
return $this->codeStrings[$code];
return self::$codeStrings[$code];
}
/**
@ -198,7 +198,7 @@ class Phergie_Plugin_Http_Response
/**
* Returns the content of the response body.
*
* @return mixed Response body content, decoded for supported content
* @return mixed Response body content, decoded for supported content
* types
*/
public function getContent()
@ -209,7 +209,7 @@ class Phergie_Plugin_Http_Response
/**
* Sets the response headers.
*
* @param array $headers Associative array of response headers indexed
* @param array $headers Associative array of response headers indexed
* by header name
*
* @return Phergie_Plugin_Http_Response Provides a fluent interface
@ -223,14 +223,14 @@ class Phergie_Plugin_Http_Response
}
/**
* Returns all response headers or the value of a single specified
* Returns all response headers or the value of a single specified
* response header.
*
* @param string $name Optional name of a single header for which the
* @param string $name Optional name of a single header for which the
* associated value should be returned
*
* @return array|string Associative array of all header values, a string
* containing the value of the header indicated by $name if one
* @return array|string Associative array of all header values, a string
* containing the value of the header indicated by $name if one
* is set, or null if one is not
*/
public function getHeaders($name = null)
@ -261,11 +261,11 @@ class Phergie_Plugin_Http_Response
/**
* Returns all metadata or the value of a single specified metadatum.
*
* @param string $name Optional name of a single metadatum for which the
* @param string $name Optional name of a single metadatum for which the
* associated value should be returned
*
* @return array|string|null Associative array of all metadata values, a
* string containing the value of the metadatum indicated by
*
* @return array|string|null Associative array of all metadata values, a
* string containing the value of the metadatum indicated by
* $name if one is set, or null if one is not
*/
public function getMeta($name = null)

View File

@ -0,0 +1,303 @@
<?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_Lart
* @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_Lart
*/
/**
* Accepts terms and corresponding definitions for storage to a local data
* source and performs and returns the result of lookups for term definitions
* as they are requested.
*
* @category Phergie
* @package Phergie_Plugin_Lart
* @author Phergie Development Team <team@phergie.org>
* @license http://phergie.org/license New BSD License
* @link http://pear.phergie.org/package/Phergie_Plugin_Lart
* @uses Phergie_Plugin_Command pear.phergie.org
* @uses extension PDO
* @uses extension pdo_sqlite
*/
class Phergie_Plugin_Lart extends Phergie_Plugin_Abstract
{
/**
* PDO instance for the database
*
* @var PDO
*/
protected $db;
/**
* Prepared statement for inserting a new definition
*
* @var PDOStatement
*/
protected $save;
/**
* Prepared statement for deleting the definition for a given term
*
* @var PDOStatement
*/
protected $delete;
/**
* Prepared statement for searching for a definition for which the term
* matches as a regular expression against a given search string
*
* @var PDOStatement
*/
protected $process;
/**
* Prepared statement for searching for a definition by its exact term
*
* @var PDOStatement
*/
protected $select;
/**
* Checks for dependencies and initializes the database.
*
* @return void
*/
public function onLoad()
{
if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
$this->fail('PDO and pdo_sqlite extensions must be installed');
}
$this->plugins->getPlugin('Command');
$dir = dirname(__FILE__) . '/' . $this->getName();
$path = $dir . '/lart.db';
$exists = file_exists($path);
if (!$exists) {
mkdir($dir);
}
try {
$this->db = new PDO('sqlite:' . $path);
} catch (PDO_Exception $e) {
throw new Phergie_Plugin_Exception($e->getMessage());
}
$this->db->sqliteCreateFunction('preg_match', 'preg_match');
if (!$exists) {
$this->db->exec('
CREATE TABLE lart (
name VARCHAR(255),
definition TEXT,
hostmask VARCHAR(50),
tstamp VARCHAR(19)
)
');
$this->db->exec('
CREATE UNIQUE INDEX lart_name ON lart (name)
');
}
$this->save = $this->db->prepare('
REPLACE INTO lart (name, definition, hostmask, tstamp)
VALUES (:name, :definition, :hostmask, :tstamp)
');
$this->process = $this->db->prepare('
SELECT *
FROM lart
WHERE preg_match(name, :name)
');
$this->select = $this->db->prepare('
SELECT *
FROM lart
WHERE name = :name
');
$this->delete = $this->db->prepare('
DELETE FROM lart
WHERE name = :name
');
}
/**
* Retrieves the definition for a given term if it exists.
*
* @param string $term Term to search for
*
* @return mixed String containing the definition or FALSE if no definition
* exists
*/
protected function getLart($term)
{
$this->process->execute(array(':name' => $term));
$row = $this->process->fetchObject();
if ($row === false) {
return false;
}
preg_match($row->name, $term, $match);
$definition = preg_replace(
"/(?:\\\\|\\$)([0-9]+)/e",
'$match[\1]',
$row->definition
);
$event = $this->getEvent();
$definition = str_replace(
array('$source', '$nick'),
array($event->getSource(), $event->getNick()),
$definition
);
return $definition;
}
/**
* Deletes a given definition.
*
* @param string $term Term for which the definition should be deleted
*
* @return boolean TRUE if the definition was found and deleted, FALSE
* otherwise
*/
protected function deleteLart($term)
{
$this->delete->execute(array(':name' => $term));
return ($this->delete->rowCount() > 0);
}
/**
* Saves a given definition.
*
* @param string $term Term to trigger a response containing the
* corresponding definition, may be a regular expression
* @param string $definition Definition corresponding to the term
*
* @return boolean TRUE if the definition was saved successfully, FALSE
* otherwise
*/
protected function saveLart($term, $definition)
{
$data = array(
':name' => $term,
':definition' => $definition,
':hostmask' => (string) $this->getEvent()->getHostmask(),
':tstamp' => time()
);
$this->save->execute($data);
return ($this->save->rowCount() > 0);
}
/**
* Returns information about a definition.
*
* @param string $term Term about which to return information
*
* @return void
*/
public function onCommandLartinfo($term)
{
$this->select->execute(array(':name' => $term));
$row = $this->select->fetchObject();
$msg = $this->getEvent()->getNick() . ': ';
if (!$row) {
$msg .= 'Lart not found';
} else {
$msg .= 'Term: ' . $row->name
. ', Definition: ' . $row->definition
. ', User: ' . $row->hostmask
. ', Added: ' . date('n/j/y g:i A', $row->tstamp);
}
$this->doNotice($this->getEvent()->getSource(), $msg);
}
/**
* Creates a new definition.
*
* @param string $term Term to add
* @param string $definition Definition to add
*
* @return void
*/
public function onCommandAddlart($term, $definition)
{
$result = $this->saveLart($term, $definition);
if ($result) {
$msg = 'Lart saved successfully';
} else {
$msg = 'Lart could not be saved';
}
$this->doNotice($this->getEvent()->getSource(), $msg);
}
/**
* Removes an existing definition.
*
* @param string $term Term for which the definition should be removed
*
* @return void
*/
public function onCommandDeletelart($term)
{
$source = $this->getEvent()->getSource();
if ($this->deleteLart($term)) {
$msg = 'Lart deleted successfully';
} else {
$msg = 'Lart not found';
}
$this->doNotice($source, $msg);
}
/**
* Processes definition triggers in the text of the current event.
*
* @return void
*/
protected function processLart()
{
$lart = $this->getLart($this->getEvent()->getText());
if ($lart) {
if (strpos($lart, '/me') === 0) {
$lart = substr($lart, 4);
$method = 'doAction';
} else {
$method = 'doPrivmsg';
}
$this->$method($this->getEvent()->getSource(), $lart);
}
}
/**
* Processes definition triggers in messages.
*
* @return void
*/
public function onPrivmsg()
{
$this->processLart();
}
/**
* Processes definition triggers in CTCP actions.
*
* @return void
*/
public function onAction()
{
$this->processLart();
}
}

View File

@ -57,16 +57,13 @@ class Phergie_Plugin_NickServ extends Phergie_Plugin_Abstract
$this->getPluginHandler()->getPlugin('Command');
// Get the name of the NickServ bot, defaults to NickServ
$this->botNick = $this->config['nickserv.botnick'];
if (!$this->botNick) {
$this->botNick = 'NickServ';
}
$this->botNick = $this->getConfig('nickserv.botnick', 'NickServ');
// Get the identify message
$this->identifyMessage = $this->config['nickserv.identify_message'];
if (!$this->identifyMessage) {
$this->identifyMessage = '/This nickname is registered./';
}
$this->identifyMessage = $this->getConfig(
'nickserv.identify_message',
'/This nickname is registered./'
);
}
/**

View File

@ -30,6 +30,8 @@
* @link http://pear.phergie.org/package/Phergie_Plugin_Remind
* @uses Phergie_Plugin_Command pear.phergie.org
* @uses Phergie_Plugin_Time pear.phergie.org
* @uses extension PDO
* @uses extension pdo_sqlite
*/
class Phergie_Plugin_Remind extends Phergie_Plugin_Abstract
{
@ -67,15 +69,11 @@ class Phergie_Plugin_Remind extends Phergie_Plugin_Abstract
$plugins = $this->getPluginHandler();
$plugins->getPlugin('Command');
$plugins->getPlugin('Time');
}
/**
* Creates the database if it does not already exist.
*
* @return void
*/
public function onConnect()
{
if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
$this->fail('PDO and pdo_sqlite extensions must be installed');
}
$dir = dirname(__FILE__) . '/' . $this->getName();
$path = $dir . '/reminder.db';
if (!file_exists($dir)) {

View File

@ -0,0 +1,81 @@
<?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_Temperature
* @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_Temperature
*/
/**
* Performs temperature calculations for other plugins.
*
* @category Phergie
* @package Phergie_Plugin_Temperature
* @author Phergie Development Team <team@phergie.org>
* @license http://phergie.org/license New BSD License
* @link http://pear.phergie.org/package/Phergie_Plugin_Temperature
*/
class Phergie_Plugin_Temperature extends Phergie_Plugin_Abstract
{
/**
* Converts a temperature in Celsius to Fahrenheit.
*
* @param int $temp Temperature in Celsius
*
* @return int Temperature converted to Fahrenheit
*/
public function convertCelsiusToFahrenheit($temp)
{
return round(((((int) $temp * 9) / 5) + 32));
}
/**
* Converts a temperature in Fahrenheit to Celsius.
*
* @param int $temp Temperature in Fahrenheit
*
* @return int Temperature converted to Celsius
*/
public function convertFahrenheitToCelsius($temp)
{
return round(((((int) $temp - 32) * 5) / 9));
}
/**
* Calculates the heat index (i.e. "feels like" temperature) based on
* temperature and relative humidity.
*
* @param int $temperature Temperature in degrees Fahrenheit
* @param int $humidity Relative humidity (ex: 68)
* @return int Heat index in degrees Fahrenheit
*/
public function getHeatIndex($temperature, $humidity)
{
$temperature2 = $temperature * $temperature;
$humidity2 = $humidity * $humidity;
return round(
-42.379 +
(2.04901523 * $temperature) +
(10.14333127 * $humidity) -
(0.22475541 * $temperature * $humidity) -
(0.00683783 * $temperature2) -
(0.05481717 * $humidity2) +
(0.00122874 * $temperature2 * $humidity) +
(0.00085282 * $temperature * $humidity2) -
(0.00000199 * $temperature2 * $humidity2)
);
}
}

View File

@ -29,7 +29,6 @@
* @author Phergie Development Team <team@phergie.org>
* @license http://phergie.org/license New BSD License
* @link http://pear.phergie.org/package/Phergie_Plugin_Tld
* @uses Phergie_Plugin_Http pear.phergie.org
* @uses extension PDO
* @uses extension pdo_sqlite
*
@ -42,11 +41,6 @@ class Phergie_Plugin_Tld extends Phergie_Plugin_Abstract
* @var PDO
*/
protected $db;
/**
* Some fixed TLD values, keys must be lowercase
* @var array
*/
protected static $fixedTlds;
/**
* Prepared statement for selecting a single tld
@ -67,19 +61,13 @@ class Phergie_Plugin_Tld extends Phergie_Plugin_Abstract
*/
public function onLoad()
{
if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
$this->fail('PDO and pdo_sqlite extensions must be installed');
}
$help = $this->getPluginHandler()->getPlugin('Help');
$help->register($this);
if (!is_array(self::$fixedTlds)) {
self::$fixedTlds = array(
'phergie' => 'You can find Phergie at http://www.phergie.org',
'spoon' => 'Don\'t you know? There is no spoon!',
'poo' => 'Do you really think that\'s funny?',
'root' => 'Diagnostic marker to indicate '
. 'a root zone load was not truncated.'
);
}
$dbFile = dirname(__FILE__) . '/Tld/tld.db';
try {
$this->db = new PDO('sqlite:' . $dbFile);
@ -124,19 +112,15 @@ class Phergie_Plugin_Tld extends Phergie_Plugin_Abstract
*
* @param string $tld TLD to search for
*
* @return string Definition of the given TLD
* @return mixed Definition of the given TLD as a string or false if unknown
*/
public function getTld($tld)
{
$tld = trim(strtolower($tld));
if (isset(self::$fixedTlds[$tld])) {
return self::$fixedTlds[$tld];
} else {
if ($this->select->execute(array('tld' => $tld))) {
$tlds = $this->select->fetch();
if (is_array($tlds)) {
return '(' . $tlds['type'] . ') ' . $tlds['description'];
}
if ($this->select->execute(array('tld' => $tld))) {
$tlds = $this->select->fetch();
if (is_array($tlds)) {
return '(' . $tlds['type'] . ') ' . $tlds['description'];
}
}
return false;
@ -145,7 +129,8 @@ class Phergie_Plugin_Tld extends Phergie_Plugin_Abstract
/**
* Retrieves a list of all the TLDs and their definitions
*
* @return array Array of all the TLDs and their definitions
* @return mixed Array of all the TLDs and their definitions or FALSE on
* failure
*/
public function getTlds()
{
@ -159,7 +144,6 @@ class Phergie_Plugin_Tld extends Phergie_Plugin_Abstract
. $tld['description'];
}
}
unset($tlds);
return $tldinfo;
}
}

View File

@ -31,7 +31,9 @@
* @author Phergie Development Team <team@phergie.org>
* @license http://phergie.org/license New BSD License
* @link http://pear.phergie.org/package/Phergie_Plugin_Url
* @uses Phergie_Plugin_Encoding pear.phergie.org
* @uses Phergie_Plugin_Http pear.phergie.org
* @uses Phergie_Plugin_Tld pear.phergie.org
*/
class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
{
@ -121,50 +123,6 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
*/
protected $detectSchemeless = false;
/**
* List of error messages to return when the requested URL returns an
* HTTP error
*
* @var array
*/
protected $httpErrors = array(
100 => '100 Continue',
200 => '200 OK',
201 => '201 Created',
204 => '204 No Content',
206 => '206 Partial Content',
300 => '300 Multiple Choices',
301 => '301 Moved Permanently',
302 => '302 Found',
303 => '303 See Other',
304 => '304 Not Modified',
307 => '307 Temporary Redirect',
400 => '400 Bad Request',
401 => '401 Unauthorized',
403 => '403 Forbidden',
404 => '404 Not Found',
405 => '405 Method Not Allowed',
406 => '406 Not Acceptable',
408 => '408 Request Timeout',
410 => '410 Gone',
413 => '413 Request Entity Too Large',
414 => '414 Request URI Too Long',
415 => '415 Unsupported Media Type',
416 => '416 Requested Range Not Satisfiable',
417 => '417 Expectation Failed',
500 => '500 Internal Server Error',
501 => '501 Method Not Implemented',
503 => '503 Service Unavailable',
506 => '506 Variant Also Negotiates'
);
/**
* An array containing a list of TLDs used for non-scheme matches
*
* @var array
*/
protected $tldList = array();
/**
* Shortener object
*/
@ -176,12 +134,17 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
protected $renderers = array();
/**
* Initializes settings, checks dependencies.
* Checks for dependencies.
*
* @return void
*/
public function onConnect()
public function onLoad()
{
$plugins = $this->plugins;
$plugins->getPlugin('Encoding');
$plugins->getPlugin('Http');
$plugins->getPlugin('Tld');
// make the shortener configurable
$shortener = $this->getConfig('url.shortener', 'Trim');
$shortener = "Phergie_Plugin_Url_Shorten_{$shortener}";
@ -191,14 +154,6 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
$this->fail("Declared shortener class {$shortener} is not of proper ancestry");
}
// Get a list of valid TLDs
if (!is_array($this->tldList) || count($this->tldList) <= 6) {
$tldPath = dirname(__FILE__) . '/Url/url.tld.txt';
$this->tldList = explode("\n", file_get_contents($tldPath));
$this->debug('Loaded ' . count($this->tldList) . ' tlds');
rsort($this->tldList);
}
// load config (a bit ugly, but focusing on porting):
foreach (
array(
@ -226,16 +181,130 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
* @return void
*/
public function onPrivmsg()
{
$this->handleMsg();
}
/**
* Checks an incoming message for the presence of a URL and, if one is
* found, responds with its title if it is an HTML document and the
* shortened equivalent of its original URL if it meets length requirements.
*
* @todo Update this to pull configuration settings from $this->config
* rather than caching them as class properties
* @return void
*/
public function onAction()
{
$this->handleMsg();
}
/**
* Handles message events and responds with url titles.
*
* @return void
*/
protected function handleMsg()
{
$source = $this->getEvent()->getSource();
$user = $this->getEvent()->getNick();
$responses = array();
$urls = $this->findUrls($this->getEvent()->getArgument(1));
foreach ($urls as $parsed) {
$url = $parsed['glued'];
// allow out-of-class renderers to handle this URL
foreach ($this->renderers as $renderer) {
if ($renderer->renderUrl($parsed) === true) {
// renderers should return true if they've fully
// rendered the passed URL (they're responsible
// for their own output)
$this->debug('Handled by renderer: ' . get_class($renderer));
continue 2;
}
}
// Convert url
$shortenedUrl = $this->shortener->shorten($url);
if (!$shortenedUrl) {
$this->debug('Invalid Url: Unable to shorten. (' . $url . ')');
$shortenedUrl = $url;
}
// Prevent spamfest
if ($this->checkUrlCache($url, $shortenedUrl)) {
$this->debug('Invalid Url: URL is in the cache. (' . $url . ')');
continue;
}
$title = $this->getTitle($url);
if (!empty($title)) {
$responses[] = str_replace(
array(
'%title%',
'%link%',
'%nick%'
), array(
$title,
$shortenedUrl,
$user
), $this->messageFormat
);
}
// Update cache
$this->updateUrlCache($url, $shortenedUrl);
unset($title, $shortenedUrl, $title);
}
// Check to see if there were any URL responses, format them and handle if they
// get merged into one message or not
if (count($responses) > 0) {
if ($this->mergeLinks) {
$message = str_replace(
array(
'%message%',
'%nick%'
), array(
implode('; ', $responses),
$user
), $this->baseFormat
);
$this->doPrivmsg($source, $message);
} else {
foreach ($responses as $response) {
$message = str_replace(
array(
'%message%',
'%nick%'
), array(
implode('; ', $responses),
$user
), $this->baseFormat
);
$this->doPrivmsg($source, $message);
}
}
}
}
/**
* Detect URLs in a given string.
*
* @param string $message the string to detect urls in
*
* @return array the array of urls found
*/
public function findUrls($message)
{
$pattern = '#'.($this->detectSchemeless ? '' : 'https?://').'(?:([0-9]{1,3}(?:\.[0-9]{1,3}){3})(?![^/]) | ('
.($this->detectSchemeless ? '(?<!http:/|https:/)[@/\\\]' : '').')?(?:(?:[a-z0-9_-]+\.?)+\.[a-z0-9]{1,6}))[^\s]*#xis';
$urls = array();
// URL Match
if (preg_match_all($pattern, $this->getEvent()->getArgument(1), $matches, PREG_SET_ORDER)) {
$responses = array();
if (preg_match_all($pattern, $message, $matches, PREG_SET_ORDER)) {
foreach ($matches as $m) {
$url = trim(rtrim($m[0], ', ].?!;'));
@ -251,17 +320,6 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
continue;
}
// allow out-of-class renderers to handle this URL
foreach ($this->renderers as $renderer) {
if ($renderer->renderUrl($parsed) === true) {
// renderers should return true if they've fully
// rendered the passed URL (they're responsible
// for their own output)
$this->debug('Handled by renderer: ' . get_class($renderer));
continue 2;
}
}
// Check to see if the given IP/Host is valid
if (!empty($m[1]) and !$this->checkValidIP($m[1])) {
$this->debug('Invalid Url: ' . $m[1] . ' is not a valid IP address. (' . $url . ')');
@ -275,7 +333,7 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
$parsed['tld'] = ($pos !== false ? substr($parsed['host'], ($pos+1)) : '');
// Check to see if the URL has a valid TLD
if (is_array($this->tldList) && !in_array(strtolower($parsed['tld']), $this->tldList)) {
if ($this->plugins->tld->getTld($parsed['tld']) === false) {
$this->debug('Invalid Url: ' . $parsed['tld'] . ' is not a supported TLD. (' . $url . ')');
continue;
}
@ -295,73 +353,12 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
$this->debug('Invalid Url: ' . $parsed['scheme'] . ' is not a supported scheme. (' . $url . ')');
continue;
}
$url = $this->glueURL($parsed);
unset($parsed);
// Convert url
$shortenedUrl = $this->shortener->shorten($url);
if (!$shortenedUrl) {
$this->debug('Invalid Url: Unable to shorten. (' . $url . ')');
continue;
}
// Prevent spamfest
if ($this->checkUrlCache($url, $shortenedUrl)) {
$this->debug('Invalid Url: URL is in the cache. (' . $url . ')');
continue;
}
$title = self::getTitle($url);
if (!empty($title)) {
$responses[] = str_replace(
array(
'%title%',
'%link%',
'%nick%'
), array(
$title,
$shortenedUrl,
$user
), $this->messageFormat
);
}
// Update cache
$this->updateUrlCache($url, $shortenedUrl);
unset($title, $shortenedUrl, $title);
}
/**
* Check to see if there were any URL responses, format them and handle if they
* get merged into one message or not
*/
if (count($responses) > 0) {
if ($this->mergeLinks) {
$message = str_replace(
array(
'%message%',
'%nick%'
), array(
implode('; ', $responses),
$user
), $this->baseFormat
);
$this->doPrivmsg($source, $message);
} else {
foreach ($responses as $response) {
$message = str_replace(
array(
'%message%',
'%nick%'
), array(
implode('; ', $responses),
$user
), $this->baseFormat
);
$this->doPrivmsg($source, $message);
}
}
$urls[] = $parsed + array('glued' => $this->glueURL($parsed));
}
}
return $urls;
}
/**
@ -454,52 +451,13 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
*/
protected function decode($str, $trim = null)
{
$out = $this->decodeTranslit($str);
$out = $this->plugins->encoding->transliterate($str);
if ($trim > 0) {
$out = substr($out, 0, $trim) . (strlen($out) > $trim ? '...' : '');
}
return $out;
}
/**
* Custom error handler meant to handle 404 errors and such
*
* @param int $errno the error code
* @param string $errstr the error string
* @param string $errfile file the error occured in
* @param int $errline line the error occured on
*
* @return bool
*/
public function onPhpError($errno, $errstr, $errfile, $errline)
{
if ($errno === E_WARNING) {
// Check to see if there was HTTP warning while connecting to the site
if (preg_match('{HTTP/1\.[01] ([0-9]{3})}i', $errstr, $m)) {
$this->errorStatus = $m[1];
$this->errorMessage = (isset($this->httpErrors[$m[1]]) ? $this->httpErrors[$m[1]] : $m[1]);
$this->debug('PHP Warning: ' . $errstr . 'in ' . $errfile . ' on line ' . $errline);
return true;
}
// Safely ignore these SSL warnings so they don't appear in the log
if (stripos($errstr, 'SSL: fatal protocol error in') !== false
|| stripos($errstr, 'failed to open stream') !== false
|| stripos($errstr, 'HTTP request failed') !== false
|| stripos($errstr, 'SSL: An existing connection was forcibly closed by the remote host') !== false
|| stripos($errstr, 'Failed to enable crypto in') !== false
|| stripos($errstr, 'SSL: An established connection was aborted by the software in your host machine') !== false
|| stripos($errstr, 'SSL operation failed with code') !== false
|| stripos($errstr, 'unable to connect to') !== false
) {
$this->errorStatus = true;
$this->debug('PHP Warning: ' . $errstr . 'in ' . $errfile . ' on line ' . $errline);
return true;
}
}
return false;
}
/**
* Takes a url, parses and cleans the URL without of all the junk
* and then return the hex checksum of the url.
@ -511,7 +469,7 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
protected function getUrlChecksum($url)
{
$checksum = strtolower(urldecode($this->glueUrl($url, true)));
$checksum = preg_replace('#\s#', '', $this->decodeTranslit($checksum));
$checksum = preg_replace('#\s#', '', $this->plugins->encoding->transliterate($checksum));
return dechex(crc32($checksum));
}
@ -628,19 +586,20 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
'user_agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12'
);
$response = $http->get($url, array(), $options);
$response = $http->head($url, array(), $options);
$header = $response->getHeaders('Content-Type');
if (!preg_match('#^(text/x?html|application/xhtml+xml)(?:;.*)?$#', $header)) {
$title = $header;
}
$content = $response->getContent();
if (empty($title)) {
} else {
$response = $http->get($url, array(), $options);
$content = $response->getContent();
if (preg_match('#<title[^>]*>(.*?)</title>#is', $content, $match)) {
$title = html_entity_decode(trim($match[1]));
$title = preg_replace('/[\s\v]+/', ' ', trim($match[1]));
}
}
$encoding = $this->plugins->getPlugin('Encoding');
$title = $encoding->decodeEntities($title);
if (empty($title)) {
if ($response->isError()) {
@ -665,19 +624,6 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
echo "(DEBUG:Url) $msg\n";
}
/**
* Placeholder/porting helper. Has no function.
*
* @param string $str a string to return
*
* @return string
*/
protected function decodeTranslit($str)
{
// placeholder/porting helper
return $str;
}
/**
* Add a renderer to the stack
*
@ -687,7 +633,6 @@ class Phergie_Plugin_Url extends Phergie_Plugin_Abstract
*/
public function registerRenderer($obj)
{
$this->renderers[] = $obj;
array_unique($this->renderers);
$this->renderers[spl_object_hash($obj)] = $obj;
}
}

View File

@ -1,273 +0,0 @@
ac
ad
ae
aero
af
ag
ai
al
am
an
ao
aq
ar
arpa
as
asia
at
au
aw
ax
az
ba
bb
bd
be
bf
bg
bh
bi
biz
bj
bl
bm
bn
bo
br
bs
bt
bv
bw
by
bz
ca
cat
cc
cd
cf
cg
ch
ci
ck
cl
cm
cn
co
com
coop
cr
cu
cv
cx
cy
cz
de
dj
dk
dm
do
dz
ec
edu
ee
eg
eh
er
es
et
eu
fi
fj
fk
fm
fo
fr
ga
gb
gd
ge
gf
gg
gh
gi
gl
gm
gn
gov
gp
gq
gr
gs
gt
gu
gw
gy
hk
hm
hn
hr
ht
hu
id
ie
il
im
in
info
int
io
iq
ir
is
it
je
jm
jo
jobs
jp
ke
kg
kh
ki
km
kn
kp
kr
kw
ky
kz
la
lb
lc
li
lk
lr
ls
lt
lu
lv
ly
ma
mc
md
me
mf
mg
mh
mil
mk
ml
mm
mn
mo
mobi
mp
mq
mr
ms
mt
mu
museum
mv
mw
mx
my
mz
na
name
nc
ne
net
nf
ng
ni
nl
no
np
nr
nu
nz
om
org
pa
pe
pf
pg
ph
pk
pl
pm
pn
pr
pro
ps
pt
pw
py
qa
re
ro
rs
ru
rw
sa
sb
sc
sd
se
sg
sh
si
sj
sk
sl
sm
sn
so
sr
st
su
sv
sy
sz
tc
td
tel
tf
tg
th
tj
tk
tl
tm
tn
to
tp
tr
travel
tt
tv
tw
tz
ua
ug
uk
um
us
uy
uz
va
vc
ve
vg
vi
vn
vu
wf
ws
ye
yt
yu
za
zm
zw

View File

@ -34,6 +34,7 @@
* @link http://www.weather.com/services/xmloap.html
* @uses Phergie_Plugin_Command pear.phergie.org
* @uses Phergie_Plugin_Http pear.phergie.org
* @uses Phergie_Plugin_Temperature pear.phergie.org
* @uses extension SimpleXML
*/
class Phergie_Plugin_Weather extends Phergie_Plugin_Abstract
@ -48,6 +49,7 @@ class Phergie_Plugin_Weather extends Phergie_Plugin_Abstract
$plugins = $this->getPluginHandler();
$plugins->getPlugin('Command');
$plugins->getPlugin('Http');
$plugins->getPlugin('Temperature');
if (empty($this->config['weather.partner_id'])
|| empty($this->config['weather.license_key'])) {
@ -55,30 +57,6 @@ class Phergie_Plugin_Weather extends Phergie_Plugin_Abstract
}
}
/**
* Converts a temperature in Celsius to Fahrenheit.
*
* @param int $temp Temperature in Celsius
*
* @return int Temperature converted to Fahrenheit
*/
public function convertCelsiusToFahrenheit($temp)
{
return round(((((int) $temp * 9) / 5) + 32));
}
/**
* Converts a temperature in Fahrenheit to Celsius.
*
* @param int $temp Temperature in Fahrenheit
*
* @return int Temperature converted to Celsius
*/
public function convertFahrenheitToCelsius($temp)
{
return round(((((int) $temp - 32) * 5) / 9));
}
/**
* Returns a weather report for a specified location.
*
@ -129,16 +107,17 @@ class Phergie_Plugin_Weather extends Phergie_Plugin_Abstract
return;
}
$temperature = $this->plugins->getPlugin('Temperature');
$xml = $response->getContent();
$weather = 'Weather for ' . (string) $xml->loc->dnam . ' - ';
switch ($xml->head->ut) {
case 'F':
$tempF = $xml->cc->tmp;
$tempC = $this->convertFahrenheitToCelsius($tempF);
$tempC = $temperature->convertFahrenheitToCelsius($tempF);
break;
case 'C':
$tempC = $xml->cc->tmp;
$tempF = $this->convertCelsiusToFahrenheit($tempC);
$tempF = $temperature->convertCelsiusToFahrenheit($tempC);
break;
default:
$this->doNotice(
@ -147,20 +126,8 @@ class Phergie_Plugin_Weather extends Phergie_Plugin_Abstract
break;
}
$r = $xml->cc->hmid;
$tempF2 = $tempF * $tempF;
$r2 = $r * $r;
$hiF = round(
-42.379 +
(2.04901523 * $tempF) +
(10.14333127 * $r) -
(.22475541 * $tempF * $r) -
(6.83783 * pow(10,-3) * $tempF2) -
(5.481717 * pow(10,-2) * $r2) +
(1.22874 * pow(10,-3) * $tempF2 * $r) +
(8.5282 * pow(10,-4) * $tempF * $r2) -
(1.99 * pow(10,-6) * $tempF2 * $r2)
);
$hiC = $this->convertFahrenheitToCelsius($hiF);
$hiF = $temperature->getHeatIndex($tempF, $r);
$hiC = $temperature->convertFahrenheitToCelsius($hiF);
$weather .= 'Temperature: ' . $tempF . 'F/' . $tempC . 'C';
$weather .= ', Humidity: ' . (string) $xml->cc->hmid . '%';
if ($hiF > $tempF || $hiC > $tempC) {

View File

@ -0,0 +1,168 @@
<?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_Youtube
* @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_Youtube
*/
/**
* Provides commands used to access several services offered by Google
* including search, translation, weather, maps, and currency and general
* value unit conversion.
*
* @category Phergie
* @package Phergie_Plugin_Youtube
* @author Phergie Development Team <team@phergie.org>
* @license http://phergie.org/license New BSD License
* @link http://pear.phergie.org/package/Phergie_Plugin_Youtube
* @uses Phergie_Plugin_Command pear.phergie.org
* @uses Phergie_Plugin_Http pear.phergie.org
*/
class Phergie_Plugin_Youtube extends Phergie_Plugin_Abstract
{
/**
* Checks for dependencies.
*
* @return void
*/
public function onLoad()
{
$plugins = $this->getPluginHandler();
$plugins->getPlugin('Command');
$plugins->getPlugin('Http');
if ($url = $plugins->getPlugin('Url')) {
$url->registerRenderer($this);
}
}
/**
* Queries the YouTube video search web service, processes the first
* result, and sends a message back to the current event source.
*
* @param string $query Search term
*
* @return object YouTube result object
*/
protected function queryYoutube($query)
{
$url = 'http://gdata.youtube.com/feeds/api/videos';
$params = array(
'max-results' => '1',
'alt' => 'json',
'q' => $query
);
$http = $this->plugins->getPlugin('Http');
$response = $http->get($url, $params);
$json = $response->getContent();
$entries = $json->feed->entry;
if (!$entries) {
$this->doNotice($this->event->getNick(), 'Query returned no results');
return;
}
$entry = reset($entries);
$nick = $this->event->getNick();
$link = $entry->link[0]->href;
$title = $entry->title->{'$t'};
$author = $entry->author[0]->name->{'$t'};
$seconds = $entry->{'media$group'}->{'yt$duration'}->seconds;
$published = $entry->published->{'$t'};
$views = $entry->{'yt$statistics'}->viewCount;
$rating = $entry->{'gd$rating'}->average;
$minutes = floor($seconds / 60);
$seconds = str_pad($seconds % 60, 2, '0', STR_PAD_LEFT);
$parsed_link = parse_url($link);
parse_str($parsed_link['query'], $parsed_query);
$link = 'http://youtu.be/' . $parsed_query['v'];
$published = date('n/j/y g:i A', strtotime($published));
$views = number_format($views, 0);
$rating = round($rating, 2);
$format = $this->getConfig('youtube.format');
if (!$format) {
$format = '%nick%:'
. ' [ %link% ]'
. ' "%title%" by %author%,'
. ' Length %minutes%:%seconds%,'
. ' Published %published%,'
. ' Views %views%,'
. ' Rating %rating%';
}
$replacements = array(
'nick' => $nick,
'link' => $link,
'title' => $title,
'author' => $author,
'minutes' => $minutes,
'seconds' => $seconds,
'published' => $published,
'views' => $views,
'rating' => $rating
);
$msg = $format;
foreach ($replacements as $from => $to) {
$msg = str_replace('%' . $from . '%', $to, $msg);
}
$this->doPrivmsg($this->event->getSource(), $msg);
}
/**
* Returns the first result of a YouTube search.
*
* @param string $query Search query
*
* @return void
*/
public function onCommandYoutube($query)
{
$this->queryYoutube($query);
}
/**
* Renders YouTube URLs.
*
* @param array $parsed parse_url() output for the URL to render
*
* @return boolean TRUE if the URL was rendered successfully, FALSE
* otherwise
*/
public function renderUrl(array $parsed)
{
switch ($parsed['host']) {
case 'youtu.be':
$v = ltrim('/', $parsed['path']);
break;
case 'youtube.com':
case 'www.youtube.com':
parse_str($parsed['query'], $parsed_query);
if (!empty($parsed_query['v'])) {
$v = $parsed_query['v'];
break;
}
default:
return false;
}
$this->queryYoutube($v);
return true;
}
}