aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Somerville <matthew-github@dracos.co.uk>2019-05-21 16:28:31 +0100
committerMatthew Somerville <matthew@mysociety.org>2019-09-19 16:11:09 +0100
commitc78ddc808b6d48188d7057c35718bed7f1fc28ff (patch)
treebbbaa67296737fec1946f6f8f3c79e34f9a38728
parentcc2ca7a697e1750ef197e222a1d45c4b345e61d4 (diff)
Switch geocoders to be pluggable.
-rw-r--r--perllib/FixMyStreet/Cobrand/Default.pm3
-rw-r--r--perllib/FixMyStreet/Geocode.pm25
-rw-r--r--perllib/FixMyStreet/Geocode/Bing.pm8
-rw-r--r--perllib/FixMyStreet/Geocode/Google.pm2
-rw-r--r--perllib/FixMyStreet/Geocode/OSM.pm2
-rw-r--r--perllib/FixMyStreet/Geocode/Zurich.pm2
-rw-r--r--t/geocode/google.t4
7 files changed, 28 insertions, 18 deletions
diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm
index a6c6f34c4..829c85f5d 100644
--- a/perllib/FixMyStreet/Cobrand/Default.pm
+++ b/perllib/FixMyStreet/Cobrand/Default.pm
@@ -1192,8 +1192,7 @@ Return the default geocoder from config.
=cut
sub get_geocoder {
- my ($self, $c) = @_;
- return $c->config->{GEOCODER};
+ FixMyStreet->config('GEOCODER');
}
diff --git a/perllib/FixMyStreet/Geocode.pm b/perllib/FixMyStreet/Geocode.pm
index d552afaa5..61c968269 100644
--- a/perllib/FixMyStreet/Geocode.pm
+++ b/perllib/FixMyStreet/Geocode.pm
@@ -13,12 +13,14 @@ use JSON::MaybeXS;
use LWP::Simple qw($ua);
use Path::Tiny;
use URI::Escape;
-use FixMyStreet::Geocode::Bing;
-use FixMyStreet::Geocode::Google;
-use FixMyStreet::Geocode::OSM;
-use FixMyStreet::Geocode::Zurich;
use Utils;
+use Module::Pluggable
+ sub_name => 'geocoders',
+ search_path => __PACKAGE__,
+ require => 1,
+ except => qr/Address/;
+
# lookup STRING CONTEXT
# Given a user-inputted string, try and convert it into co-ordinates using either
# MaPit if it's a postcode, or some web API otherwise. Returns an array of
@@ -44,14 +46,17 @@ sub lookup {
sub string {
my ($s, $c) = @_;
- my $service = $c->cobrand->get_geocoder($c);
+ my $service = $c->cobrand->get_geocoder();
$service = $service->{type} if ref $service;
- $service = 'OSM' unless $service =~ /^(Bing|Google|OSM|Zurich)$/;
- $service = 'OSM' if $service eq 'Bing' && !FixMyStreet->config('BING_MAPS_API_KEY');
- $service = "FixMyStreet::Geocode::${service}::string";
- no strict 'refs';
- return &$service($s, $c);
+ $service = __PACKAGE__ . '::' . $service;
+ my %avail = map { $_ => 1 } __PACKAGE__->geocoders;
+
+ if (!$avail{$service} || ($service->can('setup') && !$service->setup)) {
+ $service = __PACKAGE__ . '::OSM';
+ }
+
+ return $service->string($s, $c);
}
# escape STRING CONTEXT
diff --git a/perllib/FixMyStreet/Geocode/Bing.pm b/perllib/FixMyStreet/Geocode/Bing.pm
index 9e425441a..ee5e15f8c 100644
--- a/perllib/FixMyStreet/Geocode/Bing.pm
+++ b/perllib/FixMyStreet/Geocode/Bing.pm
@@ -11,13 +11,19 @@ use strict;
use FixMyStreet::Geocode;
use Utils;
+sub setup {
+ my $cls = shift;
+ return 1 if FixMyStreet->config('BING_MAPS_API_KEY');
+ return 0;
+}
+
# string STRING CONTEXT
# Looks up on Bing Maps API, and caches, a user-inputted location.
# Returns array of (LAT, LON, ERROR), where ERROR is either undef, a string, or
# an array of matches if there are more than one. The information in the query
# may be used to disambiguate the location in cobranded versions of the site.
sub string {
- my ( $s, $c ) = @_;
+ my ( $cls, $s, $c ) = @_;
my $params = $c->cobrand->disambiguate_location($s);
# Allow cobrand to fixup the user input
diff --git a/perllib/FixMyStreet/Geocode/Google.pm b/perllib/FixMyStreet/Geocode/Google.pm
index ad1881541..455d9cec0 100644
--- a/perllib/FixMyStreet/Geocode/Google.pm
+++ b/perllib/FixMyStreet/Geocode/Google.pm
@@ -16,7 +16,7 @@ use URI::Escape;
# an array of matches if there are more than one. The information in the query
# may be used to disambiguate the location in cobranded versions of the site.
sub string {
- my ( $s, $c ) = @_;
+ my ( $cls, $s, $c ) = @_;
my $params = $c->cobrand->disambiguate_location($s);
# Allow cobrand to fixup the user input
diff --git a/perllib/FixMyStreet/Geocode/OSM.pm b/perllib/FixMyStreet/Geocode/OSM.pm
index 0d296f299..fb7924c23 100644
--- a/perllib/FixMyStreet/Geocode/OSM.pm
+++ b/perllib/FixMyStreet/Geocode/OSM.pm
@@ -23,7 +23,7 @@ my $nominatimbase = "http://nominatim.openstreetmap.org/";
# an array of matches if there are more than one. The information in the query
# may be used to disambiguate the location in cobranded versions of the site.
sub string {
- my ( $s, $c ) = @_;
+ my ( $cls, $s, $c ) = @_;
my $params = $c->cobrand->disambiguate_location($s);
# Allow cobrand to fixup the user input
diff --git a/perllib/FixMyStreet/Geocode/Zurich.pm b/perllib/FixMyStreet/Geocode/Zurich.pm
index c7bd9e9d9..38df431c9 100644
--- a/perllib/FixMyStreet/Geocode/Zurich.pm
+++ b/perllib/FixMyStreet/Geocode/Zurich.pm
@@ -60,7 +60,7 @@ sub setup_soap {
# versions of the site.
sub string {
- my ( $s, $c ) = @_;
+ my ( $cls, $s, $c ) = @_;
setup_soap();
diff --git a/t/geocode/google.t b/t/geocode/google.t
index ee3c15ea8..40e8caf9a 100644
--- a/t/geocode/google.t
+++ b/t/geocode/google.t
@@ -11,12 +11,12 @@ use Catalyst::Test 'FixMyStreet::App';
use t::Mock::GoogleGeocoder;
my $c = ctx_request('/');
-my $r = FixMyStreet::Geocode::Google::string("one result", $c);
+my $r = FixMyStreet::Geocode::Google->string("one result", $c);
ok $r->{latitude};
ok $r->{longitude};
$c->stash->{cobrand} = FixMyStreet::Cobrand::Tester->new;
-$r = FixMyStreet::Geocode::Google::string("two results", $c);
+$r = FixMyStreet::Geocode::Google->string("two results", $c);
is scalar @{$r->{error}}, 2;
done_testing;