diff --git a/dist.ini b/dist.ini index 8e6ff460b..df4261954 100644 --- a/dist.ini +++ b/dist.ini @@ -71,6 +71,7 @@ Telephony::CountryDialingCodes = 1.04 URI::Escape::XS = 0.12 DateTime::Calendar::Chinese = 1.00 DateTime::Event::Chinese = 1.00 +DateTime::Event::Sunrise = 0 Geo::Coordinates::DecimalDegrees = 0.09 Math::SigFigs = 1.09 Bit::Vector = 7.3 diff --git a/lib/DDG/Goodie/SunInfo.pm b/lib/DDG/Goodie/SunInfo.pm new file mode 100644 index 000000000..87b6e68c3 --- /dev/null +++ b/lib/DDG/Goodie/SunInfo.pm @@ -0,0 +1,67 @@ +package DDG::Goodie::SunInfo; +# ABSTRACT: sunrise and sunset information for the client location + +use DDG::Goodie; +with 'DDG::GoodieRole::Dates'; + +use DateTime::Event::Sunrise; +use Try::Tiny; + +zci answer_type => "sun_info"; +zci is_cached => 0; + +triggers start => 'sunrise', 'sunset'; + +primary_example_queries 'sunrise', 'sunset'; +secondary_example_queries 'sunrise for aug 30', 'sunset on 2015-01-01'; +description 'Compute the sunrise and sunset for a given day'; +code_url 'https://github.com/duckduckgo/zeroclickinfo-goodies/blob/master/lib/DDG/Goodie/SunInfo.pm'; +category 'calculations'; +topics 'everyday'; +attribution github => ['https://github.com/duckduckgo', 'duckduckgo']; + +my $time_format = '%T %Z'; +my $datestring_regex = datestring_regex(); + +handle remainder => sub { + + my $remainder = shift; + my ($lat, $lon, $tz) = ($loc->latitude, $loc->longitude, $loc->time_zone); + my $where = join(', ', grep { defined $_ } ($loc->city, $loc->region_name, $loc->country_name)); + return unless (($lat || $lon) && $tz && $where); # We'll need a real location and time zone. + my $dt; + if (!$remainder) { + $dt = DateTime->now(time_zone => $tz); + } elsif ($remainder =~ /^(?:on|for)\s+(?$datestring_regex)$/) { + try { $dt = parse_datestring_to_date($+{'when'}); $dt->set_time_zone($tz) }; + } + return unless $dt; # Also going to need to know which day. + my @table_data = (['Location', $where]); + + my $sun_at_loc = DateTime::Event::Sunrise->new( + longitude => $lon, + latitude => $lat, + precise => 1, # Slower but more precise. + silent => 1, # Don't fill up STDERR with noise, if we have trouble. + ); + push @table_data, ['Date', date_output_string($dt)]; + + # We don't care for which one they asked, we compute both sunrise and sunset + push @table_data, ['Sunrise', $sun_at_loc->sunrise_datetime($dt)->strftime($time_format)]; + push @table_data, ['Sunset', $sun_at_loc->sunset_datetime($dt)->strftime($time_format)]; + my $text = join(' | ', (map { join(' => ', @{$_}) } @table_data)); + return $text, html => to_html(@table_data); +}; + +sub to_html { + my $results = ""; + my $minwidth = "90px"; + foreach my $result (@_) { + $results .= + "
$result->[0]: $result->[1]
"; + $minwidth = "180px" if length($result->[0]) > 10; + } + return $results . ""; +} + +1; diff --git a/share/goodie/sun_info/sun_info.css b/share/goodie/sun_info/sun_info.css new file mode 100755 index 000000000..dcc8dde03 --- /dev/null +++ b/share/goodie/sun_info/sun_info.css @@ -0,0 +1,19 @@ +.zci--answer table.suninfo { + font-family: Consolas,"Anonymous Pro",Anonymous,"Courier New",monospace; + font-size: 12px; + line-height: 14px; +} + +.zci--answer table.suninfo td { + padding: 4px 10px 4px 10px; + border: 0px; +} + +.zci--answer table.suninfo th { + font-weight: bold; + text-align: left; + background-color: #aaa; + color: #fff; + border: 0px; + padding: 4px 10px; +} diff --git a/t/SunInfo.t b/t/SunInfo.t new file mode 100644 index 000000000..2ecc6707d --- /dev/null +++ b/t/SunInfo.t @@ -0,0 +1,33 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Test::More; +use DDG::Test::Goodie; + +zci answer_type => 'sun_info'; +zci is_cached => 0; + +my @now = (qr/^Location => Phoenixville, Pennsylvania, United States.*(EDT|EST)$/, html => qr/Location:.*(EDT|EST)/); +my @aug = (qr/^Location => Phoenixville, Pennsylvania, United States | Date => 30 Aug.*(EDT|EST)$/, html => qr/Location:.*(EDT|EST)/); +my @exact = ( + 'Location => Phoenixville, Pennsylvania, United States | Date => 01 Jan 2015 | Sunrise => 07:23:39 EST | Sunset => 16:46:52 EST', + html => + '
Location: Phoenixville, Pennsylvania, United States
Date: 01 Jan 2015
Sunrise: 07:23:39 EST
Sunset: 16:46:52 EST
' +); + +ddg_goodie_test([qw( + DDG::Goodie::SunInfo + ) + ], + 'sunrise' => test_zci(@now), + 'sunset' => test_zci(@now), + 'sunrise for aug 30' => test_zci(@aug), + 'sunset for aug 30' => test_zci(@aug), + 'sunset on 2015-01-01' => test_zci(@exact), + 'sunrise on 2015-01-01' => test_zci(@exact), + 'sunset for pilly' => undef, + 'sunrise on mars' => undef, +); + +done_testing;