Go Back   CodingForums.com > :: Server side development > Perl/ CGI

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 12-07-2008, 06:45 AM   PM User | #1
metaphorever
New to the CF scene

 
Join Date: Dec 2008
Posts: 6
Thanks: 1
Thanked 0 Times in 0 Posts
metaphorever is an unknown quantity at this point
Question Random Image Perl Script

I am using the random image perl script from
http://scripts.anolecomputer.com/random_image/

I want to display multiple random images on a single page, but when I call the script multiple times the same image shows up for all of them. I can work around this by duplicating the images over several directories, but this is inefficient and isn't cache friendly.

Any ideas how to change how I call the random_image.cgi so that it will give me different images on the same page?
metaphorever is offline   Reply With Quote
Old 12-07-2008, 04:23 PM   PM User | #2
FishMonger
Super Moderator


 
Join Date: May 2005
Location: Southern tip of Silicon Valley
Posts: 2,753
Thanks: 2
Thanked 149 Times in 144 Posts
FishMonger will become famous soon enoughFishMonger will become famous soon enough
How you're calling random_image.cgi via an img tag, an ssi include, or by some other method?

Can you show us your code that calls random_image.cgi?

There are several issues I have with that script, which we can go over if you wish, but first I'd like to see how you're calling it.

Edit:
I forgot one question.

If it always returns the same image each time it's called, have you checked how many files are in the @allfiles array and which array index it's coming up with in this statement?
Code:
my $img_file = $allfiles[int rand $nlines];

Last edited by FishMonger; 12-07-2008 at 05:34 PM..
FishMonger is offline   Reply With Quote
Old 12-07-2008, 05:25 PM   PM User | #3
metaphorever
New to the CF scene

 
Join Date: Dec 2008
Posts: 6
Thanks: 1
Thanked 0 Times in 0 Posts
metaphorever is an unknown quantity at this point
Smile

Right now I'm using the img tag so:

<img src="../demo/random_image.cgi?path=frame1" alt="alt text">
<img src="../demo/random_image.cgi?path=frame2" alt="alt text">
<img src="../demo/random_image.cgi?path=frame3" alt="alt text">
<img src="../demo/random_image.cgi?path=frame4" alt="alt text">

where I have 4 frame directories which all have the same images duplicated in all four dirs. This does what I want, in a clunky way, but I want it to be able to call all the images from the same place.

I hope that explains it well enough, this is my first time working with perl.
you can see what I've got right now, live at
http://www.cloverpatchwork.com/search/ (NSFW stick figures)
metaphorever is offline   Reply With Quote
Old 12-07-2008, 06:05 PM   PM User | #4
FishMonger
Super Moderator


 
Join Date: May 2005
Location: Southern tip of Silicon Valley
Posts: 2,753
Thanks: 2
Thanked 149 Times in 144 Posts
FishMonger will become famous soon enoughFishMonger will become famous soon enough
I don't have time to fix all of the problems with that script, but see if this works better. (I've added another module which you may need to install).

Code:
#!/usr/local/bin/perl -T
# DON"T FORGET TO SET THE PATH!
#
##############################################################################
# Random Image: A random image display script
# Copyright (C) 2005 Larry Boyd
# random_image@anolecomputer.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################
# random_image 2.1

$|= 1;
use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);
use strict;
use warnings;
use List::Util qw/shuffle/;


#################
# Configuration #
#################

# absolute path to your starting point only directories below this can be used
my $base_path = "/path/to/your/images/";

# base URL to your images. DON'T put the trailing "/"
my $image_url = "/images";

###################
## error messages #
###################

## Error Code 1: Missing directory
my $e1 = "<center><b>Error code: 1<p>I'm sorry, but I am unable to complete your request. Please contact the page administrator and provide the error code listed above.</b></center>";

## Error Code 2: Someone tried to use a / or .. in the start of a $path or $directory var
my $e2 = "<center><b>Error code: 2<p>I'm sorry, but I am unable to complete your request. Please contact the page administrator and provide the error code listed above.</b></center>";

##############
# here we go #
##############

my $method = param('method');
my $path = param('path');
my $alt_txt = param('alt_txt');
my $link = param('link');

# let's do some checks on the the supplied path to make sure
# someone doesn't try to do anything tricky

# make sure the parameters are there so the default directories don't get shown
if (!$path) {
	&print_error($e1);
} # end if

# check to see if  $path starts with a / or \ and error if they do
if ($path =~ /^\//) {
	&print_error($e2);
} # end if
if ($path =~ /^\\/) {
	&print_error($e2);
} # end if

# make sure we don't allow any tricky stuff using ".." or "."
if ((index $path, "..") != -1) {
	&print_error($e2);
} # end if

if ((index $path, ".") != -1) {
	&print_error($e2);
} # end if

my $file_dir = $base_path . "$path/";

# open the directory and output the files
opendir(FILES, $file_dir) or die "Couldn't open directory $file_dir for reading!";

my $image_filter = qr/[.](gif|jpeg|jpg|png|bmp|tiff|tif)$/;
my @allfiles = grep { /$image_filter/ } readdir(FILES);

closedir(FILES);
my $img_file = (shuffle @allfiles)[0];


if ($method eq 'ssi') {
	if (!$link) {
		print "Content-type: text/html \n\n";
		print "<img src=\"$image_url\/$path\/$img_file\" alt=\"$alt_txt\" border=\"0\">";
	} # end if
	else {
		print "Content-type: text/html \n\n";
		print "<a href=\"$link\"><img src=\"$image_url\/$path\/$img_file\" alt=\"$alt_txt\" border=\"0\"></a>";
	} # end else
	exit;
} # end if

else {
	my %img_type = ("jpg","jpeg",  "jpeg","jpeg",  "gif","gif",  "png","png", "bmp","bmp", "tif","tiff", "tiff","tiff");
	my $ext = '';

	($ext) = $img_file =~ /\.([^.]+)$/;
	$ext = lc($ext);
	my $type = $img_type{"$ext"};

	open IMG, "$file_dir/$img_file"
		or die qq(Image "$file_dir/$img_file" not found);
	binmode IMG;
	undef $/;
	my $img = <IMG>;
	close IMG;
	print "Content-Type: image/$type\r\n\r\n";
	binmode STDOUT;
	print STDOUT $img;
} # end else


###################################################################################
# print_error: subroutine to output error messages. Useful for debugging as well. #
###################################################################################
sub print_error	{
my $error = shift;
print "content-type: text/html \n\n";
print "<b>$error</b><br>";
exit(0);
} # end sub print_error
FishMonger is offline   Reply With Quote
Old 12-07-2008, 07:10 PM   PM User | #5
metaphorever
New to the CF scene

 
Join Date: Dec 2008
Posts: 6
Thanks: 1
Thanked 0 Times in 0 Posts
metaphorever is an unknown quantity at this point
Okay, I think I may have explained my problem wrong; the script works OK, I can call for images and each time I call it it gives me a new image. My problem is I want to call the script multiple times in a single page.

The modified script you gave me is at
http://cloverpatchwork.com/search/new.cgi?path=clover1

An example page calling it
http://cloverpatchwork.com/search/search.shtml
I want to find a way to call the script multiple times in a page, so in the first part of that page I use:
Code:
<img src="../search/new.cgi?path=clover1" alt="Frame 1">
<img src="../search/new.cgi?path=clover1" alt="Frame 2">
but it just calls the script once and both the img are the same image. I can use calls to different directories to get different images to show:
Code:
<img src="../search/new.cgi?path=clover1" alt="Frame 1">
<img src="../search/new.cgi?path=clover2" alt="Frame 2">
but this is very inefficient if I want to have lots of images.

Any ideas for calling the cgi multiple times in a single page?
Thanks for being so helpful.
metaphorever is offline   Reply With Quote
Old 12-07-2008, 08:29 PM   PM User | #6
KevinADC
Senior Coder

 
Join Date: Mar 2006
Posts: 1,274
Thanks: 2
Thanked 39 Times in 38 Posts
KevinADC is on a distinguished road
Then you need to use a totally different approach. You need the script to produce the html code that displays the images as well assign a random image. The script you have is not designed to do that.
KevinADC is offline   Reply With Quote
Old 12-08-2008, 06:58 AM   PM User | #7
metaphorever
New to the CF scene

 
Join Date: Dec 2008
Posts: 6
Thanks: 1
Thanked 0 Times in 0 Posts
metaphorever is an unknown quantity at this point
Thumbs up

You're right Kevin. I looked into printing html and came up with this
http://www.cloverpatchwork.com/search/search.cgi
Code:
#!/usr/bin/perl

#$|= 1;
#use CGI qw(:standard);
#use CGI::Carp qw(fatalsToBrowser);
#use strict;
#use vars qw(%img_type);

#################
# Configuration #
#################

# absolute path to your starting point only directories below this can be used
my $base_path = "/home/metaphorever/public_html/clover/search/"; 

# base URL to your images. DON'T put the trailing "/"
my $image_url = "clover1";

my $file_dir = $base_path . "$image_url/";

# open the directory and output the files
opendir(FILES,"$file_dir") or die "Couldn't open directory $file_dir for reading!";
my @allfiles = grep(!/^\.\.?$/,readdir(FILES));
srand();                        
closedir(FILES);

#########Print###########


print "Content-type: text/html\n\n";
print <<HTML;
<html>
<head>
<title>clover search</title>
<body bgcolor="#000">
</head>
<body>
HTML

my $range = 20;
my $random_number = rand($range);
my $remainder = 20-$random_number;

for ($count = $random_number; $count >= 1; $count--) {
my $nlines=@allfiles;         
my $file = int(rand(@ls));
my $img_file = $allfiles[int rand $nlines];

print <<HTML;
<img src="http://www.cloverpatchwork.com/search/clover1/$img_file" alt="a clover">
HTML
}

print <<HTML;
<img src="http://www.cloverpatchwork.com/search/clover2/01.jpg" alt="a clover">
HTML

for ($count = $remainder; $count >= 1; $count--) {
my $nlines=@allfiles;         
my $file = int(rand(@ls));
my $img_file = $allfiles[int rand $nlines];

print <<HTML;
<img src="http://www.cloverpatchwork.com/search/clover1/$img_file" alt="a clover">
HTML
}


print <<HTML;
</body>
HTML
exit;
I think the space around the images comes from the line breaks in between images in the generated html, how can I get rid of them? And how would I go about changing the $range to be whatever was called from the url as in /search.cgi?20

Any feedback would be wonderful. Thank you for your time
metaphorever is offline   Reply With Quote
Old 12-08-2008, 07:06 PM   PM User | #8
KevinADC
Senior Coder

 
Join Date: Mar 2006
Posts: 1,274
Thanks: 2
Thanked 39 Times in 38 Posts
KevinADC is on a distinguished road
everywhere you print an image change the code to :

print qq{<img src="http://www.cloverpatchwork.com/search/clover1/$img_file" alt="a clover">};

that should get rid of the space between images that your heredoc blocks are introducing. In the html source code you want to see all the image tags strung together instead of on seperate lines or with any space between them.

<img><img><img>

what you have right now is:

<img>
<img>
<img>

which is adding a space bwteeen each image
KevinADC is offline   Reply With Quote
Users who have thanked KevinADC for this post:
metaphorever (12-08-2008)
Old 12-08-2008, 07:10 PM   PM User | #9
KevinADC
Senior Coder

 
Join Date: Mar 2006
Posts: 1,274
Thanks: 2
Thanked 39 Times in 38 Posts
KevinADC is on a distinguished road
To use the range in your script:

Code:
use CGI qw(:standard);
my $range = param('r') || 20; #<- 20 is a default range if none is submitted
#here you should filter and validate that $range is what your  script expects
and change the URI to:

Code:
/search.cgi?r=15
KevinADC is offline   Reply With Quote
Old 12-08-2008, 09:03 PM   PM User | #10
metaphorever
New to the CF scene

 
Join Date: Dec 2008
Posts: 6
Thanks: 1
Thanked 0 Times in 0 Posts
metaphorever is an unknown quantity at this point
Thanks so much Kevin, you've been very helpful. Hopefully I can work out the rest on my own.
metaphorever is offline   Reply With Quote
Old 12-08-2008, 09:31 PM   PM User | #11
KevinADC
Senior Coder

 
Join Date: Mar 2006
Posts: 1,274
Thanks: 2
Thanked 39 Times in 38 Posts
KevinADC is on a distinguished road
You're welcome, post back if you get stuck.
KevinADC is offline   Reply With Quote
Old 12-10-2008, 06:21 AM   PM User | #12
metaphorever
New to the CF scene

 
Join Date: Dec 2008
Posts: 6
Thanks: 1
Thanked 0 Times in 0 Posts
metaphorever is an unknown quantity at this point
Here's the finished page, if you are interested, every time you find (click) the four-leaf clover it reshuffles and adds another row of clovers.

http://www.cloverpatchwork.com/search/
metaphorever is offline   Reply With Quote
Old 12-10-2008, 10:09 PM   PM User | #13
KevinADC
Senior Coder

 
Join Date: Mar 2006
Posts: 1,274
Thanks: 2
Thanked 39 Times in 38 Posts
KevinADC is on a distinguished road
Cool...
KevinADC is offline   Reply With Quote
Reply

Bookmarks

Tags
cgi, image, perl, random

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 12:55 PM.


Advertisement
Log in to turn off these ads.