]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Irc/extlib/phergie/Phergie/Plugin/Google.php
Merged in Phergie changes
[quix0rs-gnu-social.git] / plugins / Irc / extlib / phergie / Phergie / Plugin / Google.php
1 <?php
2 /**
3  * Phergie
4  *
5  * PHP version 5
6  *
7  * LICENSE
8  *
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
13  *
14  * @category  Phergie
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
20  */
21
22 /**
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.
26  *
27  * @category Phergie
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
35  */
36 class Phergie_Plugin_Google extends Phergie_Plugin_Abstract
37 {
38     /**
39      * Checks for dependencies.
40      *
41      * @return void
42      */
43     public function onLoad()
44     {
45         $plugins = $this->getPluginHandler();
46         $plugins->getPlugin('Command');
47         $plugins->getPlugin('Http');
48         $plugins->getPlugin('Weather');
49     }
50
51     /**
52      * Returns the first result of a Google search.
53      *
54      * @param string $query Search term
55      *
56      * @return void
57      * @todo Implement use of URL shortening here
58      */
59     public function onCommandG($query)
60     {
61         $url = 'http://ajax.googleapis.com/ajax/services/search/web';
62         $params = array(
63             'v' => '1.0',
64             'q' => $query
65         );
66         $response = $this->plugins->http->get($url, $params);
67         $json = $response->getContent()->responseData;
68         $event = $this->getEvent();
69         $source = $event->getSource();
70         $nick = $event->getNick();
71         if ($json->cursor->estimatedResultCount > 0) {
72             $msg
73                 = $nick
74                 . ': [ '
75                 . $json->results[0]->titleNoFormatting
76                 . ' ] - '
77                 . $json->results[0]->url
78                 . ' - More results: '
79                 . $json->cursor->moreResultsUrl;
80             $this->doPrivmsg($source, $msg);
81         } else {
82             $msg = $nick . ': No results for this query.';
83             $this->doPrivmsg($source, $msg);
84         }
85     }
86
87     /**
88      * Performs a Google Count search for the given term.
89      *
90      * @param string $query Search term
91      *
92      * @return void
93      */
94     public function onCommandGc($query)
95     {
96         $url = 'http://ajax.googleapis.com/ajax/services/search/web';
97         $params = array(
98             'v' => '1.0',
99             'q' => $query
100         );
101         $response = $this->plugins->http->get($url, $params);
102         $json = $response->getContent()->responseData->cursor;
103         $count = $json->estimatedResultCount;
104         $event = $this->getEvent();
105         $source = $event->getSource();
106         $nick = $event->getNick();
107         if ($count) {
108             $msg
109                 = $nick . ': ' .
110                 number_format($count, 0) .
111                 ' estimated results for ' . $query;
112             $this->doPrivmsg($source, $msg);
113         } else {
114             $this->doPrivmsg($source, $nick . ': No results for this query.');
115         }
116     }
117
118     /**
119      * Performs a Google Translate search for the given term.
120      *
121      * @param string $from  Language of the search term
122      * @param string $to    Language to which the search term should be
123      *        translated
124      * @param string $query Term to translate
125      *
126      * @return void
127      */
128     public function onCommandGt($from, $to, $query)
129     {
130         $url = 'http://ajax.googleapis.com/ajax/services/language/translate';
131         $params = array(
132             'v' => '1.0',
133             'q' => $query,
134             'langpair' => $from . '|' . $to
135         );
136         $response = $this->plugins->http->get($url, $params);
137         $json = $response->getContent();
138         $event = $this->getEvent();
139         $source = $event->getSource();
140         $nick = $event->getNick();
141         if (empty($json->responseData->translatedText)) {
142             $this->doPrivmsg($source, $nick . ': ' . $json->responseDetails);
143         } else {
144             $this->doPrivmsg(
145                 $source,
146                 $nick . ': ' . $json->responseData->translatedText
147             );
148         }
149     }
150
151     /**
152      * Performs a Google Weather search for the given term.
153      *
154      * @param string $location Location to search for
155      * @param int    $offset   Optional day offset from the current date
156      *        between 0 and 3 to get the forecast
157      *
158      * @return void
159      */
160     public function onCommandGw($location, $offset = null)
161     {
162         $url = 'http://www.google.com/ig/api';
163         $params = array(
164             'weather' => $location,
165             'hl' => $this->getConfig('google.lang', 'en'),
166             'oe' => 'UTF-8'
167         );
168         $response = $this->plugins->http->get($url, $params);
169         $xml = $response->getContent()->weather;
170
171         $event = $this->getEvent();
172         $source = $event->getSource();
173         $msg = '';
174         if ($event->isInChannel()) {
175             $msg .= $event->getNick() . ': ';
176         }
177
178         if (isset($xml->problem_cause)) {
179             $msg .= $xml->problem_cause->attributes()->data[0];
180             $this->doPrivmsg($source, $msg);
181             return;
182         }
183
184         $temperature = $this->plugins->getPlugin('Temperature');
185
186         $forecast = $xml->forecast_information;
187         $city = $forecast->city->attributes()->data[0];
188         $zip = $forecast->postal_code->attributes()->data[0];
189
190         if ($offset !== null) {
191             $offset = (int) $offset;
192             if ($offset < 0) {
193                 $this->doNotice($source, 'Past weather data is not available');
194                 return;
195             } elseif ($offset > 3) {
196                 $this->doNotice($source, 'Future weather data is limited to 3 days from today');
197                 return;
198             }
199
200             $linha = $xml->forecast_conditions[$offset];
201             $low = $linha->low->attributes()->data[0];
202             $high = $linha->high->attributes()->data[0];
203             $units = $forecast->unit_system->attributes()->data[0];
204             $condition = $linha->condition->attributes()->data[0];
205             $day = $linha->day_of_week->attributes()->data[0];
206
207             $date = ($offset == 0) ? time() : strtotime('next ' . $day);
208             $day = ucfirst($day) . ' ' . date('n/j/y', $date);
209
210             if ($units == 'US') {
211                 $lowF = $low;
212                 $lowC = $temperature->convertFahrenheitToCelsius($low);
213                 $highF = $high;
214                 $highC = $temperature->convertFahrenheitToCelsius($high);
215             } else {
216                 $lowC = $low;
217                 $lowF = $temperature->convertCelsiusToFahrenheit($lowC);
218                 $highC = $high;
219                 $highF = $temperature->convertCelsiusToFahrenheit($high);
220             }
221
222             $msg .= 'Forecast for ' . $city . ' (' . $zip . ')'
223                 . ' on ' . $day . ' ::'
224                 . ' Low: ' . $lowF . 'F/' . $lowC . 'C,'
225                 . ' High: ' . $highF . 'F/' . $highC . 'C,'
226                 . ' Conditions: ' . $condition;
227         } else {
228             $conditions = $xml->current_conditions;
229             $condition = $conditions->condition->attributes()->data[0];
230             $tempF = $conditions->temp_f->attributes()->data[0];
231             $tempC = $conditions->temp_c->attributes()->data[0];
232             $humidity = $conditions->humidity->attributes()->data[0];
233             $wind = $conditions->wind_condition->attributes()->data[0];
234             $time = $forecast->current_date_time->attributes()->data[0];
235             $time = date('n/j/y g:i A', strtotime($time)) . ' +0000';
236
237             $hiF = $temperature->getHeatIndex($tempF, $humidity);
238             $hiC = $temperature->convertFahrenheitToCelsius($hiF);
239
240             $msg .= 'Weather for ' . $city . ' (' . $zip . ') -'
241                 . ' Temperature: ' . $tempF . 'F/' . $tempC . 'C,'
242                 . ' ' . $humidity . ','
243                 . ' Heat Index: ' . $hiF . 'F/' . $hiC . 'C,'
244                 . ' Conditions: ' . $condition . ','
245                 . ' Updated: ' . $time;
246         }
247
248         $this->doPrivmsg($source, $msg);
249     }
250
251     /**
252      * Performs a Google Maps search for the given term.
253      *
254      * @param string $location Location to search for
255      *
256      * @return void
257      */
258     public function onCommandGmap($location)
259     {
260         $event = $this->getEvent();
261         $source = $event->getSource();
262         $nick = $event->getNick();
263
264         $location = utf8_encode($location);
265         $url = 'http://maps.google.com/maps/geo';
266         $params = array(
267             'q' => $location,
268             'output' => 'json',
269             'gl' => $this->getConfig('google.lang', 'en'),
270             'sensor' => 'false',
271             'oe' => 'utf8',
272             'mrt' => 'all',
273             'key' => $this->getConfig('google.key')
274         );
275         $response = $this->plugins->http->get($url, $params);
276         $json =  $response->getContent();
277         if (!empty($json)) {
278             $qtd = count($json->Placemark);
279             if ($qtd > 1) {
280                 if ($qtd <= 3) {
281                     foreach ($json->Placemark as $places) {
282                         $xy = $places->Point->coordinates;
283                         $address = utf8_decode($places->address);
284                         $url = 'http://maps.google.com/maps?sll=' . $xy[1] . ','
285                             . $xy[0] . '&z=15';
286                         $msg = $nick . ' -> ' . $address . ' - ' . $url;
287                         $this->doPrivmsg($source, $msg);
288                     }
289                 } else {
290                     $msg
291                         = $nick .
292                         ', there are a lot of places with that query.' .
293                         ' Try to be more specific!';
294                     $this->doPrivmsg($source, $msg);
295                 }
296             } elseif ($qtd == 1) {
297                 $xy = $json->Placemark[0]->Point->coordinates;
298                 $address = utf8_decode($json->Placemark[0]->address);
299                 $url = 'http://maps.google.com/maps?sll=' . $xy[1] . ',' . $xy[0]
300                     . '&z=15';
301                 $msg = $nick . ' -> ' . $address . ' - ' . $url;
302                 $this->doPrivmsg($source, $msg);
303             } else {
304                 $this->doPrivmsg($source, $nick . ', I found nothing.');
305             }
306         } else {
307             $this->doPrivmsg($source, $nick . ', we have a problem.');
308         }
309     }
310
311     /**
312      * Perform a Google Convert query to convert a value from one metric to
313      * another.
314      *
315      * @param string $value Value to convert
316      * @param string $from  Source metric
317      * @param string $to    Destination metric
318      *
319      * @return void
320      */
321     public function onCommandGconvert($value, $from, $to)
322     {
323         $url = 'http://www.google.com/finance/converter';
324         $params = array(
325             'a' => $value,
326             'from' => $from,
327             'to' => $to
328         );
329         $response = $this->plugins->http->get($url, $params);
330         $contents = $response->getContent();
331         $event = $this->getEvent();
332         $source = $event->getSource();
333         $nick = $event->getNick();
334         if ($contents) {
335             libxml_use_internal_errors(true);
336             $doc = new DOMDocument;
337             $doc->loadHTML($contents);
338             libxml_clear_errors();
339             $xpath = new DOMXPath($doc);
340             $result = $xpath->query('//div[@id="currency_converter_result"]');
341             $div = $result->item(0);
342             $text = rtrim($div->textContent);
343             $this->doPrivmsg($source, $text);
344         }
345     }
346
347     /**
348      * Performs a Google search to convert a value from one unit to another.
349      *
350      * @param string $query Query of the form "[quantity] [unit] to [unit2]"
351      *
352      * @return void
353      *
354      * @pluginCmd [quantity] [unit] to [unit2] Convert a value from one
355      *            metric to another
356      */
357     public function onCommandConvert($query)
358     {
359         $url = 'http://www.google.com/search?q=' . urlencode($query);
360         $response = $this->plugins->http->get($url);
361         $contents = $response->getContent();
362         $event = $this->getEvent();
363         $source = $event->getSource();
364         $nick = $event->getNick();
365
366         if ($response->isError()) {
367             $code = $response->getCode();
368             $message = $response->getMessage();
369             $this->doNotice($nick, 'ERROR: ' . $code . ' ' . $message);
370             return;
371         }
372
373         $start = strpos($contents, '<h3 class=r>');
374         if ($start !== false) {
375             $end = strpos($contents, '</b>', $start);
376             $text = strip_tags(substr($contents, $start, $end - $start));
377             $text = str_replace(
378                 array(chr(195), chr(151), chr(160)),
379                 array('x', '', ' '),
380                 $text
381             );
382         }
383
384         if (isset($text)) {
385             $this->doPrivmsg($source, $nick . ': ' . $text);
386         } else {
387             $this->doNotice($nick, 'Sorry I couldn\'t find an answer.');
388         }
389     }
390
391
392     /**
393      * Returns the first definition of a Google Dictionary search.
394      *
395      * @param string $query Word to get the definition
396      *
397      * @return void
398      * @todo Implement use of URL shortening here
399      */
400     public function onCommandDefine($query)
401     {
402         $lang = $this->getConfig('google.lang', 'en');
403         $url = 'http://www.google.com/dictionary/json';
404         $params = array(
405             'callback' => 'result',
406             'q' => $query,
407             'sl' => $lang,
408             'tl' => $lang,
409             'restrict' => 'pr,de'
410         );
411         $response = $this->plugins->http->get($url, $params);
412         $json = $response->getContent();
413
414         // Remove some garbage from the JSON and decode it
415         $json = str_replace(array('result(', ',200,null)'), '', $json);
416         $json = str_replace('"', '¿?¿', $json);
417         $json = strip_tags(stripcslashes($json));
418         $json = str_replace('"', "'", $json);
419         $json = str_replace('¿?¿', '"', $json);
420         $json = json_decode($json);
421
422         $event = $this->getEvent();
423         $source = $event->getSource();
424         $nick = $event->getNick();
425         if (!empty($json->webDefinitions)) {
426             $results = 0;
427             foreach ($json->primaries[0]->entries as $entry) {
428                 if ($entry->type == 'meaning') {
429                     $results++;
430                     if (empty($text)) {
431                         foreach ($entry->terms as $term) {
432                             if ($term->type == 'text') {
433                                 $text = trim($term->text);
434                             }
435                         }
436                     }
437                 }
438             }
439             $more = $results > 1 ? ($results - 1) . ' ' : '';
440             $lang_code = substr($lang, 0, 2);
441             $msg = $nick . ': ' . $text
442                  . ' - You can find ' . $more . 'more results at '
443                  . 'http://www.google.com/dictionary'
444                  . '?aq=f'
445                  . '&langpair=' . $lang_code . '%7C' . $lang_code
446                  . '&q=' . $query
447                  . '&hl=' . $lang_code;
448             $this->doPrivmsg($source, $msg);
449         } else {
450             if ($lang != 'en'){
451                $lang = 'en';
452                $this->onCommandDefine($query);
453             } else {
454                $msg = $nick . ': No results for this query.';
455                $this->doPrivmsg($source, $msg);
456             }
457         }
458     }
459 }