I kept forgetting to send our club meeting notices to the newsletter. Google Calendar couldn't help me, so I wrote this script.
I help run a monthly Computer Club meeting in our community. The club actually meets twice per month, once for a general meeting and once to offer troubleshooting services to members of the community.
I keep forgetting to put meeting notices in our community newsletter.
That sounds like a job for a calendar program, doesn't it? Yeah, that's what I thought too, so I fired up Google Calendar and added the two dates for the first Monday and the first Wednesday of every month. So far, so good and now all I had to do was to tell it to remind me at an appropriate time.
Unfortunately, I ran into an immediate problem. I need to get notices to the newsletter editor very early. If I want something to be in the December newsletter, I need to send it in before the first of November. Google Calendar won't let you set a reminder more than one month earlier than an event. If I try to set it for 5 weeks or 32 days, it won't allow that. That's dumb, but there it is: Google doesn't think you'd ever need more than 4 weeks advance notice for anything.
So, I turned to Perl.
There are many ways to approach this in Perl. You could take a brute force approach, setting the date to December 1st, testing to see if that is a Monday and incrementing to December 2d and beyond if it is not. That's actually not such a terrible way to do it as the date we want has to be before the 8th, so there cannot be many iterations.
#!/usr/bin/perl use Time::Local; ($day,$month,$year)=(localtime)[3,4,5]; $month+=2; if ($month > 11) { $month=0; $year++; } $nextmonth=timelocal(0,0,0,1,$month,$year); $dow=(localtime $nextmonth)[6]; while ($dow != 1) { $nextmonth+=24 * 60 * 60; $dow=(localtime $nextmonth)[6]; } print scalar localtime $nextmonth, "\n";;
If you ran that on the 28th of each month, you'd have the first Monday of the 2d month following. Add some code to send email and you are done.
I decided to use Date::Calc instead. It's probably no faster (it might even be slower) and it very likely uses a brute force approach itself, but it has a lot of useful functions (68, in fact) beyond just what we need to do here.
Installing Date::Calc is, however, a somewhat lengthy procedure. It's a lot of code with a whole army of dependencies and it will keep CPAN busy for quite a little while. It will be worth it, though, as our code becomes as simple as:
($year,$month,$day) = Today(); ($year,$month,$day) = Add_Delta_YMD($year,$month,$day, 0,2,0); $monday=Nth_Weekday_of_Month_Year($year,$month,1,1);
We just need to wrap that up in some formatting and we're ready to put it in crontab:
10 6 28 * * /mybin/remindme 2>&1 > /dev/null
I'll run it on the 28th of each month and it will send me a reminder email that is ready for any last many editing before being forwarded along to the newsletter.
#!/usr/bin/perl # "remindme" Tony Lawrence October 2012 # I'm going to run this on the 28th of the month # I want to know the first Monday and First Wednesday of TWO months ahead # use Date::Calc qw( Today Date_to_Days Add_Delta_YMD Decode_Date_US Nth_Weekday_of_Month_Year ); @day=("1st","2d","3rd","4th","5th","6th","7th"); @months=("January","February", "March", "April", "May", "June", "July", "August", "September", "October", "November","December"); ($year,$month,$day) = Today(); ($year,$month,$day) = Add_Delta_YMD($year,$month,$day, 0,2,0); $monday=Nth_Weekday_of_Month_Year($year,$month,1,1); $monday=~ s/$year$month//; $wednesday=Nth_Weekday_of_Month_Year($year,$month,3,1); $wednesday=~ s/$year$month//; open(SENT,"|/opt/kerio/mailserver/sendmail tony\@aplawrence.com"); print SENT <<EOF; Mime-Version: 1.0 Content-Type: text/html Content-Transfer-Encoding: 8BIT From: tony\@aplawrence.com Subject: Computer club schedule for $months[$month-1] $year <h2>Oak Point Computer Club $months[$month-1] $year</h2> <p>The Oak Point Computer Club meets on the first Monday and the first Wednesday of every month.</p> <ul> <li>The Monday $months[$month-1] $day[$monday-1] meeting is at 2:00 PM in the Back Ballroom.</li> <li>The Wednesday $months[$month-1] $day[$wednesday-1] meeting is at 5:00 PM in the Back Ballroom.</li> </ul> <p>Wednesday is Troubleshooting. Bring us your problems and questions and we will try to help. First come, first served.</p> <p>Monday is usually a lecture or informal discussion on some subject.</p> <p><b>Not just for computer geeks!</b></p> <p>All Oak Point homeowners are welcome; there are no dues or charges of any kind.</p> EOF exit 0;
This is the result:
That should help me get my notices to the newsletter on time.
Got something to add? Send me email.
More Articles by Anthony Lawrence © 2012-10-20 Anthony Lawrence
Tough times never last, but tough people do. (Robert H. Schuller)
Printer Friendly Version
Early reminders for first Monday of month events Copyright © October 2012 Tony Lawrence
Have you tried Searching this site?
This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more.
Contact us
Printer Friendly Version