X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FGeonamesPlugin.php;h=589462ed9936399492436536a8c5ca248e96ca4b;hb=82f11190734c203ed6b2fd4a07cb9460f25b2183;hp=0d12c1cf7057cabac36d3071e517c67a37137570;hpb=3262930ed46936140244c5385e4b172632d2dd44;p=quix0rs-gnu-social.git diff --git a/plugins/GeonamesPlugin.php b/plugins/GeonamesPlugin.php index 0d12c1cf70..589462ed99 100644 --- a/plugins/GeonamesPlugin.php +++ b/plugins/GeonamesPlugin.php @@ -71,43 +71,38 @@ class GeonamesPlugin extends Plugin $loc = $this->getCache(array('name' => $name, 'language' => $language)); - if (!empty($loc)) { + if ($loc !== false) { $location = $loc; return false; } - $client = HTTPClient::start(); - - // XXX: break down a name by commas, narrow by each - - $result = $client->get($this->wsUrl('search', - array('maxRows' => 1, - 'q' => $name, - 'lang' => $language, - 'type' => 'json'))); - - if (!$result->isOk()) { - $this->log(LOG_WARNING, "Error code " . $result->code . - " from " . $this->host . " for $name"); + try { + $geonames = $this->getGeonames('search', + array('maxRows' => 1, + 'q' => $name, + 'lang' => $language, + 'type' => 'xml')); + } catch (Exception $e) { + $this->log(LOG_WARNING, "Error for $name: " . $e->getMessage()); return true; } - $rj = json_decode($result->getBody()); - - if (count($rj->geonames) <= 0) { - $this->log(LOG_WARNING, "No results in response from " . - $this->host . " for $name"); + if (count($geonames) == 0) { + // no results + $this->setCache(array('name' => $name, + 'language' => $language), + null); return true; } - $n = $rj->geonames[0]; + $n = $geonames[0]; $location = new Location(); - $location->lat = $n->lat; - $location->lon = $n->lng; - $location->names[$language] = $n->name; - $location->location_id = $n->geonameId; + $location->lat = $this->canonical($n->lat); + $location->lon = $this->canonical($n->lng); + $location->names[$language] = (string)$n->name; + $location->location_id = (string)$n->geonameId; $location->location_ns = self::LOCATION_NS; $this->setCache(array('name' => $name, @@ -138,59 +133,47 @@ class GeonamesPlugin extends Plugin $loc = $this->getCache(array('id' => $id)); - if (!empty($loc)) { + if ($loc !== false) { $location = $loc; return false; } - $client = HTTPClient::start(); - - $result = $client->get($this->wsUrl('hierarchyJSON', - array('geonameId' => $id, - 'lang' => $language))); - - if (!$result->isOk()) { - $this->log(LOG_WARNING, - "Error code " . $result->code . - " from " . $this->host . " for ID $id"); - return false; - } - - $rj = json_decode($result->getBody()); - - if (count($rj->geonames) <= 0) { - $this->log(LOG_WARNING, - "No results in response from " . - $this->host . " for ID $id"); + try { + $geonames = $this->getGeonames('hierarchy', + array('geonameId' => $id, + 'lang' => $language)); + } catch (Exception $e) { + $this->log(LOG_WARNING, "Error for ID $id: " . $e->getMessage()); return false; } $parts = array(); - foreach ($rj->geonames as $level) { + foreach ($geonames as $level) { if (in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { - $parts[] = $level->name; + $parts[] = (string)$level->name; } } - $last = $rj->geonames[count($rj->geonames)-1]; + $last = $geonames[count($geonames)-1]; if (!in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { - $parts[] = $last->name; + $parts[] = (string)$last->name; } $location = new Location(); - $location->location_id = $last->geonameId; + $location->location_id = (string)$last->geonameId; $location->location_ns = self::LOCATION_NS; - $location->lat = $last->lat; - $location->lon = $last->lng; + $location->lat = $this->canonical($last->lat); + $location->lon = $this->canonical($last->lng); + $location->names[$language] = implode(', ', array_reverse($parts)); - $this->setCache(array('id' => $last->geonameId), + $this->setCache(array('id' => (string)$last->geonameId), $location); - // We're responsible for this NAMESPACE; nobody else + // We're responsible for this namespace; nobody else // can resolve it return false; @@ -212,61 +195,57 @@ class GeonamesPlugin extends Plugin function onLocationFromLatLon($lat, $lon, $language, &$location) { - $lat = rtrim($lat, "0"); - $lon = rtrim($lon, "0"); + // Make sure they're canonical + + $lat = $this->canonical($lat); + $lon = $this->canonical($lon); $loc = $this->getCache(array('lat' => $lat, 'lon' => $lon)); - if (!empty($loc)) { + if ($loc !== false) { $location = $loc; return false; } - $client = HTTPClient::start(); - - $result = - $client->get($this->wsUrl('findNearbyPlaceNameJSON', - array('lat' => $lat, - 'lng' => $lon, - 'lang' => $language))); - - if (!$result->isOk()) { - $this->log(LOG_WARNING, - "Error code " . $result->code . - " from " . $this->host . " for coords $lat, $lon"); + try { + $geonames = $this->getGeonames('findNearbyPlaceName', + array('lat' => $lat, + 'lng' => $lon, + 'lang' => $language)); + } catch (Exception $e) { + $this->log(LOG_WARNING, "Error for coords $lat, $lon: " . $e->getMessage()); return true; } - $rj = json_decode($result->getBody()); - - if (count($rj->geonames) <= 0) { - $this->log(LOG_WARNING, - "No results in response from " . - $this->host . " for coords $lat, $lon"); + if (count($geonames) == 0) { + // no results + $this->setCache(array('lat' => $lat, + 'lon' => $lon), + null); return true; } - $n = $rj->geonames[0]; + $n = $geonames[0]; $parts = array(); $location = new Location(); - $parts[] = $n->name; + $parts[] = (string)$n->name; if (!empty($n->adminName1)) { - $parts[] = $n->adminName1; + $parts[] = (string)$n->adminName1; } if (!empty($n->countryName)) { - $parts[] = $n->countryName; + $parts[] = (string)$n->countryName; } - $location->location_id = $n->geonameId; + $location->location_id = (string)$n->geonameId; $location->location_ns = self::LOCATION_NS; - $location->lat = $lat; - $location->lon = $lon; + $location->lat = $this->canonical($n->lat); + $location->lon = $this->canonical($n->lng); $location->names[$language] = implode(', ', $parts); @@ -299,53 +278,49 @@ class GeonamesPlugin extends Plugin return true; } - $n = $this->getCache(array('id' => $location->location_id, + $id = $location->location_id; + + $n = $this->getCache(array('id' => $id, 'language' => $language)); - if (!empty($n)) { + if ($n !== false) { $name = $n; return false; } - $client = HTTPClient::start(); - - $result = $client->get($this->wsUrl('hierarchyJSON', - array('geonameId' => $location->location_id, - 'lang' => $language))); - - if (!$result->isOk()) { - $this->log(LOG_WARNING, - "Error code " . $result->code . - " from " . $this->host . " for ID " . $location->location_id); + try { + $geonames = $this->getGeonames('hierarchy', + array('geonameId' => $id, + 'lang' => $language)); + } catch (Exception $e) { + $this->log(LOG_WARNING, "Error for ID $id: " . $e->getMessage()); return false; } - $rj = json_decode($result->getBody()); - - if (count($rj->geonames) <= 0) { - $this->log(LOG_WARNING, - "No results " . - " from " . $this->host . " for ID " . $location->location_id); + if (count($geonames) == 0) { + $this->setCache(array('id' => $id, + 'language' => $language), + null); return false; } $parts = array(); - foreach ($rj->geonames as $level) { + foreach ($geonames as $level) { if (in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { - $parts[] = $level->name; + $parts[] = (string)$level->name; } } - $last = $rj->geonames[count($rj->geonames)-1]; + $last = $geonames[count($geonames)-1]; if (!in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { - $parts[] = $last->name; + $parts[] = (string)$last->name; } if (count($parts)) { $name = implode(', ', array_reverse($parts)); - $this->setCache(array('id' => $location->location_id, + $this->setCache(array('id' => $id, 'language' => $language), $name); } @@ -354,7 +329,7 @@ class GeonamesPlugin extends Plugin } /** - * Human-readable name for a location + * Human-readable URL for a location * * Given a location, we try to retrieve a geonames.org URL. * @@ -448,8 +423,65 @@ class GeonamesPlugin extends Plugin $params['token'] = $this->token; } - $str = http_build_query($params); + $str = http_build_query($params, null, '&'); return 'http://'.$this->host.'/'.$method.'?'.$str; } + + function getGeonames($method, $params) + { + $client = HTTPClient::start(); + + $result = $client->get($this->wsUrl($method, $params)); + + if (!$result->isOk()) { + throw new Exception("HTTP error code " . $result->code); + } + + $body = $result->getBody(); + + if (empty($body)) { + throw new Exception("Empty HTTP body in response"); + } + + // This will throw an exception if the XML is mal-formed + + $document = new SimpleXMLElement($body); + + // No children, usually no results + + $children = $document->children(); + + if (count($children) == 0) { + return array(); + } + + if (isset($document->status)) { + throw new Exception("Error #".$document->status['value']." ('".$document->status['message']."')"); + } + + // Array of elements, >0 elements + + return $document->geoname; + } + + function onPluginVersion(&$versions) + { + $versions[] = array('name' => 'Geonames', + 'version' => STATUSNET_VERSION, + 'author' => 'Evan Prodromou', + 'homepage' => 'http://status.net/wiki/Plugin:Geonames', + 'rawdescription' => + _m('Uses Geonames service to get human-readable '. + 'names for locations based on user-provided lat/long pairs.')); + return true; + } + + function canonical($coord) + { + $coord = rtrim($coord, "0"); + $coord = rtrim($coord, "."); + + return $coord; + } }