163 lines
5.7 KiB
Perl
163 lines
5.7 KiB
Perl
package DDG::Goodie::CallingCodes;
|
|
# ABSTRACT: Matches country names to international calling codes
|
|
|
|
use DDG::Goodie;
|
|
use Locale::Country qw/country2code code2country/;
|
|
use Telephony::CountryDialingCodes;
|
|
|
|
zci answer_type => "calling_codes";
|
|
zci is_cached => 1;
|
|
|
|
name "CallingCodes";
|
|
description "Matches country names to international calling codes";
|
|
source "https://en.wikipedia.org/wiki/List_of_country_calling_codes#Alphabetical_listing_by_country_or_region";
|
|
code_url "https://github.com/duckduckgo/zeroclickinfo-spice/blob/master/lib/DDG/Goodie/CallingCodes.pm";
|
|
category "geography";
|
|
topics "travel", "geography";
|
|
|
|
primary_example_queries "calling code 55", "dialing code brazil";
|
|
secondary_example_queries "dialing code +55", "country calling code 55";
|
|
|
|
attribution github => ["kablamo", "Eric Johnson"],
|
|
web => ["http://kablamo.org", "Eric Johnson"];
|
|
|
|
my @codewords = qw(code codes);
|
|
my @descriptors = ('calling', 'dialing', 'dial-in', 'dial in');
|
|
my @extras = qw(international country);
|
|
|
|
my @triggers;
|
|
foreach my $cw (@codewords) {
|
|
foreach my $desc (@descriptors) {
|
|
push @triggers, $desc . ' ' . $cw;
|
|
foreach my $extra (@extras) {
|
|
push @triggers, join(' ', $extra, $desc, $cw);
|
|
}
|
|
}
|
|
}
|
|
|
|
triggers any => @triggers;
|
|
|
|
Locale::Country::rename_country('ae' => 'the United Arab Emirates');
|
|
Locale::Country::rename_country('do' => 'the Dominican Republic');
|
|
Locale::Country::rename_country('gb' => 'the United Kingdom');
|
|
Locale::Country::rename_country('kr' => "the Republic of Korea"); # South Korea
|
|
Locale::Country::rename_country('kp' => "the Democratic People's Republic of Korea"); # North Korea
|
|
Locale::Country::rename_country('ky' => 'the Cayman Islands');
|
|
Locale::Country::rename_country('mp' => 'the Northern Mariana Islands');
|
|
Locale::Country::rename_country('nl' => 'the Netherlands');
|
|
Locale::Country::rename_country('ph' => 'the Philippines');
|
|
Locale::Country::rename_country('ru' => 'the Russian Federation');
|
|
Locale::Country::rename_country('tw' => 'Taiwan');
|
|
Locale::Country::rename_country('us' => 'the United States');
|
|
Locale::Country::rename_country('va' => 'the Holy See (Vatican City State)');
|
|
Locale::Country::rename_country('vg' => 'the British Virgin Islands');
|
|
Locale::Country::rename_country('vi' => 'the US Virgin Islands');
|
|
|
|
# These are the only 2 countries which officially have 'The' in their name
|
|
# Source: http://www.bbc.co.uk/news/magazine-18233844
|
|
Locale::Country::rename_country('gm' => 'The Gambia');
|
|
Locale::Country::rename_country('bs' => 'The Bahamas');
|
|
|
|
Locale::Country::add_country_alias('Antigua and Barbuda' => 'Antigua');
|
|
Locale::Country::add_country_alias('Antigua and Barbuda' => 'Barbuda');
|
|
Locale::Country::add_country_alias('Russian Federation' => 'Russia');
|
|
Locale::Country::add_country_alias('Trinidad and Tobago' => 'Tobago');
|
|
Locale::Country::add_country_alias('Trinidad and Tobago' => 'Trinidad');
|
|
Locale::Country::add_country_alias('Vatican City' => 'Vatican');
|
|
Locale::Country::add_country_alias('Virgin Islands, U.S.' => 'US Virgin Islands');
|
|
|
|
# Source: http://www.bbc.co.uk/news/magazine-18233844
|
|
Locale::Country::add_country_alias('United States' => 'America');
|
|
|
|
|
|
# Easter eggs
|
|
Locale::Country::add_country_alias('Russian Federation' => 'Kremlin');
|
|
Locale::Country::add_country_alias('United States' => 'murica');
|
|
Locale::Country::add_country_alias('Canada' => 'Canadia');
|
|
Locale::Country::add_country_alias('Australia' => 'down under');
|
|
|
|
handle remainder => sub {
|
|
my $query = shift;
|
|
|
|
my ($dialing_code, @countries);
|
|
|
|
if ($query =~ /^\+?(\d+)/) {
|
|
# $query looks like a phone number. eg +65
|
|
($dialing_code, @countries) = number_to_country($1);
|
|
}
|
|
elsif ($query =~ /^\w+/) {
|
|
# $query looks like a country name or country code. eg Brazil or Br
|
|
($dialing_code, @countries) = country_to_calling_code($query);
|
|
}
|
|
|
|
return unless $dialing_code && @countries;
|
|
|
|
my $answer = "+" . $dialing_code;
|
|
$answer .= " is the international calling code for ";
|
|
$answer .= list2string(@countries);
|
|
$answer .= ".";
|
|
|
|
return $answer;
|
|
};
|
|
|
|
# Convert a list of country names to a single human readable English string.
|
|
sub list2string {
|
|
my @countries = @_;
|
|
my $string;
|
|
|
|
$_ =~ s/^The /the / for @countries;
|
|
|
|
if (scalar @countries == 1) {
|
|
$string = $countries[0];
|
|
}
|
|
elsif (scalar @countries == 2) {
|
|
$string = $countries[0] . " and " . $countries[1];
|
|
}
|
|
else {
|
|
my $last = pop @countries;
|
|
$string = join ', ', @countries;
|
|
$string .= ", and " . $last;
|
|
}
|
|
|
|
return $string;
|
|
}
|
|
|
|
# Deduce the country from a number.
|
|
sub number_to_country {
|
|
my $number = shift;
|
|
|
|
my $telephony = Telephony::CountryDialingCodes->new;
|
|
my @country_codes = $telephony->country_codes($number);
|
|
my $dialing_code = $telephony->extract_dialing_code($number);
|
|
my @countries = map { code2country($_) } @country_codes;
|
|
|
|
return ($dialing_code, @countries);
|
|
}
|
|
|
|
# Deduce the calling code from a country name or country code.
|
|
sub country_to_calling_code {
|
|
my $country = shift;
|
|
|
|
# clean up
|
|
$country =~ s/^to\s+//;
|
|
$country =~ s/^for\s+//;
|
|
$country =~ s/^in\s+//;
|
|
$country =~ s/^the\s+//;
|
|
$country =~ s/\s+\+?\d+$//; # remove trailing phone code. for queries
|
|
# like 'calling code for brazil +55'
|
|
|
|
my $country_code = country2code($country);
|
|
|
|
# if we didn't find a country code, maybe $country is a country_code
|
|
$country_code = $country unless $country_code;
|
|
|
|
$country = code2country($country_code);
|
|
|
|
my $telephony = Telephony::CountryDialingCodes->new;
|
|
my $dialing_code = $telephony->dialing_code($country_code);
|
|
|
|
return ($dialing_code, $country);
|
|
}
|
|
|
|
1;
|