forked from GNUsocial/gnu-social
460 lines
16 KiB
PHP
460 lines
16 KiB
PHP
<?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_Google
|
|
* @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_Google
|
|
*/
|
|
|
|
/**
|
|
* 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_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
|
|
*/
|
|
class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
|
|
{
|
|
/**
|
|
* Checks for dependencies.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function onLoad()
|
|
{
|
|
$plugins = $this->getPluginHandler();
|
|
$plugins->getPlugin('Command');
|
|
$plugins->getPlugin('Http');
|
|
$plugins->getPlugin('Weather');
|
|
}
|
|
|
|
/**
|
|
* Returns the first result of a Google search.
|
|
*
|
|
* @param string $query Search term
|
|
*
|
|
* @return void
|
|
* @todo Implement use of URL shortening here
|
|
*/
|
|
public function onCommandG($query)
|
|
{
|
|
$url = 'http://ajax.googleapis.com/ajax/services/search/web';
|
|
$params = array(
|
|
'v' => '1.0',
|
|
'q' => $query
|
|
);
|
|
$response = $this->plugins->http->get($url, $params);
|
|
$json = $response->getContent()->responseData;
|
|
$event = $this->getEvent();
|
|
$source = $event->getSource();
|
|
$nick = $event->getNick();
|
|
if ($json->cursor->estimatedResultCount > 0) {
|
|
$msg
|
|
= $nick
|
|
. ': [ '
|
|
. $json->results[0]->titleNoFormatting
|
|
. ' ] - '
|
|
. $json->results[0]->url
|
|
. ' - More results: '
|
|
. $json->cursor->moreResultsUrl;
|
|
$this->doPrivmsg($source, $msg);
|
|
} else {
|
|
$msg = $nick . ': No results for this query.';
|
|
$this->doPrivmsg($source, $msg);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Performs a Google Count search for the given term.
|
|
*
|
|
* @param string $query Search term
|
|
*
|
|
* @return void
|
|
*/
|
|
public function onCommandGc($query)
|
|
{
|
|
$url = 'http://ajax.googleapis.com/ajax/services/search/web';
|
|
$params = array(
|
|
'v' => '1.0',
|
|
'q' => $query
|
|
);
|
|
$response = $this->plugins->http->get($url, $params);
|
|
$json = $response->getContent()->responseData->cursor;
|
|
$count = $json->estimatedResultCount;
|
|
$event = $this->getEvent();
|
|
$source = $event->getSource();
|
|
$nick = $event->getNick();
|
|
if ($count) {
|
|
$msg
|
|
= $nick . ': ' .
|
|
number_format($count, 0) .
|
|
' estimated results for ' . $query;
|
|
$this->doPrivmsg($source, $msg);
|
|
} else {
|
|
$this->doPrivmsg($source, $nick . ': No results for this query.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* translated
|
|
* @param string $query Term to translate
|
|
*
|
|
* @return void
|
|
*/
|
|
public function onCommandGt($from, $to, $query)
|
|
{
|
|
$url = 'http://ajax.googleapis.com/ajax/services/language/translate';
|
|
$params = array(
|
|
'v' => '1.0',
|
|
'q' => $query,
|
|
'langpair' => $from . '|' . $to
|
|
);
|
|
$response = $this->plugins->http->get($url, $params);
|
|
$json = $response->getContent();
|
|
$event = $this->getEvent();
|
|
$source = $event->getSource();
|
|
$nick = $event->getNick();
|
|
if (empty($json->responseData->translatedText)) {
|
|
$this->doPrivmsg($source, $nick . ': ' . $json->responseDetails);
|
|
} else {
|
|
$this->doPrivmsg(
|
|
$source,
|
|
$nick . ': ' . $json->responseData->translatedText
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public function onCommandGw($location, $offset = null)
|
|
{
|
|
$url = 'http://www.google.com/ig/api';
|
|
$params = array(
|
|
'weather' => $location,
|
|
'hl' => $this->getConfig('google.lang', 'en'),
|
|
'oe' => 'UTF-8'
|
|
);
|
|
$response = $this->plugins->http->get($url, $params);
|
|
$xml = $response->getContent()->weather;
|
|
|
|
$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);
|
|
}
|
|
|
|
/**
|
|
* Performs a Google Maps search for the given term.
|
|
*
|
|
* @param string $location Location to search for
|
|
*
|
|
* @return void
|
|
*/
|
|
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' => $this->getConfig('google.lang', 'en'),
|
|
'sensor' => 'false',
|
|
'oe' => 'utf8',
|
|
'mrt' => 'all',
|
|
'key' => $this->getConfig('google.key')
|
|
);
|
|
$response = $this->plugins->http->get($url, $params);
|
|
$json = $response->getContent();
|
|
if (!empty($json)) {
|
|
$qtd = count($json->Placemark);
|
|
if ($qtd > 1) {
|
|
if ($qtd <= 3) {
|
|
foreach ($json->Placemark as $places) {
|
|
$xy = $places->Point->coordinates;
|
|
$address = utf8_decode($places->address);
|
|
$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.' .
|
|
' 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]
|
|
. '&z=15';
|
|
$msg = $nick . ' -> ' . $address . ' - ' . $url;
|
|
$this->doPrivmsg($source, $msg);
|
|
} else {
|
|
$this->doPrivmsg($source, $nick . ', I found nothing.');
|
|
}
|
|
} else {
|
|
$this->doPrivmsg($source, $nick . ', we have a problem.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Perform a Google Convert query to convert a value from one metric to
|
|
* another.
|
|
*
|
|
* @param string $value Value to convert
|
|
* @param string $from Source metric
|
|
* @param string $to Destination metric
|
|
*
|
|
* @return void
|
|
*/
|
|
public function onCommandGconvert($value, $from, $to)
|
|
{
|
|
$url = 'http://www.google.com/finance/converter';
|
|
$params = array(
|
|
'a' => $value,
|
|
'from' => $from,
|
|
'to' => $to
|
|
);
|
|
$response = $this->plugins->http->get($url, $params);
|
|
$contents = $response->getContent();
|
|
$event = $this->getEvent();
|
|
$source = $event->getSource();
|
|
$nick = $event->getNick();
|
|
if ($contents) {
|
|
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);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Performs a Google search to convert a value from one unit to another.
|
|
*
|
|
* @param string $query Query of the form "[quantity] [unit] to [unit2]"
|
|
*
|
|
* @return void
|
|
*
|
|
* @pluginCmd [quantity] [unit] to [unit2] Convert a value from one
|
|
* metric to another
|
|
*/
|
|
public function onCommandConvert($query)
|
|
{
|
|
$url = 'http://www.google.com/search?q=' . urlencode($query);
|
|
$response = $this->plugins->http->get($url);
|
|
$contents = $response->getContent();
|
|
$event = $this->getEvent();
|
|
$source = $event->getSource();
|
|
$nick = $event->getNick();
|
|
|
|
if ($response->isError()) {
|
|
$code = $response->getCode();
|
|
$message = $response->getMessage();
|
|
$this->doNotice($nick, 'ERROR: ' . $code . ' ' . $message);
|
|
return;
|
|
}
|
|
|
|
$start = strpos($contents, '<h3 class=r>');
|
|
if ($start !== false) {
|
|
$end = strpos($contents, '</b>', $start);
|
|
$text = strip_tags(substr($contents, $start, $end - $start));
|
|
$text = str_replace(
|
|
array(chr(195), chr(151), chr(160)),
|
|
array('x', '', ' '),
|
|
$text
|
|
);
|
|
}
|
|
|
|
if (isset($text)) {
|
|
$this->doPrivmsg($source, $nick . ': ' . $text);
|
|
} else {
|
|
$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
|
|
*/
|
|
public function onCommandDefine($query)
|
|
{
|
|
$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();
|
|
|
|
// 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 = 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 ($lang != 'en'){
|
|
$lang = 'en';
|
|
$this->onCommandDefine($query);
|
|
} else {
|
|
$msg = $nick . ': No results for this query.';
|
|
$this->doPrivmsg($source, $msg);
|
|
}
|
|
}
|
|
}
|
|
}
|