homepage Welcome to WebmasterWorld Guest from 54.226.0.225
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
Forum Library, Charter, Moderators: coopster & jatar k & phranque

Perl Server Side CGI Scripting Forum

    
Script to change image at certain time of day
smarsh




msg:3359703
 4:56 am on Jun 6, 2007 (gmt 0)

Hi,

I've installed plenty of Perl scripts but can't write them - even simple ones like this probably is...

I'm looking for a server side script that looks at the current time and day of week and loads one of two images. The idea is that for a different hour each day the site owner takes calls, so one graphic will say to "call now" the other "sorry phones are closed". For example: Monday 9:00 - 10:00, Tuesday 10:00 - 11:00, etc. He has a seven day schedule that is the same week to week. Ideally, the "phones closed" image will also load some javascript to pop open a window with the weekly schedule.

Short of the javascript twist, I know there's not much challenge for a Perl programmer, but all the scripts I've come across don't quite do it.

Anyone know of a script to accomplish this and if it can have the javascript twist added to it?

Thanks guys!

 

lexipixel




msg:3360831
 6:17 am on Jun 7, 2007 (gmt 0)

...easiest to work with 'seconds since midnight' for all values, (so you don't have to do a lot of programming to check hours, minutes, seconds, etc).

8:30am = 30600, (or 60 x 60 x 8.5)
8:35am = 30900, (or 60 x 60 x 8) + (60 x 35)
5:30pm = 63000, (or 60 x 60 x 17.5)
8:30pm = 73800, (or 60 x 60 x 20.5)
12noon = 43200, (or 60 x 60 x 12)

Here's a quick and dirty approach. (You would need to use SSI and include this file into the page where you want the "Phone On" or "Phone Off" image to appear).

#!/usr/local/bin/perl
#
# set the time for phone to be 'ON' and 'OFF' below
#
$phoneon = '30600';
$phoneoff = '63000';
#
# edit the names of the images to use below
#
$image1 = "phone-on.gif";
$image2 = "phone-off.gif";
#
#
$image = $image2;
($h,$m) = (localtime)[2,1];
$t = ($h * 3600) + ($m * 60);
if (($t > $phoneon) && ($t < $phoneoff)) {
$image = $image1;
}
#
print "Content-type: text/html\n\n";
print "<img src=\"$image\"><br>\n";
#
# end

You can build the script to handle different days and times using the values from localtime[] returned values.

# =================================================================
# localtime
# =================================================================
# # Variable Values Range
# =================================================================
# 0 $sec seconds 0-60
# 1 $min minutes 0-59
# 2 $hours hours 0-23
# 3 $mday day of month 1-31
# 4 $month month of year 0-11, 0 == January
# 5 $year years since 1900 1-138 (or more)
# 6 $wday day of week 0-6, 0 == Sunday
# 7 $yday day of year 1-366
# 8 $isdst 0 or 1 1 if daylight savings in effect
# =================================================================
# usage: ($var,$var,$var) = (localtime)[#,#,#];
# =================================================================
#

perl_diver




msg:3363766
 9:07 pm on Jun 10, 2007 (gmt 0)

another possible way:

use strict;
use warnings;
# time in military format 0-23
# first number is opening time
# second number is closing time
# 24-24 indicates always closed
my %schedule = (
Sun => [24,24],
Mon => [9,10],
Tue => [10,11],
Wed => [9,11],
Thu => [8,10],
Fri => [13,15],
Sat => [24,24]
);

# default value
my $image = 'closed.gif';

# get the day and hour
my ($day, $hour) = (split(/ /,scalar localtime))[0,3];
$hour = (split(/:/,$hour))[0];

# check the day and hour
if ($schedule{$day}[0] <= $hour && $schedule{$day}[1] >= $hour) {
$image = 'open.gif';
}

# print the image
print "<img src='$image'>";


smarsh




msg:3365952
 1:58 am on Jun 13, 2007 (gmt 0)

I guess I know less than I thought. I've tried to use these scripts but can't make them work. Do they need to be completed, or do they get embedded, or what am I missing? Any help is appreciated!

perl_diver




msg:3366036
 5:34 am on Jun 13, 2007 (gmt 0)

With the script I posted you could just call the script from the image tag on the page it will be displayed. Say you have an html document, where you want the open/closed image to display you put an image tag like so:

<img src="cgi-bin/phone.pl" width="50" height="50" alt="image of a phone">

the phone.pl script:



#!/usr/bin/perl
use strict;
use warnings;

# path to folder where images are
# assumes an image named open.gif and closed.gif
my $path = '/home/yoursite/images/';

# time in military format 0-23
# first number is opening time
# second number is closing time
# 24-24 indicates always closed
my %schedule = (
Sun => [24,24],
Mon => [9,10],
Tue => [10,11],
Wed => [9,11],
Thu => [8,10],
Fri => [13,15],
Sat => [24,24]
);

# default value
my $image = 'closed.gif';

# get the day and hour
my ($day, $hour) = (split(/ /,scalar localtime))[0,3];
$hour = (split(/:/,$hour))[0];

# check the day and hour
if ($schedule{$day}[0] <= $hour && $schedule{$day}[1] >= $hour) {
$image = 'open.gif';
}

#print appropriate MIME type header
print "Content-type: image/gif\n\n";

open(FH,"$path$image") or die "$!";
binmode(FH);
print while (<FH>);
close(FH);
exit;

as far as the javascript pop-up with a calendar goes I would forget about that because pop-up blockers will just block it. Have a link the user can click on if they want to see a calendar.

smarsh




msg:3367054
 4:00 am on Jun 14, 2007 (gmt 0)

It seems that the more I do... the less I know!

I've now tried the version from perl_diver and I can't get that to work. I changed the path to perl to #/usr/bin/perl I changed the path to the images to my $path = '../images/'; I set the script to 755. The html page is in the root level. File names are all lower case. I set the image names and put them in the images folder and still it doesn't work! Anyone know what I'm doing wrong?

I'm assuming the path to the images is relative to the script and not to the page calling them right? That would mean from the cgi-bin it would have to hop up one level to the root and then into the images folder as I have it right?

Thanks guys!

perl_diver




msg:3367164
 7:11 am on Jun 14, 2007 (gmt 0)

Use the full path to the folder where the image is:

$path = 'path/from/root/images/';

if that works, try messing around with the relative path:

$path = '../images/';

that path is relative to where the script is. Check your server error logs if possible too.

perl_diver




msg:3367168
 7:23 am on Jun 14, 2007 (gmt 0)

I tested the script I posted and it seems to work OK for me.

lexipixel




msg:3368074
 12:10 am on Jun 15, 2007 (gmt 0)

If neither worked, most likely the server isn't setup to handle SSI, (server side includes)...

You may need to add the following to your .htaccess file (or create an .htaccess file if one does not exist).

AddType text/html .shtml
AddHandler server-parsed .htm
AddHandler server-parsed .html
AddHandler server-parsed .shtml
Options Indexes FollowSymLinks Includes

perl_diver




msg:3368104
 1:21 am on Jun 15, 2007 (gmt 0)

The script I posted does not use SSI. The script is called in the image tag from a regular html page but it would still work on an SSI (shtml) page.

smarsh




msg:3368160
 3:16 am on Jun 15, 2007 (gmt 0)

Thanks guys for all the input! SSI is enabled but I'm calling the script from the cgi-bin. I changed the path to the root path and still NG. Checking the error logs it says "Premature end of script headers:"

Is that a clue to anything?

perl_diver




msg:3368268
 6:22 am on Jun 15, 2007 (gmt 0)

that usually means the script is trying to print something before an http header has been printed. Add this line to the beginning of the script:

use CGI::Carp qw/fatalsToBrowser/;

then run the script directly from the url of the script:

http://www.example.com/cgi-bin/phone.pl

and see what happens.

You can see the script in action here:

that is the script I posted called directly from the URL of the script but it would work the same if called from an <img> tag in an html document:

<img src="cgi-bin/phone.pl">

My guess is that your script is "dieing" here:

open(FH,"$path$image") or die "$!";

and trying to print the error message contained in $!

[edited by: jatar_k at 12:46 pm (utc) on June 15, 2007]
[edit reason] sorry no urls thanks [/edit]

perl_diver




msg:3369777
 12:23 am on Jun 17, 2007 (gmt 0)

smarsh,

did you get it working yet? I see the link I posted was removed as expected by the moderator, I was hoping you would get a look at it before it was removed. If you need further help you can PM me (or sticky mail as they call it here).

perl_diver




msg:3370344
 6:59 pm on Jun 17, 2007 (gmt 0)

smarsh,

check your sticky mail

smarsh




msg:3370376
 7:57 pm on Jun 17, 2007 (gmt 0)

You got it man! Thanks soooooooooo much. The path mistake with spia and fireplug was simply my sloppiness when I moved the script from one URL to another. All other issues were my misunderstanding. I have read the script a number of times to at least try and follow the logic, but that will never make up for not knowing how to use the language. I always knew that I was the problem, I just didn't know where...

To prove I can follow the basic logic, am I right in believing that any matching time would work as the "closed time" and not just 24,24 such as 03,03?

Not that I need it, but so I can understand more: it seems to me that if the script had to be changed to work with minutes like open 11:30 - 4:45, it wouldn't take much to do it other than adding a function to get minutes too, right?

perl_diver




msg:3370419
 9:35 pm on Jun 17, 2007 (gmt 0)

03,03 will not be the same as 24,24. There will be 59 minutes where two matching times, such as 03,03 will return "open". You can "see" how this works:


Mon => [10,10],

Monday hours (above) are 10 AM to 10 AM (10 to 10).
We check time (below) and the hour is 10.


# default value
my $image = 'closed.gif';

# get the day and hour
my ($day, $hour) = (split(/ /,scalar localtime))[0,3];
$hour = (split(/:/,$hour))[0];

Now check to see if we are in the open/closed range:


# check the day and hour
if ($schedule{$day}[0] <= $hour && $schedule{$day}[1] >= $hour) {
$image = 'open.gif';
}

it will look like this:


if (10 <= 10 && 10 >= 10) {

which translates to:


if 10 is equal or less than 10 and 10 is equal or greater than 10

which is true because 10 is "equal" to 10 on both sides of the "and" operator. So for 59 minutes and 59 seconds the hours of 10,10 will display as "open". I used 24,24 because the return value of "localtime" will never be 24. So one side or the other of the line that checks the time range will always be false and "open" will never be returned. I hope that makes sense.

perl_diver




msg:3370420
 9:37 pm on Jun 17, 2007 (gmt 0)


Not that I need it, but so I can understand more: it seems to me that if the script had to be changed to work with minutes like open 11:30 - 4:45, it wouldn't take much to do it other than adding a function to get minutes too, right?

Thats right, you would just need to add in the minutes. It would not be hard.

smarsh




msg:3371032
 1:29 pm on Jun 18, 2007 (gmt 0)

Thanks again! I see what you are saying about the 24 and why my thought won't work.

perl_diver




msg:3371043
 1:52 pm on Jun 18, 2007 (gmt 0)

OK, you're welcome.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved