Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Autoresponder automator

by jkva (Chaplain)
on Jul 27, 2005 at 10:04 UTC ( [id://478541]=sourcecode: print w/replies, xml ) Need Help??
Category: Utility Scripts
Author/Contact Info See node or send a /msg :)
Description: UPDATE: Working on quite a bit of improvements now; using the current version is .ill-advised.
UPDATE: Fixed. I wonder if I should let it go to the next users on file access errors or die() ...
UPDATE: b10m notified me of design flaws, I am fixing it now. Stay tuned.
UPDATE: Added status message when successful copy of .forward file has been achieved.
UPDATE: Fixed a bug and added comments.

This script generates a .forward Exim filter, plus the needed .vacation.msg reply message.
Those two files are standard, the .vacation.msg is changed to contain the start-and end date, so that the person recieving the reply knows when the user will be back.

I could've done it by hand, but I thought writing a script would be good exercise.

Any hints/advice/notices of bad style or simply horrid code are greatly appreciated. Criticism == learning opportunity.

It's the first script I've written in Unix (or in Vim, for that matter). Future additions include reading the user data out of a file, and removing itself from a crontab when the "last" date has been passed.
I'm thinking of reading the vacation dates out of the MySQL database that the company web-based calendar uses...
#!/usr/bin/perl -w

################################
# This script creates .forward #
# and .vacation.msg files      #
# for e-mail autoreplying      #
# used by Exim                 #
#                              #
###############################

use strict;
use diagnostics;

my %users = ( #username                 leaves on                 is b
+ack on
        user        =>    {van    =>    [17,7,5], tm    =>    [13,8,5]
+, },
        );
my $vacstd = '/home/user/scripts/.vacation.msg';    #standard away mes
+sage
my $fwdstd = '/home/user/scripts/.forward';         #standard Exim fil
+ter file

-e $vacstd or die("Needed file \"$vacstd\" not found; Quitting.");
-e $fwdstd or die("Needed file \"$fwdstd\" not found; Quitting.");

foreach(keys %users) {
        my $crntuser = $_;        #current user
        my @d = localtime(time);  #date info it needs for comparing
        my $sdate = join('-',@{$users{$crntuser}{van}});  #leaving dat
+e
        my $edate = join('-',@{$users{$crntuser}{tm}});   #returning d
+ate
        my $cdate = join('-',$d[3],$d[4]+1,$d[5]-100);    #current dat
+e
        my @udata = getpwnam($crntuser);                  #user login 
+pass uid gid for chown later
        my $fwdnew = "/home/$_/.forward";                 #filename fo
+r fresh Exim filter file

    if($edate eq $cdate) {   #Is the returning date today?
    if(-e $fwdnew) {        #Does the fresh Exim filter file exist?
             unlink $fwdnew;   #then delete it
              print "User Scrntuser : File $fwdnew removed due to reac
+hed target end date $edate ($cdate); Quitting.";
          exit 0;           #and we're done for today.
    }
    }

    if($sdate ne $cdate) {
        print "User $crntuser : Target start date $sdate ($cdate) not 
+yet reached.";  #next user if we're not ready yet
        next;
    }
    my $vacnew = "/home/$_/.vacation.msg";     #fresh vacation message
+ file
    print "Creating .vacation file for user $_\n";

    if(-e $vacnew)      #Does it already exist? then go on.
          { print "File \"$vacnew\" already exists? Wut??\n" ; }
    else {
         open VACSTD,$vacstd   #open standard vacation file for readin
+g
                  or die("Unable to access standard vacation file \"$v
+acstd\"; Quitting.");
         open VACNEW,">$vacnew"  #open fresh vacation file for writing
             or die("Unable to access fresh vacation file \"$vacnew\";
+ Quitting.");
         while(<VACSTD>) {
              s/_DATE_FROM_/$sdate/g;    #replace start date
          s/_DATE_UNTIL_/$edate/g;   #replace return date
          print VACNEW $_;           #save to fresh vacation file
         }
             close VACSTD;
         close VACNEW;
             print "File \"$vacnew\" successfully written.\n";
    }

    die("Unable to create \"$fwdnew\"; Quitting.")
        if system('cp',$fwdstd,$fwdnew) == -1;  #kill off if we can't 
+copy the exim filter file to the fresh copy.

    die('Error changing file permissions; Quitting.') if
    chown $udata[2],$udata[3],[$vacnew,$fwdnew] <2;  #kill off if we c
+an't set user permissions on fresh filter
                                                         # and vacatio
+n message file.

print "File \"$fwdnew\" successfully written.\n"; #Otherwise we'd have
+ die()d so this can be displayed ok :)

} #and we're done.
Replies are listed 'Best First'.
Re: Autoresponder automator
by b10m (Vicar) on Jul 27, 2005 at 11:04 UTC

    Automating things is always a Good Thing™. A few things I find interesting though.

    • You use system() to copy a file. Not very Perl'ish ;)
    • Setting the "van" and "tm" variables are first stored in an array, then converted to a scalar, why?
    • User settings are hardcoded in the script. Shouldn't be a configuration file be easier?
    • This script is probably invoked by cron, a "--silent" switch would be nice.
    • $sdate (and others) will be in this format: 27-7-5, while "2005-07-27" probably makes more sense to international users.
    • Script dies when target start date has not been reached yet. This is a Bad Thing™ for other %users. next would be nicer in the foreach loop.

    PS: isn't a BASH script easier for such tasks? ;)

    --
    b10m

    All code is usually tested, but rarely trusted.
      • I don't know how else to do it (yet). (File::Copy?)
      • Leftover from the first design. It changed a lot... should be changed, I agree.
      • It's in my to-do, but thanks for the thought :)
      • That has crossed my mind too :)
      • I've been doubting that, yeah. I didn't think anyone else will use this, so I just left it this way.
      • It does? That's a bug. Thanks!

      Re: PS: As I said, it's for the exercise. If I don't code, I won't improve. Plus I wanted to make a shell script first, asked in the CB, and got asked why I didn't make a Perl script ;)

      All in all, thanks for the help.
        b10m:
        You use system() to copy a file. Not very Perl'ish ;)
        Detonite:
        I don't know how else to do it (yet). (File::Copy?)

        That would work.

        b10m:
        $sdate (and others) will be in this format: 27-7-5, while "2005-07-27" probably makes more sense to international users.
        Detonite:
        I've been doubting that, yeah. I didn't think anyone else will use this, so I just left it this way.

        First of all, you post it here, so someone might be using it already. Secondly, you seem to use that information also in your reply emails (s/_DATE_FROM_/$sdate/g;) - and those might reach other mailboxes besides yours ;)

        b10m:
        Script dies when target start date has not been reached yet.
        Detonite:
        It does? That's a bug. Thanks!

        Before you updated the node, it said "die("...") if($sdate ne $cdate)", so yes, it will die ;) Instead of die'ing, you might want to print just errors, so when something fails, cron will notify you. (See the --silent option I suggested before).

        Detonite
        As I said, it's for the exercise. If I don't code, I won't improve. Plus I wanted to make a shell script first, asked in the CB, and got asked why I didn't make a Perl script ;)

        True, it's good excercise, yet Perl isn't always the right tool ;)

        --
        b10m

        All code is usually tested, but rarely trusted.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://478541]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2024-04-16 07:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found