In article
<[EMAIL PROTECTED]>,
[EMAIL PROTECTED] (Ilya Sterin) wrote:
> Well post the script and we can look. Please eliminate the parts that are
> not relevant if you script is big.
it's about 255 lines of code incuding comments.. I'll remove the
comments from the file to shorten it a bit. The linewrapping will suck
but I'll try and clean it up a bit.
it's *considerably* streamlined from my first hackish attempts at
writing cgi scripts and from working with the original CSV/Tab-delimited
tables using DBD::CSV and more recently DBD::AnyData. I'm damned proud
of how far I've come in the year since I started working with Perl, and
situations like this just <gross understatement>annoy me</gross
understatement>.
Your help will be most greatly appreciated.
I'm starting to wonder how much of a threat to Perl the PHP crowd really
is, and how much of a resource hog mod_perl is compared with the
embedded PHP in Apache, and why, if PHP is based on Perl, there could be
such a huge disparity in performance.
> These benchmarks are a bunch of crap. There are 900 times more bytes
> transfered. The files look way to much different in sizes. So we are yet
> to see an exact comparison:-)
definitely. I *KNOW* how hard I've worked on streamlining this code, and
I'll be damned if someone can hack together a php script that does
things in half the time, and with fewer memory resources used, much less
what that so-called-benchmark shows.
the code:
#!/usr/bin/perl -T
#### search.cgi
use warnings;
use strict;
use CGI qw/:standard :html3 *table *div *form
-no_xhtml escapeHTML unescapeHTML/;
# do these get left out if you use CGI->compile(':all')
# and in particular with mod_perl and Apache::DBI?
# security sanity check.
$CGI::POST_MAX = 1024 * 16; # max 16k POSTs
$CGI::DISABLE_UPLOADS++; # no uploads
$ENV{'PATH'} = '/bin:/usr/bin:';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
use CGI::Carp qw(fatalsToBrowser set_message);
BEGIN {
sub handle_errors {
my $msg = join( br(), @_);
print header,
start_html( "CGI/Perl Script Error" ),
h2( "aCk!"),
p( "I must be currently beta-testing some changes, so
E-mail me, ",
a({-href=>'mailto:[EMAIL PROTECTED]'},
"fuzzbuster"),
", about this if it persists for very long.",
),
hr,
p( "Got an error: $msg" ),
end_html;
}
set_message(\&handle_errors);
};
use DBI;
my $dbiuser = 'nalicity';
my $dbipass = 'password';
my $map_db = 'maps';
my $download_url = 'http://www.planetunreal.com/dl/nc.asp?nalicity/';
my @types = (qw/empty unknown unknown unknown unknown unknown utdm
utassault utdomination utctf utother/);
my $newStyle = <<'EOS';
table, caption, th, td { background: #1E2B4A; font-family: "Trebuchet
MS", "Sapir Sans", sans-serif; font-size: 12pt; }
body { font-family: "Trebuchet MS", "Sapir Sans",
sans-serif; font-size: 12pt; }
EOS
my %files_list = (
'7' => 'UT Assault Maps',
'9' => 'UT Capture The Flag Maps',
'6' => 'UT DeathMatch Maps',
'8' => 'UT Domination maps',
'10' => 'UT Other Maps'
);
sub size_calc ($)
{
my $mapsize = shift;
($mapsize <= 1024)
? return $mapsize . "k"
: return sprintf('%.2f', ($mapsize/1024)) . "MB";
};
sub checkrating ($$$)
{
my($rating, $reviewfile, $id) = @_;
if ( $rating == -1 )
{
return "N/A";
}
else
{
if ($reviewfile eq "-1")
{
return
a({-href=>"http://nalicity.beyondunreal.com/testbed/review.php?Id=${id}",
-target=>"review"},
b($rating),
);
}
else
{
return
a({-href=>"http://nalicity.beyondunreal.com/testbed/reviews/${reviewfile}
.html", -target=>"review"},
b($rating),
);
}
}
};
sub create_dbi_table ($)
{
my $displayselect = shift;
my $dbh = DBI->connect("DBI:mysql:database=nalicity;host=localhost",
$dbiuser, $dbipass, {RaiseError => 1})
or die("Cannot connect to database - $!");
END { $dbh->disconnect if $dbh }
my $sth = $dbh->prepare($displayselect) or die $dbh->errstr;
$sth->execute;
my $rowcount = $sth->rows;
unless( $rowcount )
{
print Tr( td({-colspan=>3, -align=>'center', }, b("No Match
Found") ));
return '';
}
print Tr( td({-colspan=>3, -align=>'center', }, b("Found $rowcount
matches") ));
my( $type, $id, $filename, $title, $size, $reviewfile, $rating,
$rated, $oldtype );
$sth->bind_columns(\$type, \$id, \$filename, \$title, \$size,
\$reviewfile, \$rating);
while ( $sth->fetch )
{
# in english: If oldrating is empty, or different from the
# previous rating AND the rating is now < 0
if ( !defined($rated) or ($rated != $rating and $rating < 0) )
{
# then check to see whether we're rated or unrated and print
# an appropriate header for that section
if ($rating < 0)
{
print Tr( td({-colspan=>3, -align=>'center', }, b(
u("Unrated Maps")) )),
Tr(
th({-align=>"center"}, "Map Name"),
th({-align=>"right"}, "Size"),
th({-align=>"center"}, "Rating"),
);
$oldtype = -1; #re-set oldtype ;)
}
else
{
print Tr( td({-colspan=>3, -align=>'center', }, b(
u("Rated Maps")) )),
Tr(
th({-align=>"center"}, "Map Name"),
th({-align=>"right"}, "Size"),
th({-align=>"center"}, "Rating"),
);
};
};
# okay so we have nice section headers..
# how about some type section headers for the unrated section?
if ( $rating == -1 and $type != $oldtype )
{
print Tr( td({-colspan=>3, -align=>'center'},
$files_list{$type} ) );
}
$filename= unescapeHTML($filename);
print Tr(
td({-align=>"left", -valign=>"top"},
a({-href=>"${download_url}$types[${type}]/${filename}.zip",
-target=>"_new"}, $title ),
),
td({-align=>"right", -valign=>"top"},
size_calc($size),
),
td({-align=>"center", -valign=>"top",},
checkrating($rating, $reviewfile, $id),
),
), "\n";
# adjust loop vars for prettyprint
$rated = $rating;
$oldtype = $type;
};
die $sth->errstr if $sth->err;
}
my $search_obj = escapeHTML( param('searchfor') ) || '';
# un-taint the search object
$search_obj =~ m/([ a-zA-Z-_\[\]\{\}0-9]+)/;
$search_obj = $1;
if (!param() && cgi_error()) {
print header(-status=>cgi_error());
goto FINISH;# don't call exit 0; !!! (unless you LIKE killing your
perl process over and over, ass-hat) :P
}
my $expires = (localtime(time + 30));
print header({'head'=>meta( {-http_equiv=>'Expires', -content=>$expires
} )}),
start_html({-Title=>"FuzzBuster's NaliCity Quick Search!",
-Style=>{-Code=>$newStyle},
-bgcolor=>'#003366',
-text=>'white',
-"link"=>'#ffff99',
-vlink=>'yellow'});
print start_form,
div({-align=>'center'},
h3("Map Search"),
p("Enter the name of a map title or file to search for:"),
textfield(-name=>'searchfor',
-default=>'',
-size=>30,
-maxlength=>68,
-override=>1),
br,
submit(-name=>'Submit', -value=>'Submit'),
),
end_form, hr;
if ( $search_obj eq '' )
{
# skip the database query
print end_html;
goto FINISH;
}
my $query = "SELECT Type, ID, FileName, Title, Size, ReviewFile,
ROUND(Rating, 2)
FROM $map_db
WHERE FileName LIKE '%$search_obj%' OR Title LIKE
'%$search_obj%'
ORDER BY Rating DESC, Type, FileName";
print start_div({-align=>"center"}),
start_table({-border=>"0", -cellpadding=>"0", -cellspacing=>"2",
-width=>"300"});
create_dbi_table($query);
print end_table,
end_div,
hr,
end_html;
FINISH:
# end of code
If anyone is interested I can provide particulars on the maps table in
the MySQL database as well.
--
Scott R. Godin | e-mail : [EMAIL PROTECTED]
Laughing Dragon Services | web : http://www.webdragon.net/