Tuesday, November 18, 2008

Perl Timers v1

A simple perl script that permits 3 timers to be controlled from a Tk GUI:

The script keeps a log of it's uses, and there is a simple help pop-up.

## ------------------------------------------------#!/usr/bin/perl

use English;
require Tk;
require Tk::Balloon;
use Tk;

my $main = MainWindow->new();
my $timeStamp;

open( LOG, ">>.timers.log" ) or die "can't open .timers.log logfile.";
print LOG "==== Program Start ====\n";

##$main->minsize( qw(440 140));
$main->configure( - background => 'grey' );

my $introFrm = $main->Frame( -background=>'cyan' )->
  pack( -side => 'top'); #, pady => 9, -padx => 7 

my $imgPause = $main->Photo(-file => 'pause.gif');
my $imgStart = $main->Photo(-file => 'play.gif');
my $imgStop = $main->Photo(-file => 'stop.gif');

my $intro = $introFrm->Label(
  -text=>'Countdown to alarm, or time a duration', # Enter a time (minutes) and start countdown.
  -background=>'lightgrey',
  )->pack(-side=>'top'
);
   
$ticker = $intro->repeat(1000, \&tick );  

$balloon = $main->Balloon();
$balloon->attach($intro, 
  -balloonmsg => 
  "Down count from set number of minutes,\n".
  "or up count by setting minutes value to zero.\n".
  "2h34 can be used for 2 hrs 34 minutes."
  );



#############################################
   
my $timer1Running = 0;
my $timer1Paused = 0;
my $secs1;
   
#my $new = $introFrm->Button(
 # -background=>'lightblue', 
 # -text=>'+',
 # -padx=>'3',
 # -command => sub { print "Add another timer ...\n"; },
 # )->pack(-side=>'left');

my $alarmFrame1 = $main->Frame( -background=>'grey' )->
  pack( -side => 'top', -fill => 'x' );
   
my $name1 = $alarmFrame1->Entry(
  -background=>'white', 
  -width=>24 ) -> pack(-side=>'left', -padx=>4);

$name1->insert("end", "Citrix");

my $minute1 = $alarmFrame1->Entry(
  -background=>'white', 
  -width=>3 ) ->pack(-side=>'left');

$minute1->insert("end", "35");

my $ctrl1 = $alarmFrame1->Button(
  -background=>'lightgreen', 
  -image => $imgStart,
  -command => [ \&HandleCtrl1 ]
  )->pack(-side=>'left', -padx=>1);


my $pause1 = $alarmFrame1->Button(
  -background=>'lightgrey', 
  -image => $imgPause,
  -state=>'disabled',
  -command => [ \&HandlePause1 ]
  )->pack(-side=>'left');

my $remain1 = $alarmFrame1->Label(
  -background=>'lightgreen', 
  -text=>'0',
  -width=>7,
  -padx=>3,  
  -relief=>'sunken' ) ->pack(-side=>'left' );

sub HandleCtrl1 ()
{
  my $title = $name1->get();
  chomp $title; 
  if ($timer1Running) {
  $ctrl1->configure (
  -image => $imgStart,
  -background=>'lightgreen') ;
  $pause1->configure ( 
  -state=>'disable',
  -text => 'Pause' ); 
  $timer1Running = 0;
  consoleLog("Stop ".$name1->get(), 1, $secs1);

  } else {

  my $mins = $minute1->get();
  chomp $mins;
  $ctrl1->configure (
  -image => $imgStop,
  -background=>'pink'
  ) ;

  $secs1 = getSecsFromMins($mins); ## 60 * $mins; 

  consoleLog("Start ".$name1->get(), 1, $secs1);
  $timer1Running = 1;
  $timer1Paused = 0;
  $pause1->configure ( 
  -state=>'normal',
  -text => 'Pause', 
  -background=>'lightgrey');
  $remain1->configure(
  -text => timeStr($secs3),
  -background=>'lightgreen' 
  );
  }
}

sub HandlePause1 ()
{
  my $title = $name1->get();
  chomp $title;
  if (!$timer1Paused) {
  $pause1->configure (
  -text => 'Resume', 
  -background=>'lightgreen') ;
  consoleLog("Pause ".$name1->get(), 1, $secs1);
  $timer1Paused = 1;
  } else {
  $pause1->configure(
  -text => 'Pause ', 
  -background=>'lightgrey' );
  consoleLog("Resume ".$name1->get(), 1, $secs1);
  $timer1Paused = 0;
  }
}


#############################################

my $timer2Running = 0;
my $timer2Paused = 0;
my $secs2;

my $alarmFrame2 = $main->Frame( -background=>'grey' )->
  pack( -side => 'top', -fill => 'x' );
   
my $name2 = $alarmFrame2->Entry(
  -background=>'white', 
  -width=>24 ) -> pack(-side=>'left', -padx=>4);

$name2->insert("end", "Timer2");

my $minute2 = $alarmFrame2->Entry(
  -background=>'white', 
  -width=>3 ) ->pack(-side=>'left');

$minute2->insert("end", "10");

my $ctrl2 = $alarmFrame2->Button(
  -background=>'lightgreen', 
  -image => $imgStart,
  -command => [ \&HandleCtrl2 ]
  )->pack(-side=>'left', -padx=>1);

my $pause2 = $alarmFrame2->Button(
  -background=>'lightgrey', 
  -image => $imgPause,
  -state=>'disabled',
  -command => [ \&HandlePause2 ]
  )->pack(-side=>'left');

my $remain2 = $alarmFrame2->Label(
  -background=>'lightgreen', 
  -text=>'0',
  -width=>7, 
  -padx=>3,  
  -relief=>'sunken' ) ->pack(-side=>'left' );

sub HandleCtrl2 ()
{
  my $title = $name2->get();
  chomp $title; 
  if ($timer2Running) {
  consoleLog("Stop ".$name2->get(), 2, $secs2);
  $timer2Running = 0;
  $ctrl2->configure (
  -image => $imgStart,
  -background=>'lightgreen') ;
 $remain2->configure ( -background=>'lightgreen') ;
  $pause2->configure ( 
  -state=>'disable',
  -text => 'Pause' ); 
  } else {
  my $mins = $minute2->get();
  chomp $title; chomp $mins;
  $ctrl2->configure (
  -image => $imgStop,
  -background=>'pink'
  ) ;

  $secs2 = getSecsFromMins($mins); ## 60 * $mins; 
   
  consoleLog("Start ".$name2->get(), 2, $secs2);
  $timer2Running = 1;
  $timer2Paused = 0;
  $pause2->configure ( 
  -state=>'normal',
  -text => 'Pause', 
  -background=>'lightgrey');

  $remain2->configure(
  -text => timeStr($secs3),
  -background=>'lightgreen' 
  );
  }
}

sub HandlePause2 ()
{
  my $title = $name2->get();
  chomp $title;
  if (!$timer2paused) {
  $pause2->configure (-text => 'Resume', -background=>'lightgreen') ;
  consoleLog("Pause ".$name2->get(), 2, $secs2);
  $timer2Paused = 1;
  } else {
  $pause2->configure (-text => 'Pause ', -background=>'lightgrey') ;
  consoleLog("Resume ".$name2->get(), 2, $secs2);
  $timer2Paused = 0;
  }
}


#############################################

my $timer3Running = 0;
my $timer3Paused = 0;
my $secs3;

my $alarmFrame3 = $main->Frame( -background=>'grey' )->
  pack( -side => 'top', -fill => 'x' );
   
my $name3 = $alarmFrame3->Entry(
  -background=>'white', 
  -width=>24 ) -> pack(-side=>'left', -padx=>4);

$name3->insert("end", "Timer3");

my $minute3 = $alarmFrame3->Entry(
  -background=>'white', 
  -width=>3 ) ->pack(-side=>'left');

$minute3->insert("end", "0");

my $ctrl3 = $alarmFrame3->Button(
  -background=>'lightgreen', 
  -image => $imgStart,
  -command => [ \&HandleCtrl3 ]
  )->pack(-side=>'left', -padx=>1);

my $pause3 = $alarmFrame3->Button(
  -background=>'lightgrey', 
  -image => $imgPause,
  -state=>'disabled',
  -command => [ \&HandlePause3 ]
  )->pack(-side=>'left');

my $remain3 = $alarmFrame3->Label(
  -background=>'lightgreen', 
  -text=>'0',
  -width=>7,
  -padx=>3,  
  -relief=>'sunken' ) ->pack(-side=>'left' );

sub HandleCtrl3 ()
{
  my $title = $name3->get();
  chomp $title;
  if ($timer3Running) {
  consoleLog("Stop ".$name3->get(), 3, $secs3);
  $timer3Running = 0;
   
  $ctrl3->configure (
  -image => $imgStart,
  -background=>'lightgreen'
  ) ;
  $pause3->configure ( 
  -state=>'disable',
  -text => 'Pause' 
  ); 

  } else {
   
  my $mins = $minute3->get();
  chomp $mins;
  $ctrl3->configure (
  -image => $imgStop,
  -background=>'pink'
  ) ;

  $secs3 = getSecsFromMins($mins); ## 60 * $mins; 

  # print "Running \"$title\" (3) from $mins\n";

  consoleLog("Start ".$name3->get(), 3, $secs3);
  $timer3Running = 1;
  $timer3Paused = 0;
  $pause3->configure ( 
  -state=>'normal',
  -text => 'Pause', 
  -background=>'lightgrey'
  );
  $remain3->configure(
  -text => timeStr($secs3),
  -background=>'lightgreen'
  );

  }
}

sub HandlePause3 ()
{
  my $title = $name3->get();
  chomp $title;
  if (!$timer3Paused) {
  $pause3->configure (-text => 'Resume', -background=>'lightgreen') ;
  consoleLog("Pause ".$name3->get(), 3, $secs3);
  $timer3Paused = 1;
  } else {
  $pause3->configure (-text => 'pause ', -background=>'lightgrey') ;
  consoleLog("Resume ".$name3->get(), 3, $secs3);
  $timer3Paused = 0;
  }
}

#################################

sub getSecsFromMins($)
{
  my ($hm, $hrs, $mins, @vals);
   
  if ( $_[0]=~ /[hH]/ ) ## if there's a 'h'
  {
  # print "Hours detected\n";

 $hm = "0".$_[0]; ## cater for 'h32' => 32 mins

 @vals = split ( /[hH]/, $hm );

 # print "#".@vals."\n";
 # print "".$vals[0]."-=-".$vals[1]."-=-".$vals[2]."\n";

 $mins = $vals[0] * 60 + $vals[1];

 # print "mins $mins\n";

 return 60 * $mins;


  }
  else
  {
  return 60 * $_[0];
  }
   
}

sub timeStr($)
{
  my ($times, $s);
   
  $s = abs( $_[0] );
   
  $times = sprintf("%02d:%02s", $s/60, $s%60 );
  return $times;
}

sub consoleLog ($$$)
{
  ($title, $inst, $secs) = @_;
  print "$timeStamp ($inst) \"$title\" @ ".timeStr($secs)."\n";  
  print LOG "$timeStamp ($inst) \"$title\" @ ".timeStr($secs)."\n";
  if ($title =~ "EXPIRE")
  {
  printf "%c%c%c\n",7,7,7;
  }

}

sub getDaySuffix($)
{
  my $DoM = $_[0];
   
  if ($DoM == 1 || $DoM == 21 || $DoM == 31 ) { return "st"; }

  if ($DoM == 2 || $DoM == 22 ) { return "nd"; }

  return "th";
}

sub setTime() {
  # print "t";
  my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday );
  ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday ) = localtime(time);

  my $winTitle = "".sprintf 
  "%02d%s %02d:%02d", 
  $mday, getDaySuffix($mday), $hour, $min;

  $timeStamp = sprintf( 
  "%02d-%02d-%04d %02d:%02d:%02d", 
  $mday, $mon + 1, $year + 1900, $hour, $min, $sec 
  );

  $main->title($winTitle);
}

sub tick() {

  setTime();

  if ($timer1Running && !$timer1Paused)
  {
  $secs1 --;
  if ($secs1 == 0)
  {
  my $title = $name1->get();
  chomp $title;
  consoleLog("".$name1->get()." EXPIRED", 1, $secs1);
  $remain1->configure(-text => "0", -background=>'pink' );
  } else {
  $remain1->configure( -text => timeStr($secs1) );
  }
  } 

  if ($timer2Running && !$timer2Paused)
  {
  $secs2 --;
  if ($secs2 == 0)
  {
  my $title = $name2->get();
  chomp $title;
  consoleLog("".$name2->get()." EXPIRED", 2, $secs2);
  $remain2->configure(-text => "0", -background=>'pink');
  } else {
  $remain2->configure(-text => timeStr($secs2) );
  }
  } 
   
  if ($timer3Running && !$timer3Paused)
  {
  $secs3 --;
  if ($secs3 == 0)
  {
  my $title = $name3->get();
  chomp $title;
  consoleLog("".$name3->get()." EXPIRED", 3, $secs3);
  $remain3->configure(-text => "0", -background=>'pink');
  } else {
  $remain3->configure(-text => timeStr($secs3) );
  }
  }  
}


##########

setTime();

# start first timer ... 
HandleCtrl1 ();

MainLoop();

print LOG "==== Program Exit ====\n";

close LOG;

## -------------------------- End ---

No comments: