#!/usr/bin/perl # # ovacron - egg timer # # Revision History: # 1.0 Initial version. 2010 # 2.0 Added the -quiet and -silent options. 130122 # 2.1 Globbed the default tune. 130707 # 2.2 Fixed usage message. 140117 # 2.3 Added the -postcount option. 140205 # 2.4 Added licensing info. 180531 # # Written by Wayne Morrison, 2010. # # Copyright 2010 Wayne Morrison # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ####################################################################### use strict; use Getopt::Long qw(:config no_ignore_case_always); # # Version information. # my $NAME = "ovacron"; my $VERS = "$NAME version: 2.4"; #------------------------------ # # Defaults. # my $DEFBEEPS = 5; # Default number of beeps. my $DEFSLEEP = 3; # Default sleep time. #------------------------------------------------------------------------ # # Stuff for command-line options. # my %opts = (); # Filled option array. my @opts = ( "beeps=i", # Number of beeps. "forever", # Beep forever. "postcount", # Post counter. "verbose", # Display countdown. "quiet", # No countdown. "silent", # No music "Version", # Version flag. "help", # Give help message. ); my $beeps = $DEFBEEPS; # Number of beeps to beep. my $forever = 0; # Beep forever. my $posthorn = 0; # Post-count flag. my $silent = 0; # Tune flag. my $verbose = 1; # Verbose flag. #------------------------------------------ # # Sound player and sound file for non-silent alarms. # my $musicbox = 'playsound'; my $tune = glob("~/Music/iTunes/iTunes\\ Music/Jo\\ Morrison/Flights\\ Of\\ Fantasy/09\\ Jenny\\ Lake.mp3"); my $naptime = $DEFSLEEP; # Time to sleep. my $startup; # Start time for post-alarm. main(); exit(0); #------------------------------------------------------------------------ # Routine: main() # # Purpose: Do everything. # sub main { # # Autoflush our output buffer. # $| = 1; # # Parse our command line. # opts(); # # You're feeling very sleepy... sleeeeepeeeeeee............. # sleepy(); # # Wake up! # wakey(); } #------------------------------------------------------------------------ # Routine: opts() # # Purpose: Handle our options and do some set-up. # sub opts { # # Get the options. # GetOptions(\%opts,@opts) || usage(); # # Look for -help or -Version. # usage() if(defined($opts{'help'})); version() if(defined($opts{'Version'})); # # Dig out options from the command line. # $beeps = $opts{'beeps'} if(defined($opts{'beeps'})); $forever = 1 if(defined($opts{'forever'})); $posthorn = 1 if(defined($opts{'postcount'})); $silent = 1 if(defined($opts{'silent'})); $verbose = 1 if(defined($opts{'verbose'})); $verbose = 0 if(defined($opts{'quiet'})); # # -beeps and -forever are mutually exclusive. # usage() if(defined($opts{'beeps'}) && defined($opts{'forever'})); # # Check for a sleep time. # $naptime = $ARGV[0] if(@ARGV); # # Convert the time into the proper number of seconds. # If it has a trailing 's', lop off the 's' and leave the # number alone. # If it has a trailing 'm', lop off the 'm' and multiply by 3. # If it has no trailing 'm' or s', multiply by 3. # if($naptime =~ /s$/i) { $naptime =~ s/.$//; } else { $naptime =~ s/.$// if($naptime =~ /m$/i); $naptime *= 60; } } #------------------------------------------------------------------------ # Routine: sleepy() # # Purpose: Handle our sleeping, along with the optional seconds counter. # sub sleepy { # # Sleep for a bit. If we're not verbose, just sleep. If we # are verbose, give a timer countdown. # if($verbose) { # # Give a countdown every second. # while($naptime) { print "\r\t$naptime\t"; sleep(1); print "\t\t\t\t"; $naptime--; } } else { sleep($naptime); } } #------------------------------------------------------------------------ # Routine: wakey() # # Purpose: Handle our waking up -- the beeps, the optional wake-up # tune, and the optional post-counter. # sub wakey { # # Announce the expiration of the timer. # while($beeps) { print "\r"; $beeps-- if(! $forever); last if($beeps == 0); sleep(1); } # # Maybe provide a post-sleep counter. # if($posthorn) { $startup = time; $SIG{ALRM} = \&upcount; alarm(1); } # # We might play a little chune to announce the timer completion. # if(($silent == 0) && ($musicbox ne '') && ($tune ne '') && (-e $tune)) { system("$musicbox '$tune'"); print "\n"; } # # If the user wants the post-counter, we'll take care of that here. # system() covered this while we were playing music, but we'll # just keep looping until the user interrupts us. # if($posthorn) { while(42) { select(undef,undef,undef,undef); } } print "\n" if($verbose); } #------------------------------------------------------------------------ # Routine: upcount() # # Purpose: Register that a second has passed after the wake-up. # sub upcount { my $upcount; $upcount = time - $startup; print "\r\t$upcount\t"; alarm(1); } #------------------------------------------------------------------------ # Routine: version() # sub version { print STDERR "$VERS\n"; exit(0); } #------------------------------------------------------------------------ # Routine: usage() # sub usage { print STDERR "usage: ovacron [options] \n"; print STDERR "\toptions:\n"; print STDERR "\t\t-beeps number of beeps to give\n"; print STDERR "\t\t-forever beep forever\n"; print STDERR "\t\t-postcount provide a post-alarm counter\n"; print STDERR "\t\t-silent does not play tune\n"; print STDERR "\t\t-verbose gives verbose output\n"; print STDERR "\t\t-quiet does not give countdown\n"; print STDERR "\t\t-Version gives command version\n"; print STDERR "\t\t-help displays this help message\n"; exit(0); } 1; ######################################################################### =pod =head1 NAME ovacron - Egg timer =head1 SYNOPSIS ovacron [options] =head1 DESCRIPTION B is a countdown timer. After a specified amount of time, B "beeps" the terminal. If the sleep time isn't given, then B will sleep for three minutes. The sleep time may be given in minutes as a number or a number followed by an 'm'; for example "5" or "5m". The sleep time can also be given in seconds as a number followed by an 's'; for example, "120s". By default, a countdown will be displayed. The B<-quiet> option will prevent this from happening. If you have a command-line music player, you can set two internal variables to play a tune when the timer expires. The I<$musicbox> variable should be set to the name of the command-line music player. The I<$tune> variable should be set to the path of a sound file. If these are not set or if the sound file is not found, then B will not play a tune. =head1 OPTIONS The following options are handled by B: =over 4 =item B<-beeps numbeeps> At the expiration of the timer, the terminal will be "beeped" I times. The default is 5. =item B<-forever> At the expiration of the timer, the terminal will be "beeped" until B is killed. =item B<-postcount> At the expiration of the timer, this option causes an increasing counter to be displayed showing the number of seconds since the alarm went off. =item B<-silent> Prevent a nice tune from being played upon completion of the timer. =item B<-quiet> A countdown will not be given while sleeping. This option overrides the B<-verbose> option and the default behavior. =item B<-verbose> A countdown will be given while sleeping. =item B<-Version> The command version will be printed and B will exit. =item B<-help> Displays a usage message. =back =head1 AUTHOR Wayne Morrison, wayne@waynemorrison.com =head1 LICENSE Copyright 2010 Wayne Morrison Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =cut