|
#!/usr/bin/perl
|
|
use strict;
|
|
use CGI;
|
|
use DBI ();
|
|
|
|
## Create a CGI query object
|
|
my $q = CGI->new();
|
|
## Store off the base URL to access this script
|
|
my $base_url = $q->url( -full => 1 );
|
|
## Define these variables here so they're visible to all parts of our
|
|
## script (including subroutines)
|
|
my( $prefix, $ttdb, $dbuser, $dbpass, $ttroot );
|
|
##
|
|
## Get Database parameters from %ENV
|
|
##
|
|
$prefix = $ENV{'TopTenPrefix'} || 'topten';
|
|
$ttdb = $ENV{'TopTenDB'} || 'tpj';
|
|
$dbuser = $ENV{'TopTenDBUser'} || 'ap_auth';
|
|
$dbpass = $ENV{'TopTenDBPass'} || '';
|
|
$ttroot = $ENV{'TopTenRoot'} || '/tmp';
|
|
## Print HTTP headers, and start of HTML page
|
|
print $q->header( 'text/html' ),
|
|
$q->start_html( -title => 'TopTen Administration',
|
|
-bgcolor => '#ffffff'
|
|
),
|
|
"<h1>TopTen Administration</h1>\n";
|
|
|
|
## If script was't passed parameters, simply print the initial options
|
|
unless( $q->param() ) {
|
|
## Start a form to add a file. Prints the necessary <FORM> HT\
|
|
ML.
|
|
print $q->start_multipart_form( -method => 'POST',
|
|
-action => $base_url );
|
|
## Print some explanatory text and a file upload button
|
|
print qq{\n<h2>Add a file to the repository</h2>
|
|
File to upload: \n},
|
|
$q->filefield( -name => 'addfile',
|
|
-size => 50,
|
|
),
|
|
"<br>Title:  ",
|
|
$q->textfield( -name => 'title' ),
|
|
"\n";
|
|
print $q->submit( -name => 'action',
|
|
-value => 'Add',
|
|
);
|
|
## Print HTML to end the form
|
|
print $q->endform, "\n";
|
|
|
|
## You can roll the an entire form (or even the entire output of you\
|
|
r
|
|
## script, for that matter) up into one print statement
|
|
print $q->startform( -method => 'POST',
|
|
-action => $base_url,
|
|
-encoding => &CGI::MULTIPART ),
|
|
qq{\n<h2>Zero a file\'s hit counter</h2>\nPick fil\
|
|
e . . . },
|
|
$q->submit( -name => 'action',
|
|
-value => 'Zero',
|
|
),
|
|
$q->endform, "\n";
|
|
print $q->startform( -method => 'POST',
|
|
-action => $base_url,
|
|
-enctype => &CGI::MULTIPART ),
|
|
qq{\n<h2>Delete a file</h2>\nPick file . . . \
|
|
},
|
|
$q->submit( -name => 'action',
|
|
-value => 'Delete',
|
|
),
|
|
$q->endform, "\n";
|
|
|
|
} else {
|
|
##
|
|
## Decide what to do based on $q->param( 'action' )
|
|
##
|
|
my $action = $q->param( 'action' );
|
|
|
|
if ($action eq 'Add') {
|
|
## Make them give us a file and a title
|
|
unless (defined $q->param('title') && defined $q->param('add\
|
|
file')) {
|
|
print "You must specify a title and upload a file.\n";
|
|
} else {
|
|
## Strip out the filename from the full path
|
|
my $pathname = $q->param( 'addfile' );
|
|
$pathname =~ s/.*[\/\\:]([^\/\\:]+)$/$1/;
|
|
## Gripe if a file with that pathname already exists
|
|
if (-f "$ttroot/$pathname") {
|
|
print qq{
|
|
<h2>Error!</h2>
|
|
|
|
File '$pathname' already exists. Use the 'Delete' action to remove
|
|
the current file if you really want to overwrite.<p>
|
|
}, &back_to_main();
|
|
exit 0;
|
|
}
|
|
|
|
## Copy the file to the document root.
|
|
open( OUTPUT, ">$ttroot/$pathname" )
|
|
or die "Can't create outputfile '$ttroot/$pathname': $!";
|
|
|
|
## Strict won't let us use the filename CGI.pm setup as a
|
|
## handle by default. Turn off that part of strict for this
|
|
## one block of code.
|
|
{
|
|
no strict qw(refs);
|
|
|
|
my $addfile = $q->param('addfile');
|
|
while (<$addfile>) {
|
|
print OUTPUT;
|
|
}
|
|
}
|
|
|
|
print OUTPUT "<!-- Uploaded at ", scalar localtime, " -->\\
|
|
n";
|
|
|
|
close( OUTPUT );
|
|
|
|
my $dbh = DBI->connect( "dbi:Pg:dbname=$ttdb",
|
|
$dbuser, $dbpass )
|
|
or die "DBI Error: $DBI::errstr";
|
|
|
|
my $title = $q->param('title');
|
|
|
|
## select statement to insert new record into database
|
|
my $sth = $dbh->prepare( qq{
|
|
insert into documents values ( ?, ? , 0, 3, 1 );
|
|
})
|
|
or die "DBI Error: " . $dbh->errstr . "\n";
|
|
|
|
unless ( $sth->execute( "$pathname", $title ) ) {
|
|
die "DBI Error: " . $dbh->errstr . "\n";
|
|
}
|
|
|
|
$sth->finish;
|
|
$dbh->disconnect;
|
|
print qq{
|
|
<h2>File Added</h2>
|
|
The file '$title' ($pathname) was added successfully.<p>
|
|
<ul>
|
|
<li><a href="/$prefix/$pathname">$title</a>
|
|
<li><a href="/$prefix/">TopTen Area</a>
|
|
<li>}, &back_to_main(), qq{
|
|
</ul>
|
|
};
|
|
}
|
|
} elsif ($action eq 'Zero') {
|
|
unless ($q->param( 'victimfile' )) {
|
|
print $q->startform( -method => 'POST',
|
|
-action => $base_url,
|
|
-encoding => &CGI::MULTIPART );
|
|
## Use a hidden form field to pass the action back to ourselves
|
|
print $q->hidden( -name => 'action',
|
|
-value => 'Zero',
|
|
);
|
|
|
|
print "<h2>Pick a file to zero hits for . . .</h2>\n\
|
|
";
|
|
|
|
## Print table listing all files
|
|
&list_all_files( $q );
|
|
print $q->endform;
|
|
print &back_to_main();
|
|
} else {
|
|
my $file = $q->param( 'victimfile' );
|
|
my $dbh = DBI->connect( "dbi:Pg:dbname=$ttdb",
|
|
$dbuser, $dbpass )
|
|
or die "DBI Error: $DBI::errstr";
|
|
|
|
## select statement to grab information
|
|
my $sth = $dbh->prepare( qq{
|
|
update documents set hits = 0 where path = ?;
|
|
})
|
|
or die "DBI Error: " . $dbh->errstr . "\n";
|
|
|
|
unless ( $sth->execute( $file ) ) {
|
|
die "DBI Error: " . $sth->errstr . "\n";
|
|
}
|
|
|
|
$sth->finish;
|
|
$dbh->disconnect;
|
|
print qq{
|
|
<h2>Hits for $file zeroed.</h2>
|
|
<ul>
|
|
<li>}, &back_to_main(), qq{
|
|
<li><a href="/$prefix/">TopTen Area</a>
|
|
</ul>
|
|
};
|
|
}
|
|
|
|
} elsif ($action eq 'Delete') {
|
|
unless ($q->param( 'victimfile' )) {
|
|
print $q->startform( -method => 'POST',
|
|
-action => $base_url,
|
|
-encoding => &CGI::MULTIPART );
|
|
## Use a hidden form field to pass the action back to ourselves
|
|
print $q->hidden( -name => 'action',
|
|
-value => 'Delete',
|
|
);
|
|
|
|
print "<h2>Pick file to delete . . .</h2>\n";
|
|
|
|
## Print table listing all files
|
|
&list_all_files( $q );
|
|
print $q->endform;
|
|
print &back_to_main();
|
|
} else {
|
|
my $file = $q->param( 'victimfile' );
|
|
my $dbh = DBI->connect( "dbi:Pg:dbname=$ttdb",
|
|
$dbuser, $dbpass )
|
|
or die "DBI Error: $DBI::errstr";
|
|
## select statement to grab information
|
|
my $sth = $dbh->prepare( qq{
|
|
delete from documents where path = ?;
|
|
})
|
|
or die "DBI Error: " . $dbh->errstr . "\n";
|
|
unless ( $sth->execute( $file ) ) {
|
|
die "DBI Error: " . $sth->errstr . "\n";
|
|
}
|
|
unlink "$ttroot/$file"
|
|
or die "Can't unlink '$ttroot/$file': $!";
|
|
|
|
$sth->finish;
|
|
$dbh->disconnect;
|
|
print qq{
|
|
<h2>'$file' Deleted.</h2>
|
|
<ul>
|
|
<li>}, &back_to_main(), qq{
|
|
<li><a href="/$prefix/">TopTen Area</a>
|
|
</ul>
|
|
};
|
|
}
|
|
|
|
} else {
|
|
print qq{<h2>Unknown Action</h2>\n}, &back_to_main();
|
|
}
|
|
}
|
|
print $q->end_html;
|
|
##
|
|
## Subroutines
|
|
##
|
|
sub list_all_files {
|
|
my $q = shift;
|
|
my $dbh = DBI->connect( "dbi:Pg:dbname=$ttdb",
|
|
$dbuser, $dbpass )
|
|
or die "DBI Error: $DBI::errstr\n";
|
|
|
|
## select statement to grab information
|
|
my $sth = $dbh->prepare( qq{
|
|
select title, path, hits, rating from documents
|
|
order by hits desc, rating desc;
|
|
})
|
|
or die "DBI Error: " . $dbh->errstr . "\n";
|
|
unless ( $sth->execute ) {
|
|
die "DBI Error: " . $sth->errstr . "\n";
|
|
}
|
|
## qq{} and here docs are handy ways to print large chunks of
|
|
## HTML text
|
|
print qq{
|
|
<table>
|
|
<tr>
|
|
<th>Title</th><th>Path</th><th>Hits&\
|
|
lt;/th><th> </th>
|
|
</tr>
|
|
};
|
|
|
|
##
|
|
## $filelist will look like:
|
|
## $filelist = [
|
|
## [ title, path, hits, rating ],
|
|
## [ title, path, hits, rating ],
|
|
## ...
|
|
## ]
|
|
##
|
|
my $filelist = $sth->fetchall_arrayref;
|
|
foreach (@{$filelist}) {
|
|
print " <tr>\n<td>$_->[0]</td>", # Title
|
|
"<td>$_->[1]</td>", # Path
|
|
"<td>$_->[2]</td>", # Hits
|
|
"<td>",
|
|
$q->submit( -name => 'victimfile',
|
|
-value => $_->[1],
|
|
),
|
|
"</td>\n</tr>\n";
|
|
}
|
|
|
|
print "\n</table>\n";
|
|
|
|
$sth->finish;
|
|
$dbh->disconnect;
|
|
return;
|
|
}
|
|
|
|
sub back_to_main {
|
|
return qq{<a href="$base_url">Back to TopTen Administration<\
|
|
;/a>\n};
|
|
}
|