doctor_moron has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, i have CGI script and i need your advices about my code, and here's the scenario (Sorry for my english) :

The only query string allowed is param('page'), i mean user can reach my site with something like :

http://www.mysite.com/sorting.pl?page=2
that's mean user want to see files in page 2. And if user write http://www.mysite.com/sorting.pl #(without param('page')) that's mean param('page') = 0

The directory's path is :/home/lenn287/public_html/diary and there are 21 files in that directory. So there are 5 pages for 21 articles (5 files per page).

all 21 files are saved with html format and html extension, example :

200607140809.html (yyyy-mm-dd-hh-mm),
why ? the reason is i can easily just use reverse and sort function when i need to display the latest file at the top of my page.

About my files, they all have same characteristic, i'll take 1 example to make it clearer (with what i mean with "same characteristic"), here's the contents of 200607140809.html

<!--topic:Metallic Coating--> <!--title:Galvanizing for Corrosion Protection - A Specifier's Guide t +o Reinforcing Steel--> <!--lang:English--> <p> Galvanizing for Corrosion Protection - A Specifier's Guide to Reinforc +ing Steel </p> <p> Corrosion and repair of corrosion damage aremulti-billion dollar probl +ems. Observations on numerous structures show that corrosion of reinf +orcing steel is either a prime factor, or at least an important facto +r, contributing to the staining, cracking and spalling of concrete st +ructures. These effects of corrosion often require costly repairs and continued maintenance during the life of the structure. </p>

Have a look at the comment tags, they're exist in all my files, comment tags help me when i need to show only topic, title and lang in my page (open the file and use regex to find topic,title and lang) and one thing, there is no <html>,<body></body></html> tags in every files.

But im rather in a doubt about my code , it's like.. well, i dont know what to say (after learning few chapters from Perl Intermediate, i think i cant make things simpler....:">) that's why i need advices from you all

here's my code

#!/usr/bin/perl -wT use strict; use CGI qw/:standard/; $CGI::DISABLE_UPLOADS =1; my $page=param('page') || 0; unless ($page =~ m/^(\d+)$/) { die } $page = $1; opendir(DIRE, "/home/lenn287/public_html/diary")|| er_msg("cant open d +irectory: $!"); #UPDATED
my @files_exist = reverse sort map { $_ =~ s/^(\d+)\.html$/$1/; $_} grep { /^\w+.\.html$/} readdir DIRE;
my @files_exist = reverse sort map { $_ =~ s/^(\d+)\.html$/$1/; $_} grep { /^\d+.\.html$/} readdir DIRE; closedir DIRE; my $how_many_page = sub { my ($how) = @_; $how = $how/5; $how =~ /(\d+?).?(\d+)?/; if(!$2) { return $1 } else { return $1+1 } }; my $file = sub { my $file_name = shift; my($topic,$title,$lang); open my $FH,'<', '/home/lenn287/public_html/diary/'.$file_name.".htm +l"; while(<$FH>) { $topic = $1 if /<!--topic:(.+?)-->/; $title = $1 if /<!--title:(.+?)-->/; $lang = $1 if /<!--lang:(.+?)-->/; } close $FH; return ($topic,br(),$title,br(),$lang,p()); }; if($page !~ /^[0-$how_many_page->($#files_exist)]$/) { print header,start_html,"invalid $page",end_html; exit(0); } my ($next,$previous); if($page < $how_many_page->($#files_exist)) { my $next_page=$page+1; $next = a({href=>"/cgi-bin/author.pl?page=$next_page"},"next"); } else { $next=''; } if($page > 0) { my $previous_page=$page-1; $previous = a({href=>"/cgi-bin/author.pl?page=$previous_page"},"prev +ious"); } else { $previous=''; } my $first_file = $page*5; my $last_file = $page*5+4; my @FILES;
for($first_file; $first_file<=$last_file;$first_file++) { push @FILES, $file->($files_exist[$first_file]); }
for my $f($first_file..$last_file) { push @FILES, $file->($files_exist[$f]); } print header,start_html; print table({width=>720}, Tr( td({width=>720,colspan=>2}, img({src=>"/images/logo.gif",alt=>"logo", height=>90,width=>710}))), Tr( td({width=>600},@FILES), td({width=>120,rowspan=>100}, img({src=>"/images/banner.gif", height=>450,width=>120,alt=>"banner"})) ), Tr( td($next,$previous) )); undef $file; print end_html; #UPDATED, error message sub er_msg { my $error ="@_"; print header,start_html,p($error),end_html; die "$error"; }

Thank you, zak

Replies are listed 'Best First'.
Re: Need advices, displaying files in directory with CGI..
by Leviathan (Scribe) on Jul 22, 2006 at 13:05 UTC

    Some comments:

    opendir(DIRE, "/home/lenn287/public_html/diary"); my @files_exist = reverse sort map { $_ =~ s/^(\d+)\.html$/$1/; $_} grep { /^\w+.\.html$/} readdir DIRE; closedir DIRE;

    Here your first regexp checks for (\w) and the second matches digits, so if you have a file called "bleh.html" it will pass the first grep but it will produce an empty entry on the display. Change the \w+ into \d+.

    open my $FH,'<', '/home/lenn287/public_html/diary/'.$file_name.".html" +;

    You don't check if your open succeeded or not.

    for($first_file; $first_file<=$last_file;$first_file++) {

    Since you're coding Perl:

    for my $f ($first_file .. $last_file) {

    On another note, since you want to search within the files, you should either create an index of some sorts, instead of opening each file and searching, or use a database to store the contents and then you can use fulltext search on them.

    just a couple of cents

    --
    Leviathan.
Re: Need advices, displaying files in directory with CGI..
by Ieronim (Friar) on Jul 22, 2006 at 11:51 UTC
    If i have understood you correctly, your code works, but it looks too ugly for you?

    If so, i recommend you to study HTML::Template. This module allowas you to leave all HTML in a separate template file and fill it with your data. The time you will spend learning HTML::Template will save you hours in future :) And it's a pain in the butt to create complex HTML pages with functions of CGI module :)


         s;;Just-me-not-h-Ni-m-P-Ni-lm-I-ar-O-Ni;;tr?IerONim-?HAcker ?d;print
Re: Need advices, displaying files in directory with CGI..
by fmerges (Chaplain) on Jul 22, 2006 at 10:57 UTC

    Hi,

    Don't know in which context this run, or which constraint you have, but have you thought about using a template module for the HTML output, a module for paginating, and putting the data on a Database?

    Regards,

    fmerges at irc.freenode.net
Re: Need advices, displaying files in directory with CGI..
by pope (Friar) on Sep 13, 2006 at 09:25 UTC
    this should be slightly faster:
    my @files_exist = reverse sort grep { defined } map { my $f = $_; $f =~ s/^(\d+)\.html$/$1/ ? $f : undef } readdir DIRE;