9 * This source file is subject to the new BSD license that is bundled
10 * with this package in the file LICENSE.
11 * It is also available through the world-wide-web at this URL:
12 * http://phergie.org/license
15 * @package Phergie_Plugin_Google
16 * @author Phergie Development Team <team@phergie.org>
17 * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
18 * @license http://phergie.org/license New BSD License
19 * @link http://pear.phergie.org/package/Phergie_Plugin_Google
23 * Provides commands used to access several services offered by Google
24 * including search, translation, weather, maps, and currency and general
25 * value unit conversion.
28 * @package Phergie_Plugin_Google
29 * @author Phergie Development Team <team@phergie.org>
30 * @license http://phergie.org/license New BSD License
31 * @link http://pear.phergie.org/package/Phergie_Plugin_Google
32 * @uses Phergie_Plugin_Command pear.phergie.org
33 * @uses Phergie_Plugin_Http pear.phergie.org
34 * @uses Phergie_Plugin_Temperature pear.phergie.org
36 * @pluginDesc Provide access to some Google services
38 class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
44 * @var Phergie_Plugin_Http
49 * Language for Google Services
54 * Checks for dependencies.
58 public function onLoad()
60 $plugins = $this->getPluginHandler();
61 $plugins->getPlugin('Command');
62 $this->http = $plugins->getPlugin('Http');
63 $plugins->getPlugin('Help')->register($this);
64 $plugins->getPlugin('Weather');
66 $this->lang = $this->getConfig('google.lang', 'en');
70 * Returns the first result of a Google search.
72 * @param string $query Search term
75 * @todo Implement use of URL shortening here
77 * @pluginCmd [query] do a search on google
79 public function onCommandG($query)
81 $url = 'http://ajax.googleapis.com/ajax/services/search/web';
86 $response = $this->http->get($url, $params);
87 $json = $response->getContent()->responseData;
88 $event = $this->getEvent();
89 $source = $event->getSource();
90 $nick = $event->getNick();
91 if ($json->cursor->estimatedResultCount > 0) {
95 . $json->results[0]->titleNoFormatting
97 . $json->results[0]->url
99 . $json->cursor->moreResultsUrl;
100 $this->doPrivmsg($source, $msg);
102 $msg = $nick . ': No results for this query.';
103 $this->doPrivmsg($source, $msg);
108 * Performs a Google Count search for the given term.
110 * @param string $query Search term
114 * @pluginCmd [query] Do a search on Google and count the results
116 public function onCommandGc($query)
118 $url = 'http://ajax.googleapis.com/ajax/services/search/web';
123 $response = $this->http->get($url, $params);
124 $json = $response->getContent()->responseData->cursor;
125 $count = $json->estimatedResultCount;
126 $event = $this->getEvent();
127 $source = $event->getSource();
128 $nick = $event->getNick();
132 number_format($count, 0) .
133 ' estimated results for ' . $query;
134 $this->doPrivmsg($source, $msg);
136 $this->doPrivmsg($source, $nick . ': No results for this query.');
141 * Performs a Google Translate search for the given term.
143 * @param string $from Language of the search term
144 * @param string $to Language to which the search term should be
146 * @param string $query Term to translate
150 * @pluginCmd [from language] [to language] [text to translate] Do a translation on Google
152 public function onCommandGt($from, $to, $query)
154 $url = 'http://ajax.googleapis.com/ajax/services/language/translate';
158 'langpair' => $from . '|' . $to
160 $response = $this->http->get($url, $params);
161 $json = $response->getContent();
162 $event = $this->getEvent();
163 $source = $event->getSource();
164 $nick = $event->getNick();
165 if (empty($json->responseData->translatedText)) {
166 $this->doPrivmsg($source, $nick . ': ' . $json->responseDetails);
170 $nick . ': ' . $json->responseData->translatedText
176 * Performs a Google Weather search for the given term.
178 * @param string $location Location to search for
179 * @param int $offset Optional day offset from the current date
180 * between 0 and 3 to get the forecast
184 * @pluginCmd [location] Show the weather for the specified location
186 public function onCommandGw($location, $offset = null)
188 $url = 'http://www.google.com/ig/api';
190 'weather' => $location,
194 $response = $this->http->get($url, $params);
195 $xml = $response->getContent()->weather;
197 $event = $this->getEvent();
198 $source = $event->getSource();
200 if ($event->isInChannel()) {
201 $msg .= $event->getNick() . ': ';
204 if (isset($xml->problem_cause)) {
205 $msg .= $xml->problem_cause->attributes()->data[0];
206 $this->doPrivmsg($source, $msg);
210 $temperature = $this->plugins->getPlugin('Temperature');
212 $forecast = $xml->forecast_information;
213 $city = $forecast->city->attributes()->data[0];
214 $zip = $forecast->postal_code->attributes()->data[0];
216 if ($offset !== null) {
217 $offset = (int) $offset;
219 $this->doNotice($source, 'Past weather data is not available');
221 } elseif ($offset > 3) {
222 $this->doNotice($source, 'Future weather data is limited to 3 days from today');
226 $linha = $xml->forecast_conditions[$offset];
227 $low = $linha->low->attributes()->data[0];
228 $high = $linha->high->attributes()->data[0];
229 $units = $forecast->unit_system->attributes()->data[0];
230 $condition = $linha->condition->attributes()->data[0];
231 $day = $linha->day_of_week->attributes()->data[0];
233 $date = ($offset == 0) ? time() : strtotime('next ' . $day);
234 $day = ucfirst($day) . ' ' . date('n/j/y', $date);
236 if ($units == 'US') {
238 $lowC = $temperature->convertFahrenheitToCelsius($low);
240 $highC = $temperature->convertFahrenheitToCelsius($high);
243 $lowF = $temperature->convertCelsiusToFahrenheit($lowC);
245 $highF = $temperature->convertCelsiusToFahrenheit($high);
248 $msg .= 'Forecast for ' . $city . ' (' . $zip . ')'
249 . ' on ' . $day . ' ::'
250 . ' Low: ' . $lowF . 'F/' . $lowC . 'C,'
251 . ' High: ' . $highF . 'F/' . $highC . 'C,'
252 . ' Conditions: ' . $condition;
254 $conditions = $xml->current_conditions;
255 $condition = $conditions->condition->attributes()->data[0];
256 $tempF = $conditions->temp_f->attributes()->data[0];
257 $tempC = $conditions->temp_c->attributes()->data[0];
258 $humidity = $conditions->humidity->attributes()->data[0];
259 $wind = $conditions->wind_condition->attributes()->data[0];
260 $time = $forecast->current_date_time->attributes()->data[0];
261 $time = date('n/j/y g:i A', strtotime($time)) . ' +0000';
263 $hiF = $temperature->getHeatIndex($tempF, $humidity);
264 $hiC = $temperature->convertFahrenheitToCelsius($hiF);
266 $msg .= 'Weather for ' . $city . ' (' . $zip . ') -'
267 . ' Temperature: ' . $tempF . 'F/' . $tempC . 'C,'
268 . ' ' . $humidity . ','
269 . ' Heat Index: ' . $hiF . 'F/' . $hiC . 'C,'
270 . ' Conditions: ' . $condition . ','
271 . ' Updated: ' . $time;
274 $this->doPrivmsg($source, $msg);
278 * Performs a Google Maps search for the given term.
280 * @param string $location Location to search for
284 * @pluginCmd [location] Get the location from Google Maps to the location specified
286 public function onCommandGmap($location)
288 $event = $this->getEvent();
289 $source = $event->getSource();
290 $nick = $event->getNick();
292 $location = utf8_encode($location);
293 $url = 'http://maps.google.com/maps/geo';
301 'key' => $this->getConfig('google.key')
303 $response = $this->http->get($url, $params);
304 $json = $response->getContent();
306 $qtd = count($json->Placemark);
309 foreach ($json->Placemark as $places) {
310 $xy = $places->Point->coordinates;
311 $address = utf8_decode($places->address);
312 $url = 'http://maps.google.com/maps?sll=' . $xy[1] . ','
314 $msg = $nick . ' -> ' . $address . ' - ' . $url;
315 $this->doPrivmsg($source, $msg);
320 ', there are a lot of places with that query.' .
321 ' Try to be more specific!';
322 $this->doPrivmsg($source, $msg);
324 } elseif ($qtd == 1) {
325 $xy = $json->Placemark[0]->Point->coordinates;
326 $address = utf8_decode($json->Placemark[0]->address);
327 $url = 'http://maps.google.com/maps?sll=' . $xy[1] . ',' . $xy[0]
329 $msg = $nick . ' -> ' . $address . ' - ' . $url;
330 $this->doPrivmsg($source, $msg);
332 $this->doPrivmsg($source, $nick . ', I found nothing.');
335 $this->doPrivmsg($source, $nick . ', we have a problem.');
340 * Perform a Google Convert query to convert a value from one metric to
343 * @param string $value Value to convert
344 * @param string $from Source metric
345 * @param string $to Destination metric
349 * @pluginCmd [value] [currency from] [currency to] Converts a monetary value from one currency to another
351 public function onCommandGconvert($value, $from, $to)
353 $url = 'http://www.google.com/finance/converter';
359 $response = $this->http->get($url, $params);
360 $contents = $response->getContent();
361 $event = $this->getEvent();
362 $source = $event->getSource();
363 $nick = $event->getNick();
366 '#<span class=bld>.*? ' . $to . '</span>#im',
371 $this->doPrivmsg($source, $nick . ', I can\'t do that.');
373 $str = str_replace('<span class=bld>', '', $matches[0]);
374 $str = str_replace($to . '</span>', '', $str);
376 = number_format($value, 2, ',', '.') . ' ' . $from .
377 ' => ' . number_format($str, 2, ',', '.') . ' ' . $to;
378 $this->doPrivmsg($source, $text);
381 $this->doPrivmsg($source, $nick . ', we had a problem.');
386 * Performs a Google search to convert a value from one unit to another.
388 * @param string $query Query of the form "[quantity] [unit] to [unit2]"
392 * @pluginCmd [quantity] [unit] to [unit2] Convert a value from one
395 public function onCommandConvert($query)
397 $url = 'http://www.google.com/search?q=' . urlencode($query);
398 $response = $this->http->get($url);
399 $contents = $response->getContent();
400 $event = $this->getEvent();
401 $source = $event->getSource();
402 $nick = $event->getNick();
404 if ($response->isError()) {
405 $code = $response->getCode();
406 $message = $response->getMessage();
407 $this->doNotice($nick, 'ERROR: ' . $code . ' ' . $message);
411 $start = strpos($contents, '<h3 class=r>');
412 if ($start !== false) {
413 $end = strpos($contents, '</b>', $start);
414 $text = strip_tags(substr($contents, $start, $end - $start));
416 array(chr(195), chr(151), chr(160)),
423 $this->doPrivmsg($source, $nick . ': ' . $text);
425 $this->doNotice($nick, 'Sorry I couldn\'t find an answer.');
431 * Returns the first definition of a Google Dictionary search.
433 * @param string $query Word to get the definition
436 * @todo Implement use of URL shortening here
438 * @pluginCmd [query] do a search of a definition on Google Dictionary
440 public function onCommandDefine($query)
442 $query = urlencode($query);
443 $url = 'http://www.google.com/dictionary/json?callback=result'.
444 '&q='.$query.'&sl='.$this->lang.'&tl='.$this->lang.
446 $json = file_get_contents($url);
448 //Remove some garbage from the json
449 $json = str_replace(array("result(", ",200,null)"), "", $json);
451 //Awesome workaround to remove a lot of slashes from json
452 $json = str_replace('"', '¿?¿', $json);
453 $json = strip_tags(stripcslashes($json));
454 $json = str_replace('"', "'", $json);
455 $json = str_replace('¿?¿', '"', $json);
457 $json = json_decode($json);
459 $event = $this->getEvent();
460 $source = $event->getSource();
461 $nick = $event->getNick();
462 if (!empty($json->webDefinitions)){
463 $results = count($json->webDefinitions[0]->entries);
464 $more = $results > 1 ? ($results-1).' ' : NULL;
465 $lang_code = substr($this->lang, 0, 2);
468 $json->webDefinitions[0]->entries[0]->terms[0]->text .
469 ' - You can find more '.$more.'results at '.
470 'http://www.google.com/dictionary?aq=f&langpair='.
471 $lang_code.'%7C'.$lang_code.'&q='.$query.'&hl='.$lang_code;
472 $this->doPrivmsg($source, $msg);
474 if ($this->lang != 'en'){
477 $this->onCommandDefine($query);
480 $msg = $nick . ': No results for this query.';
481 $this->doPrivmsg($source, $msg);