App-Nag

 view release on metacpan or  search on metacpan

bin/nag  view on Meta::CPAN

#!/usr/bin/perl
# PODNAME: nag
# ABSTRACT: send yourself a reminder

use Modern::Perl;
use App::Nag;

# do initial validation of arguments
my ( $opt, $usage, $name ) = App::Nag->validate_args;

# now we validate the time expression
my ( $verbosity, $text, $synopsis, $seconds ) =
  App::Nag->validate_time( $opt, $usage, @ARGV );

# still good, so we run it
App::Nag->run( $name, $seconds, $text, $synopsis, $verbosity );



=pod

=head1 NAME

lib/App/Nag.pm  view on Meta::CPAN


# some icon specs
use constant PHRASE    => [qw(psst hey HEY !!!)];
use constant STROKE    => [qw(0000ff 0000ff ff0000 ff0000)];
use constant FILL      => [qw(ffffff ffffff ffffff ffff00)];
use constant OPACITY   => [ 0, 1, 1, 1 ];
use constant FONT_SIZE => [ 20, 25, 28, 32 ];
use constant XY        => [ [ 8, 40 ], [ 9, 40 ], [ 7, 41 ], [ 3, 43 ] ];


sub validate_args {
    my $name = prog_name;
    my ( $opt, $usage ) = describe_options(
        "$name %o <time> <text>+",
        [],
        ['Send yourself a reminder.'],
        [],
        [
            'urgency' => hidden => {
                one_of => [
                    [ 'nudge|n', 'low key reminder' ],

lib/App/Nag.pm  view on Meta::CPAN

                {
                    pre_text => "ERROR: No message.\n\n"
                }
              )
        }
    }
    return ( $opt, $usage, $name );
}


sub validate_time {
    my ( undef, $opt, $usage, $time, @args ) = @_;
    require DateTime;
    require DateTime::TimeZone;

    # parse time
    $usage->die(
        {
            pre_text => "ERROR: could not understand time expression: $time\n\n"
        }
    ) unless my %props = _parse_time($time);

lib/App/Nag.pm  view on Meta::CPAN


C<App::Nag> does some heavier argument validation after the initial validation
performed by the initial script. If all looks good, it sets a daemon process
going that will wait the appointed time and then pop up a notification.

This module is written only to serve C<nag>. Use outside of this application at your
own risk.

=head1 METHODS

=head2 validate_args

C<validate_args> does your basic argument validation. If all goes well
it returns C<$opt> and C<$usage> arguments as per L<Getopt::Long::Descriptive> and 
a C<$name> argument as per C<Getopt::Long::Descriptive::prog_name>.

=head2 validate_time

C<validate_time> confirms the validity of the time expression. If all goes well
it generates a numeric verbosity level, title and body text, for whatever
widget is to pop up, and a number of seconds to wait before making and
displaying the widget.

=head2 run

C<run> spawns a daemon process which will wait until the appointed time
and then pop up the notification widget. It takes the program name, seconds
to wait, body and title text, and verbosity level. It returns nothing.

t/arg_validation.t  view on Meta::CPAN

# this all could be cleaned up a bit

my (
    $opt,      $usage,   $name, $verbosity, $text,
    $synopsis, $seconds, $time, $true_seconds
);
local @ARGV;

subtest '1s delta' => sub {
    @ARGV = qw(1s this is the text);
    ( $opt, $usage, $name ) = App::Nag->validate_args;
    ( $verbosity, $text, $synopsis, $seconds ) =
      App::Nag->validate_time( $opt, $usage, @ARGV );
    ok( $verbosity == 1, 'right verbosity' );
    ok( $seconds == 1,   '1s' );
};

subtest '1h delta' => sub {
    @ARGV = qw(--slap 1h this is the text);
    ( $opt, $usage, $name ) = App::Nag->validate_args;
    ( $verbosity, $text, $synopsis, $seconds ) =
      App::Nag->validate_time( $opt, $usage, @ARGV );
    ok( $verbosity == 3,     'right verbosity --slap' );
    ok( $seconds == 60 * 60, '1h' );
};

subtest '1H delta' => sub {
    @ARGV = qw(--slap 1H this is the text);
    ( $opt, $usage, $name ) = App::Nag->validate_args;
    ( $verbosity, $text, $synopsis, $seconds ) =
      App::Nag->validate_time( $opt, $usage, @ARGV );
    ok( $verbosity == 3,     'right verbosity --slap' );
    ok( $seconds == 60 * 60, '1h' );
};

my $tz = DateTime::TimeZone->new( name => 'local' );

subtest '10am' => sub {
    $time         = '10am';
    $true_seconds = get_time( 10, 0, 'am' );
    @ARGV         = ( $time, qw(this is the text) );
    ( $opt, $usage, $name ) = App::Nag->validate_args;
    ( $verbosity, $text, $synopsis, $seconds ) =
      App::Nag->validate_time( $opt, $usage, @ARGV );
    ok( $seconds == $true_seconds, "time: $time" );
};

subtest '10AM' => sub {
    $time         = '10AM';
    $true_seconds = get_time( 10, 0, 'am' );
    @ARGV         = ( $time, qw(this is the text) );
    ( $opt, $usage, $name ) = App::Nag->validate_args;
    ( $verbosity, $text, $synopsis, $seconds ) =
      App::Nag->validate_time( $opt, $usage, @ARGV );
    ok( $seconds == $true_seconds, "time: $time" );
};

subtest '10A.M.' => sub {
    $time         = '10A.M.';
    $true_seconds = get_time( 10, 0, 'am' );
    @ARGV         = ( $time, qw(this is the text) );
    ( $opt, $usage, $name ) = App::Nag->validate_args;
    ( $verbosity, $text, $synopsis, $seconds ) =
      App::Nag->validate_time( $opt, $usage, @ARGV );
    ok( $seconds == $true_seconds, "time: $time" );
};

subtest 'plain 10' => sub {
    $time         = '10';
    $true_seconds = get_time( 10, 0 );
    @ARGV         = ( $time, qw(this is the text) );
    ( $opt, $usage, $name ) = App::Nag->validate_args;
    ( $verbosity, $text, $synopsis, $seconds ) =
      App::Nag->validate_time( $opt, $usage, @ARGV );
    ok( $seconds == $true_seconds, "time: $time" );
};

subtest '13:24' => sub {
    $time         = '13:24';
    $true_seconds = get_time( 13, 24 );
    @ARGV         = ( $time, qw(this is the text) );
    ( $opt, $usage, $name ) = App::Nag->validate_args;
    ( $verbosity, $text, $synopsis, $seconds ) =
      App::Nag->validate_time( $opt, $usage, @ARGV );
    ok( $seconds == $true_seconds, "time: $time" );
};

subtest 'exceptions' => sub {
    isnt(
        exception {
            $time = '13:24am';
            @ARGV = ( $time, qw(this is the text) );
            ( $opt, $usage, $name ) = App::Nag->validate_args;
            App::Nag->validate_time( $opt, $usage, @ARGV );
        },
        undef,
        "can't parse 13:24am"
    );
    isnt(
        exception {
            $time = '10G';
            @ARGV = ( $time, qw(this is the text) );
            ( $opt, $usage, $name ) = App::Nag->validate_args;
            App::Nag->validate_time( $opt, $usage, @ARGV );
        },
        undef,
        "can't parse 10G"
    );
    isnt(
        exception {
            $time = '11:60';
            @ARGV = ( $time, qw(this is the text) );
            ( $opt, $usage, $name ) = App::Nag->validate_args;
            App::Nag->validate_time( $opt, $usage, @ARGV );
        },
        undef,
        "can't parse 11:60"
    );
    isnt(
        exception {
            $time = '24pm';
            @ARGV = ( $time, qw(this is the text) );
            ( $opt, $usage, $name ) = App::Nag->validate_args;
            App::Nag->validate_time( $opt, $usage, @ARGV );
        },
        undef,
        "can't parse 24pm"
    );
};

done_testing();

# construct a test time
sub get_time {



( run in 0.341 second using v1.01-cache-2.11-cpan-4d50c553e7e )