#! /usr/bin/perl -w
#Tue Aug 9 18:31:56 2005
#Sweet little appointment planer written by Robin Wenglewski <robin@wenglewski.de>
#please keep me up to date with changes on this programm. I know it's not perfect (nor is it my english) but
#I would be glad to hear suggestions for improvement
use Date::Calc qw(Mktime);
use Date::Calc qw(Today_and_Now);
use Getopt::Std;
use Time::localtime;
use Term::ReadKey;
#getting the options
my $optstring = 'nls:ad';
getopts("$optstring", \%opt ) or die "error with getopts";
#optional
if ($opt{a}) {$all='true';} else {$all='false';}
#what happens with which option
if ($opt{n}) {&new;}
elsif ($opt{l}) {&list;}
elsif ($opt{s}) {&search;}
elsif ($opt{d}) {&demon;}
else {&usage};
sub demon() {
open(IFILE,"<\.termine");
while(<IFILE>) {
#splitting the lines line up
my @parts=split("\:\:",$_);
#filtering invalid an past appoitments
if ($#parts!=2 || ($all eq 'false' && $parts[0]<(time))) {next;}
#with the next appoitment, start &countdown
if ($parts[0]>(time)) {&countdown(@parts); }}
close IFILE;}
sub printday() {
open(IFILEDAY,"<\.termine");
print "\n\nDay appointments:\n";
#getting the momentanious time
my ($y,$m,$d,$h,$min,$s) = Today_and_Now([$gmt]);
#etime is the time of the last second of that day
my $etime = Mktime($y,$m,$d,23,59,59);
while(<IFILEDAY>) {
my $line = $_;
my @parts=split("\:\:",$line);
#filter invalids
if ($#parts!=2 || ($all eq 'false' && ($parts[0]<=$_[0] || $parts[0]>=$etime))) {next;}
#print the rest
if ($parts[0]>(time)) {&printtermin($line); }}}
close IFILEDAY;
sub countdown() {
#getting the argument
my $line=$_;
my @parts=split("\:\:",$line);
#variable for a pressed key
my $key="";
#creating new process and saving the id in $pid
my $pid = fork();
# The Child-Prozess
if($pid == 0){
open(IFILE,"<\.termine");
while(1){
#clearing sceen
system("clear");
print(ctime(time)."\n");
#getting the remaining time
my $s = $parts[0]-(time);
my $d=0;
my $h=0;
my $m=0;
if ($s>=60) {
$tmp=$s % 60;
$m=($s-$tmp) / 60;
$s=$tmp;
if ($m>=60) {
$tmp=$m % 60;
$h=($m-$tmp) / 60;
$m=$tmp;
if ($h>=24) {
$tmp=$h % 24;
$d=($h-$tmp) / 24;
$h=$tmp;
}}}
#printing the remaining time
print ("\nnext appointment in $d Tagen $h\:$m\:$s\n");
#printing the coming appointment
print ("\ncoming appointment:\n\n");
&printtermin($line);
#print the rest of the appointments of that day
&printday($parts[0]);
#making sure that the whileloop doesn't take all resources
system("sleep 1");}
#Main Process
} else {
#when a key is pressed, you don't have to press also <return>
ReadMode "raw";
#as long as q isn't pressed
while(!($key eq "q")) {
open(TTY, "</dev/tty");
#waiting for a key stroke
$key = ReadKey 0, *TTY; }
#when q was pressed, Readmode back to normal
ReadMode "normal";
print "\n";
close IFILE;
#and killing the child process
kill 9,$pid;
#and exit the programm
exit;}}
sub search() {
open (IFILE,"<\.termine");
while(<IFILE>) {
#if the line contains the demanded string, print it
if($_ =~ /$opt{s}/i) {&printtermin($_);}}
close IFILE; }
sub list() {
open (IFILE,"< \.termine");
while(<IFILE>) {
&printtermin($_);}
close IFILE;
}
sub printtermin() {
#split up the given argument (it has to be a line)
@parts=split("\:\:",$_[0]);
#filter invalids
if ($#parts!=2 || ($all eq 'false' && $parts[0]<(time))) {return 1;}
#and print the appointment
print ctime($parts[0]).': '.$parts[1]."\n".$parts[2]; }
sub new() {
#get title and time
my $titel=$ARGV[2];
my $seks=&zeitumrechnung($ARGV[0],$ARGV[1]);
print "Please enter now further informations:\n";
$info=<STDIN>;
open(OFILE, ">> \.termine");
#print everything in file
print OFILE "$seks\:\:$titel\:\:$info";
close OFILE;
#arrange it
&arrange;
}
sub arrange() {
my @termine;
#open one input and one output file
open(IFILE,"< \.termine");
open(OFILE,"> \.termine.new");
while(<IFILE>) {
#split each line
@parts=split("\:\:",$_);
#and push it in termine (@parts should contain three variables)
push(@termine,@parts); }
close IFILE;
#now the real arrangement follows
for($i=0;$i<=$#termine-5;$i+=3) {
for ($j=$i+3;$j<=$#termine-2;$j+=3) {
if($termine[$i]>$termine[$j]) {
($termine[$i], $termine[$j]) = ($termine[$j], $termine[$i]);
($termine[$i+1], $termine[$j+1]) = ($termine[$j+1], $termine[$i+1]);
($termine[$i+2], $termine[$j+2]) = ($termine[$j+2], $termine[$i+2]); } }}
for($i=0;$i<=$#termine-2;$i+=3) {
#and here the termine array is printed back to a file
print OFILE "$termine[$i]\:\:$termine[$i+1]\:\:$termine[$i+2]"; }
close OFILE;
#now the new file substitutes the old one
system("mv -f .termine.new .termine");
}
sub zeitumrechnung() {
my $datum=$_[0];
my @datum=split('\.',$datum);
my $zeit=$_[1];
my @zeit=split(':',$zeit);
#make a $time format and return it
my $time = Mktime($datum[2],$datum[1],$datum[0],$zeit[0],$zeit[1],0);
return $time; }
sub usage() {
print "\nusage: apps.pl [command]
-l lists all coming appointments
-n [dd.mm.yyyy hh:mm NAME] creates an appointment to the given time under the name NAME
-s [PATTERN] looks through the coming appointments for the pattern
-d deamon (q=quit)
OPTIONAL
-a lists all\n\n"; }