CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
loops, parsing and 500 errors

 



inlimbo
User

Nov 19, 2004, 7:28 AM

Post #1 of 15 (4539 views)
loops, parsing and 500 errors Can't Post

ok i have a script for shrinking the size of images from a database using Image::Magick but I keep getting 500 errors. What am I doing wrong. I thik it has to do with the loop or the parsing in of the information into the subroutine.

Cheers
inlimbo...

#!/usr/bin/perl -wT
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use Image::Magick;

print header;
print start_html("Image Magick");


&ProcessImages("../../myimages/", "database.txt");

#below is the problem i think
foreach my $i (@out) {
print <<HTML;
<IMG SRC="$i">
HTML
}


sub ProcessImages
{
my ($dir, $filename) = @_;
my @out;
open INPUT, $filename or die "Couldn't open $filename";
while (<INPUT>)
{
chomp;
my @data = split "|";
my $imgfile = $data[2];

my $img = new Image::Magick(size=>"50x50");
if ($img->Read($dir . $imgfile))
{
$img->Resize(geometry=>"50x50");
$imgfile =~ s/.jpg$/.50x50.jpg/;
$img->Write($dir . $imgfile);
push @out, $imgfile;
}
}
close INPUT;
return @out;
}


KevinR
Veteran


Nov 19, 2004, 3:52 PM

Post #2 of 15 (4529 views)
Re: [inlimbo] loops, parsing and 500 errors [In reply to] Can't Post

if that script is not printing a detailed error message to the screen , the only things I can think of are the path to perl (the very first line) is wrong or the file is uploaded in binary instead of ASCII (text) mode.
-------------------------------------------------


inlimbo
User

Nov 21, 2004, 5:03 PM

Post #3 of 15 (4519 views)
Re: [KevinR] loops, parsing and 500 errors [In reply to] Can't Post

Thanks kevin.The path to perl is correct and i have uploaded it in ASCII. The only thing I can think is the problem is the path to the various files. The path to the database.txt file seems to work, because if i change its name to something else (i.e. datbase2.txt) I do get a detailed error message telling me that it cant find the database. So maybe its the path to images directory - "../../myimages/". I have contacted my server admin about this.

So there is no errors in the code?

Cheers
Mark


KevinR
Veteran


Nov 21, 2004, 8:48 PM

Post #4 of 15 (4518 views)
Re: [inlimbo] loops, parsing and 500 errors [In reply to] Can't Post

I'm not too familiar with Image::Magick, but the code looks error free to me.
-------------------------------------------------


davorg
Thaumaturge / Moderator

Nov 22, 2004, 1:50 AM

Post #5 of 15 (4513 views)
Re: [inlimbo] loops, parsing and 500 errors [In reply to] Can't Post

Have you looked in the web server error log? Have you tried running the program from the command line?

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


rork
User

Feb 10, 2005, 5:02 AM

Post #6 of 15 (4448 views)
Re: [inlimbo] loops, parsing and 500 errors [In reply to] Can't Post

The only place where you can get 500 Errors is while reading the text file. The foreach-loop is OK unless your server doesn't support in here documents.

The only problem in the while loop I can find is that you might use a bad reference to your images directory.

If your server uses an alias for your scripts directory ../ doesn't work the same with perl as with HTML.

I recommand you ask your serveradmin if they use an alias for the directory your script and images are in.
--
Don't reinvent the wheel, use it, abuse it or hack it.


davorg
Thaumaturge / Moderator

Feb 14, 2005, 2:11 AM

Post #7 of 15 (4422 views)
Re: [inlimbo] loops, parsing and 500 errors [In reply to] Can't Post

Looking more closely at your code I can see at least one major problem.

Within the "ProcessImages" subroutine you define a lexical variable called @out which you populate with the names of image files.

You return @out from your subroutine, but when you call this subroutine you ignore any return values. As the lexical @out variable goes out of scope when you exit the subroutine, you cannot access the values in this array outside of the subroutine.

Therefore, when you try to access the contents of @out outside the subroutine, you aren't accessing your lexical variable, but instead you're accessing a package variable of the same name which has no data in it.

This is a good example of why you should always (yes, _always_) use the "use strict" pragma" when writing code. This would have told you that you were trying to access a non-existant variable.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


davorg
Thaumaturge / Moderator

Feb 14, 2005, 2:14 AM

Post #8 of 15 (4421 views)
Re: [rork] loops, parsing and 500 errors [In reply to] Can't Post


In Reply To
The only place where you can get 500 Errors is while reading the text file.


Can you explain that a bit more for me please. I'm under the impression that there are any number of situations that can cause a 500 error - not just when reading a text file. Perhaps I have muisunderstood you.


In Reply To
The foreach-loop is OK unless your server doesn't support in here documents.


I don't think it's your web server that needs to support heredocs, but your version of Perl. And as they've been in Perl for as long as I can remember I'd be very surprised if anyone is using a version that doesn't support them.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


inlimbo
User

Feb 14, 2005, 2:33 AM

Post #9 of 15 (4417 views)
Re: [davorg] loops, parsing and 500 errors [In reply to] Can't Post

Thanks davorg. Could u show what my code should look like. Im not sure exactly how it works so i dont quite follow what you have said.

My bad, i know I should use strict.

I posted this question months ago and i am still having problems with it. My server admin aren't particulary helpful - i think i know about it than they do! If u could help I would be most appreciative.

Before i think u suggested that it might be a path issue. I have tried all combinations of paths to no avail. I do know the correct path to files and directories as I have been using .htaccess for a while with no problems.

Ive never had problems with foreach loops before. As far as I am aware my server uses the msot recent version of Perl - so there shouldn't be any issues there.

Cheers
inlimbo


davorg
Thaumaturge / Moderator

Feb 14, 2005, 2:46 AM

Post #10 of 15 (4415 views)
Re: [inlimbo] loops, parsing and 500 errors [In reply to] Can't Post

We're all only really guessing what the problem is. The problem I mentioned will stop your program working correctly, but it probably won't cause the 500 errors that you are seeing.

As I said in my first post on this discussion, we really need to see what's in the web server error logs before we can make any reasonable attempt to solve the problem.

You can't solve a problem if you don't know what it is :)

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


rork
User

Feb 14, 2005, 9:37 AM

Post #11 of 15 (4411 views)
Re: [inlimbo] loops, parsing and 500 errors [In reply to] Can't Post

Sort of glad that you still have the problem, now I feel less bad for the topic kick. But it would be better if you had solved the problem.

First the Here documents. My hosting provider doesn't support here documents for as far as I know. But I'm not sure it is the server or perl version.

Something in such a small script generating 500 errors is probably a loop. I can't think about anything else. There are 2 loops


Code
foreach my $i (@out) { 
print <<HTML;
<IMG SRC="$i">
HTML
}

Which we all agree on is right. What can be wrong?
You might want to try: print "<IMG SRC = '$i'>";

The next loop is while reading the file:

Code
while (<INPUT>) 
{
chomp; #ok
my @data = split "|"; #ok?
my $imgfile = $data[2]; # min length @data = 3?

my $img = new Image::Magick(size=>"50x50"); #ok
if ($img->Read($dir . $imgfile))
# $dir . $imagefile must exist absolute.
{
$img->Resize(geometry=>"50x50"); #ok
$imgfile =~ s/.jpg$/.50x50.jpg/; #ok
$img->Write($dir . $imgfile); #ok
push @out, $imgfile; #ok
}
}


So here should be a mistake. That is what I meant with "While reading the file" Off course here are some chances for errors.

This suggest 3 questions:
1. The split function.
perlfunc says split /PATTERN/ but maybe "PATTERN" is also right. Then | is a metacharacter \| should work. (This is how I would write it: "my @data = split /\|/;" But I'm not sure your way is wrong)
2. How does a line of database.txt look like. And how many files are in it?
3. Is the path ../../myimages correct? You say it is.

I just remembered something else. Do you mean you get 500 errors or just one "500 - Internal Server Error" From your title I thought you were getting 500 single errors.

If it is a "500 - Internal Server Error" davorg gave you the solution:

Declaring "my @out" outside the subroutine before you call it and thus making it a global variable. (You shouldn't declare @out again within the subroutine and remove "return @ out;").

Or you can write:

my @out = ProcessImages("../../myimages/", "database.txt");
--
Don't reinvent the wheel, use it, abuse it or hack it.

(This post was edited by rork on Feb 14, 2005, 10:10 AM)


davorg
Thaumaturge / Moderator

Feb 15, 2005, 6:06 AM

Post #12 of 15 (4399 views)
Re: [rork] loops, parsing and 500 errors [In reply to] Can't Post


In Reply To
First the Here documents. My hosting provider doesn't support here documents for as far as I know. But I'm not sure it is the server or perl version.


See. When people say that their hosting provider doesn't support heredocs it usually means that they haven't been able to get them to work. and that usually means either that they have whitespace on the line following the strign that ends the heredoc or that they don't have an empty line following a heredoc that is right at the end of their file.


In Reply To
Something in such a small script generating 500 errors is probably a loop. I can't think about anything else.


Oh. I see what you mean. But I really think it's "one 500 error" rather than "500 errors". A 500 error is by far the most likely explaination in a web programming context.


In Reply To
This suggest 3 questions:
1. The split function.
perlfunc says split /PATTERN/ but maybe "PATTERN" is also right. Then | is a metacharacter \| should work. (This is how I would write it: "my @data = split /\|/;" But I'm not sure your way is wrong)


This is one of the major problems. The first argument to "split" is _always_ interpreted as a regex, even when you try to make it look like a string. So, as you say, it should be "split /\|/". Without that, it is splitting the string on _every_ character and $data[2] won't contain what you think it does.


Quote
If it is a "500 - Internal Server Error" davorg gave you the solution:


No. Like I said in my post. My solution will stop the program from working as expected (it won't process any images) but it won't cause an error.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


davorg
Thaumaturge / Moderator

Feb 15, 2005, 6:18 AM

Post #13 of 15 (4398 views)
Re: [inlimbo] loops, parsing and 500 errors [In reply to] Can't Post

Ok. Having taken a longer look at this (and installed ImageMagick so I can try it out), I know what the problems are.

Firstly, your regex that you pass to "split" is wrong. You are splitting each line from your file on _every_ character. This means that $imgfile doesn't end up containing the name of your file. When you try to read the (non-existant) file, ImageMagick throws a fatal error which becomes your 500 error.

Secondly, Image::Magick doesn't seem to work as advertised. It doesn't seem to return a true value if "Read" succeeds in reading an image file. So I've had to remove that check.

And thirdly, as I mentioned before, you have two @out arrays and you're populating the wrong one.

Here's how I'd write your program.


Code
#!/usr/bin/perl -T 

use strict;
use warnings;

use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use Image::Magick;

print header;
print start_html('Image Magick');

my @out = ProcessImages('../myimages/', 'database.txt');

foreach (@out) {
print <<HTML;
<IMG SRC="$_">
HTML
}

sub ProcessImages {
my ($dir, $filename) = @_;
my @out;
open INPUT, $filename or die "Couldn't open $filename: $!\n";
while (<INPUT>) {
chomp;
my $imgfile = (split /\|/)[2];

my $img = Image::Magick->new(size => '50x50');
$img->Read($dir . $imgfile);
$img->Resize(geometry=>"50x50");
$imgfile =~ s/\.jpg$/.50x50.jpg/;
$img->Write($dir . $imgfile);
push @out, $imgfile;
}
close INPUT;
return @out;
}


As I've said before in this discussion, for a lot of the time we were just fumbling around in the dark as we didn't know what the error message was that you were getting. The fatal error from Image::Magick which I mentioned above would have written the error into your web server error log and seeing that error would have saved everyone a great deal of time.

Whenever you get a "500 error" from a CGI program then your first action should be to see what the real error is from the error log. Anything else is just a waste of time.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


inlimbo
User

Feb 15, 2005, 5:56 PM

Post #14 of 15 (4385 views)
Re: [davorg] loops, parsing and 500 errors [In reply to] Can't Post

Woot!!!! Rawk!!!!! It works!!!!

Thanks rork for starting this thread up again! I had put this problem into the "too hard basket". I had searched the internet far and wide to find a solution to no avail.

Thanks very much davorg for solving my problem. I really really appreciate you installing Image:Magick and figuring out what was wrong. People don't praise your work enough in these forums. Thanks very much again.

You have both saved me a lot of time in uploading both small and large versions of images. Its great to know that I can empty out my "too hard basket" for now :)

My bad, i did put up the original error message but it was in another thread (a few months ago) - http://www.perlguru.com/gforum.cgi?post=23033;search_string=image%20magi;guest=1357943#23033

Here is the original error message:

Code
<?xml version="1.0" encoding="iso-8859-1"?>  
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"
xml:lang="en-US"><head><title>Image Magick</title>
[Mon Nov 22 17:27:48 2004] im.cgi: Exception 410: no images to mogrify
(Resize) at /webhome/www.mydomain.com.au/cgi-bin/shoppingcart/im.cgi
line 25, <INPUT> line 1.


I don't have access to the error logs, I can only get them through my server admin which is a teeth-pulling task.

Now i always use strict and declare my variables etc... I should have got into this habit earlier.

I just have one more small question. The code currenly just prints out the image. I would also like to print out the other corresponding fields in my database with the image. My (test) database is as follows
A001|Amazing|BK-Amazing-Klaus.jpg
B002|Amma|BK-Amma-Sohn.jpg
C001|Zhenguo|BK-Anatomical-Zhenguo.jpg

How do I get the HTML be like:
<p>A001<br>Amazing <IMG SRC="../myimages/BK-Amazing-Klaus.50x50.jpg"></p>

etc for each line of the database? I know I have to add something here

Code
foreach (@out) {  
print <<HTML;
<IMG SRC="../myimages/$_">
HTML
}

but there is no array containing the contents of the other fields.

Thankyou very much again!
inlimbo...

For those who may be using this code in the future the line <IMG SRC="$_"> should in fact be <IMG SRC="../myimages/$_">


davorg
Thaumaturge / Moderator

Feb 16, 2005, 1:54 AM

Post #15 of 15 (4379 views)
Re: [inlimbo] loops, parsing and 500 errors [In reply to] Can't Post


In Reply To
I don't have access to the error logs, I can only get them through my server admin which is a teeth-pulling task.


I would consider have access to the web server error logs to be a base level requirement for serious CGI development. Without you are just going waste a lot of time (as we've seen in this discussion).


In Reply To
I just have one more small question. The code currenly just prints out the image. I would also like to print out the other corresponding fields in my database with the image. My (test) database is as follows

Code
A001|Amazing|BK-Amazing-Klaus.jpg 
B002|Amma|BK-Amma-Sohn.jpg
C001|Zhenguo|BK-Anatomical-Zhenguo.jpg

How do I get the HTML be like:

Code
<p>A001 
Amazing <IMG SRC="../myimages/BK-Amazing-Klaus.50x50.jpg"></p>

etc for each line of the database? I know I have to add something here

Code
foreach (@out) {  
print <<HTML;
<IMG SRC="../myimages/$_">
HTML
}

but there is no array containing the contents of the other fields.


I suggest that you change the values in the @out array so that instead of just containing the image filename, it contains a reference to hash which, in turn, contains all of the data from one record in your data file.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives