2014-11-07 14:47:36 -08:00
|
|
|
package DDG::Goodie::Uptime;
|
|
|
|
# Given an uptime percentage, display various average downtime durations
|
|
|
|
|
2015-02-22 12:09:29 -08:00
|
|
|
use strict;
|
2014-11-07 14:47:36 -08:00
|
|
|
use DDG::Goodie;
|
|
|
|
use Time::Duration;
|
|
|
|
use Time::Seconds;
|
2014-11-09 05:06:43 -08:00
|
|
|
with 'DDG::GoodieRole::NumberStyler';
|
2014-11-07 14:47:36 -08:00
|
|
|
|
|
|
|
zci answer_type => "uptime";
|
|
|
|
zci is_cached => 1;
|
|
|
|
|
|
|
|
name "Uptime";
|
|
|
|
description "Given an uptime percentage, display various average downtime durations";
|
2014-11-13 07:26:41 -08:00
|
|
|
primary_example_queries "uptime 99,99%", "uptime 99.99%", "99.99% uptime";
|
2014-11-07 14:47:36 -08:00
|
|
|
secondary_example_queries "uptime of 99.9998%";
|
|
|
|
category "calculations";
|
|
|
|
topics "computing";
|
|
|
|
code_url "https://github.com/duckduckgo/zeroclickinfo-goodies/blob/master/lib/DDG/Goodie/Uptime/Uptime.pm";
|
|
|
|
attribution github => ["YouriAckx", "Youri Ackx"],
|
|
|
|
web => ["http://ackx.net/", "Youri Ackx"],
|
2015-01-07 10:24:47 -08:00
|
|
|
twitter => ["YouriAckx", "Youri Ackx"];
|
2014-11-07 14:47:36 -08:00
|
|
|
|
|
|
|
# Triggers
|
2014-11-09 05:56:28 -08:00
|
|
|
triggers startend => "uptime", start => "uptime of";
|
2014-11-07 14:47:36 -08:00
|
|
|
|
|
|
|
# Near zero duration messages
|
|
|
|
my $JUST_NOW_MSG = "just now"; # from Time::Duration
|
2014-11-15 03:35:07 -08:00
|
|
|
my $LESS_THAN_ONE_SECOND_MSG = "less than one second"; # from us
|
2014-11-07 14:47:36 -08:00
|
|
|
|
|
|
|
|
|
|
|
# Compute the downtime string durations (year, month, day)
|
|
|
|
# for the given uptime (must be btw 0 and 1)
|
|
|
|
sub compute_durations {
|
|
|
|
my $downtime_percentage = 1 - $_[0];
|
2014-11-09 05:28:21 -08:00
|
|
|
return map { fix_just_now(duration($_ * $downtime_percentage)) } (ONE_YEAR, ONE_MONTH, ONE_DAY);
|
2014-11-07 14:47:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Given a duration, replace "just now" emitted by Time::Duration
|
|
|
|
# by "Less than one second" when applicable,
|
|
|
|
# or return the duration itself otherwise.
|
|
|
|
sub fix_just_now {
|
|
|
|
my $duration = $_[0];
|
2014-11-09 05:10:35 -08:00
|
|
|
return $duration eq $JUST_NOW_MSG ? $LESS_THAN_ONE_SECOND_MSG : $duration;
|
2014-11-07 14:47:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Format response as text
|
|
|
|
sub format_text {
|
|
|
|
my ($uptime_percentage, $downtime_year, $downtime_month, $downtime_day) = @_;
|
2014-11-19 03:25:23 -08:00
|
|
|
my $text = "Implied downtimes for " . $uptime_percentage . " uptime\n";
|
2014-11-07 14:47:36 -08:00
|
|
|
|
|
|
|
if ($downtime_year eq $LESS_THAN_ONE_SECOND_MSG) {
|
2014-11-15 03:35:07 -08:00
|
|
|
$text .= "No downtime or less than a second during a year";
|
2014-11-07 14:47:36 -08:00
|
|
|
return $text;
|
|
|
|
}
|
|
|
|
|
2014-11-15 03:35:07 -08:00
|
|
|
$text .= "Daily: " . $downtime_day . "\n";
|
|
|
|
$text .= "Monthly: " . $downtime_month . "\n";
|
|
|
|
$text .= "Annually: " . $downtime_year;
|
2014-11-07 14:47:36 -08:00
|
|
|
return $text;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Format response as HTML
|
|
|
|
sub format_html {
|
|
|
|
my ($uptime_percentage, $downtime_year, $downtime_month, $downtime_day) = @_;
|
2014-11-19 03:25:23 -08:00
|
|
|
my $html = '<div class="zci__header">Implied downtimes for ';
|
|
|
|
$html .= $uptime_percentage . " uptime</div>";
|
2014-11-07 14:47:36 -08:00
|
|
|
|
|
|
|
if ($downtime_year eq $LESS_THAN_ONE_SECOND_MSG) {
|
2014-11-14 02:31:10 -08:00
|
|
|
$html .= '<div class="zci__content">No downtime or less than a second during a year</div>';
|
2014-11-07 14:47:36 -08:00
|
|
|
return $html;
|
|
|
|
}
|
|
|
|
|
2014-11-15 03:35:07 -08:00
|
|
|
$html .= '<div class="zci__content"> Daily: ' . $downtime_day . '<br>';
|
|
|
|
$html .= 'Monthly: ' . $downtime_month . '<br>';
|
|
|
|
$html .= 'Annually: ' . $downtime_year . '</div>';
|
2014-11-07 14:47:36 -08:00
|
|
|
return $html;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Handle statement
|
|
|
|
handle remainder => sub {
|
2014-11-09 05:09:15 -08:00
|
|
|
return unless $_; # Guard against "no answer"
|
2014-11-09 05:06:43 -08:00
|
|
|
return unless s/%$//; # Query should end with '%'. Test and remove it
|
2014-11-07 14:47:36 -08:00
|
|
|
s/\s+//g; # Delete the whitespaces
|
2014-11-09 05:06:43 -08:00
|
|
|
|
|
|
|
# Look for something that "looks like a number"
|
|
|
|
my $number_string = $_;
|
|
|
|
my $number_re = number_style_regex();
|
|
|
|
$number_string =~ qr/($number_re)/;
|
|
|
|
|
|
|
|
# Get an object that can handle the number
|
|
|
|
my $styler = number_style_for($number_string);
|
|
|
|
return unless $styler; # might not be supported
|
|
|
|
my $perl_number = $styler->for_computation($number_string);
|
|
|
|
my $clean_query = $styler->for_display($perl_number) . '%';
|
2014-11-07 14:47:36 -08:00
|
|
|
|
|
|
|
# Query value must be btw 0 and 100
|
2014-11-09 05:06:43 -08:00
|
|
|
return unless $perl_number >= 0 && $perl_number < 100;
|
2014-11-07 14:47:36 -08:00
|
|
|
|
2014-11-09 05:06:43 -08:00
|
|
|
my ($year, $month, $day) = compute_durations($perl_number / 100);
|
2014-11-07 14:47:36 -08:00
|
|
|
my $text = format_text($clean_query, $year, $month, $day);
|
|
|
|
my $html = format_html($clean_query, $year, $month, $day);
|
|
|
|
|
|
|
|
return $text, html => $html;
|
|
|
|
};
|
|
|
|
|
|
|
|
1;
|