Made all scripts "use strict"

Implemented Captcha
This commit is contained in:
briandilley 2006-10-23 22:14:15 +00:00
parent ab68bd0d6c
commit eed35515bf
6 changed files with 281 additions and 115 deletions

View File

@ -1,32 +1,160 @@
#!/usr/bin/perl #!/usr/bin/perl
# bring in configuration
require "kwotes.conf.pl";
# add a module directory
use lib qw(./deps);
# we use DBI, for it's sexy body # we use DBI, for it's sexy body
use DBI; use DBI;
use GD::SecurityImage;
# super strict
package Lib;
use strict;
# template variables # template variables
$HEADER = "header"; $Lib::HEADER = "header";
$FOOTER = "footer"; $Lib::FOOTER = "footer";
$CONTENT_DEFAULT = "default-content"; $Lib::CONTENT_DEFAULT = "default-content";
$CONTENT_ADD = "add-kwote"; $Lib::CONTENT_ADD = "add-kwote";
$CONTENT_ADD_THANKS = "add-kwote-thanks"; $Lib::CONTENT_ADD_THANKS = "add-kwote-thanks";
$CONTENT_SEARCH = "search"; $Lib::CONTENT_SEARCH = "search";
$BEFORE_LIST = "before-list"; $Lib::BEFORE_LIST = "before-list";
$AFTER_LIST = "after-list"; $Lib::AFTER_LIST = "after-list";
$NAVIGATION = "navigation"; $Lib::NAVIGATION = "navigation";
$NAVIGATION_NO_BACK = "navigation-no-back"; $Lib::NAVIGATION_NO_BACK = "navigation-no-back";
$NAVIGATION_NO_FORWARD = "navigation-no-forward"; $Lib::NAVIGATION_NO_FORWARD = "navigation-no-forward";
$KWOTE_ODD = "kwote-odd"; $Lib::KWOTE_ODD = "kwote-odd";
$KWOTE_EVEN = "kwote-even"; $Lib::KWOTE_EVEN = "kwote-even";
$CONTENT_ERROR = "error"; $Lib::CONTENT_ERROR = "error";
$HTTP_HEADERS = "http-headers"; $Lib::HTTP_HEADERS = "http-headers";
# database connection # database connection
my $GLOBAL_DBH = undef; $Lib::GLOBAL_DBH = undef;
# captcha stuff
$Lib::CAPTCHA_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
$Lib::CAPTCHA_LEN = 8;
@Lib::CAPTCHA_BG_COLORS;
push(@Lib::CAPTCHA_BG_COLORS, "\#eeceff");
push(@Lib::CAPTCHA_BG_COLORS, "\#eeee00");
push(@Lib::CAPTCHA_BG_COLORS, "\#00ff00");
@Lib::CAPTCHA_FG_COLORS;
push(@Lib::CAPTCHA_FG_COLORS, "\#000000");
push(@Lib::CAPTCHA_FG_COLORS, "\#ff0000");
push(@Lib::CAPTCHA_FG_COLORS, "\#0000ff");
##
# validates a captcha
sub validate_captcha {
my ($cid, $phrase) = @_;
# connect
my $dbh = get_db_connection();
# prepare and execute
my $sth = $dbh->prepare(
"SELECT count(*) as count FROM captchas WHERE id=? and LOWER(phrase)=LOWER(?);");
$sth->bind_param(1, $cid);
$sth->bind_param(2, $phrase);
$sth->execute();
# get count
my $row = $sth->fetchrow_hashref();
my $count = $row->{"count"};
# return
return ($count>0);
}
##
# serves a captcha image
sub serve_captcha {
my ($cid) = @_;
# connect
my $dbh = get_db_connection();
# execute
my $sth = $dbh->prepare("SELECT phrase FROM captchas WHERE id=?");
$sth->bind_param(1, $cid);
$sth->execute();
# get row
my $row = $sth->fetchrow_hashref();
my $phrase = $row->{"phrase"} ? $row->{"phrase"} : "!ERROR!";
# generate captcha
my ($image_data, $mime_type) = gen_captcha($phrase);
# send to browser
print "Content-Type: $mime_type\n\n";
print $image_data;
}
##
# returns a captcha image and other info
sub gen_captcha {
my ($phrase) = @_;
my $bg = $Lib::CAPTCHA_BG_COLORS[rand()*int(@Lib::CAPTCHA_BG_COLORS)];
my $image = GD::SecurityImage->new(
width => 120,
height => 30,
lines => (rand()*3)+1,
gd_font => 'giant',
send_ctobg => 0,
bgcolor => $bg
);
$image->random($phrase);
$image->create(
"normalf",
"default",
$Lib::CAPTCHA_FG_COLORS[rand()*int(@Lib::CAPTCHA_FG_COLORS)]
);
my ($image_data, $mime_type, $random_number) = $image->out(force => 'jpeg');
return ($image_data, $mime_type);
}
##
# generates a random captcha phrase
sub gen_captcha_phrase {
my $phrase;
for (my $i=0; $i<$Lib::CAPTCHA_LEN; $i++) {
$phrase .= substr(
$Lib::CAPTCHA_CHARS,
rand()*length($Lib::CAPTCHA_CHARS),
1
);
}
# get connection
my $dbh = get_db_connection();
# prepare statement
my $sth = $dbh->prepare(
"INSERT INTO captchas (phrase) VALUES (?)",
) or return undef;
# bind params
$sth->bind_param(1, $phrase);
# execute
$sth->execute() or return undef;
# return id
return ($dbh->{'mysql_insertid'}) ?
$dbh->{'mysql_insertid'} : $sth->insert_id;
}
## ##
# Returns a random tagline # Returns a random tagline
sub get_tagline { sub get_tagline {
return $TAG_LINES[ @TAG_LINES*rand() ]; return $Conf::TAG_LINES[ @Conf::TAG_LINES*rand() ];
} }
## ##
@ -73,25 +201,18 @@ sub cleanup {
"INSERT INTO kwote_backup SELECT * FROM kwote WHERE ". "INSERT INTO kwote_backup SELECT * FROM kwote WHERE ".
"(now()-submit_dt)>? AND rating<=?" "(now()-submit_dt)>? AND rating<=?"
); );
$sth->bind_param(1, $KWOTE_TTL); $sth->bind_param(1, $Conf::KWOTE_TTL);
$sth->bind_param(2, $KWOTE_DEATH_RATING); $sth->bind_param(2, $Conf::KWOTE_DEATH_RATING);
$sth->execute() or die "Couldn't backup kwotes"; $sth->execute() or die "Couldn't backup kwotes";
# delete kwotes # delete kwotes
$sth = $dbh->prepare( $sth = $dbh->prepare(
"DELETE FROM kwote WHERE (now()-submit_dt)>? AND rating<=?" "DELETE FROM kwote WHERE (now()-submit_dt)>? AND rating<=?"
); );
$sth->bind_param(1, $KWOTE_TTL); $sth->bind_param(1, $Conf::KWOTE_TTL);
$sth->bind_param(2, $KWOTE_DEATH_RATING); $sth->bind_param(2, $Conf::KWOTE_DEATH_RATING);
$sth->execute() or die "Couldn't delete kwotes"; $sth->execute() or die "Couldn't delete kwotes";
# delete the vote log (this doesn't affect kwote rating)
$sth = $dbh->prepare(
"DELETE FROM vote WHERE (now()-vote_dt)>?"
);
$sth->bind_param(1, $VOTE_TTL);
$sth->execute() or die "Couldn't delete votes";
# let em know we're good # let em know we're good
print "Kwote Database cleanup complete\n"; print "Kwote Database cleanup complete\n";
@ -110,10 +231,11 @@ sub vote {
# prepare statement # prepare statement
my $sth = $dbh->prepare( my $sth = $dbh->prepare(
"SELECT COUNT(*) as vote_count FROM vote WHERE ". "SELECT COUNT(*) as vote_count FROM vote WHERE ".
"ip_address=? AND kwote_id=?" "ip_address=? AND kwote_id=? AND (now()-vote_dt)<=?"
); );
$sth->bind_param(1, $addr); $sth->bind_param(1, $addr);
$sth->bind_param(2, $kid); $sth->bind_param(2, $kid);
$sth->bind_param(3, $Conf::SECS_BETWEEN_VOTES);
# execute # execute
$sth->execute(); $sth->execute();
@ -122,7 +244,7 @@ sub vote {
my $row = $sth->fetchrow_hashref(); my $row = $sth->fetchrow_hashref();
# check if they suck # check if they suck
return undef if ($row->{"vote_count"}>=$MAX_VOTES_PER_IP); return undef if ($row->{"vote_count"}>=$Conf::MAX_VOTES_PER_IP);
# prepare # prepare
$sth = $dbh->prepare( $sth = $dbh->prepare(
@ -134,11 +256,12 @@ sub vote {
# record the vote # record the vote
$sth = $dbh->prepare( $sth = $dbh->prepare(
"INSERT INTO vote (ip_address, kwote_id, vote_dt) ". "INSERT INTO vote (ip_address, kwote_id, vote, vote_dt) ".
"VALUES (?, ?, now())" "VALUES (?, ?, ?, now())"
); );
$sth->bind_param(1, $addr); $sth->bind_param(1, $addr);
$sth->bind_param(2, $kid); $sth->bind_param(2, $kid);
$sth->bind_param(3, $amt);
$sth->execute() or return undef; $sth->execute() or return undef;
# we're good # we're good
@ -159,7 +282,7 @@ sub add_kwote {
"SELECT COUNT(*) as kwote_count FROM kwote WHERE ip_address=? AND (now()-submit_dt)<?" "SELECT COUNT(*) as kwote_count FROM kwote WHERE ip_address=? AND (now()-submit_dt)<?"
); );
$sth->bind_param(1, $ip_address); $sth->bind_param(1, $ip_address);
$sth->bind_param(2, $SECS_BETWEEN_KWOTES); $sth->bind_param(2, $Conf::SECS_BETWEEN_KWOTES);
# execute # execute
$sth->execute() or return undef; $sth->execute() or return undef;
@ -168,7 +291,7 @@ sub add_kwote {
my $row = $sth->fetchrow_hashref() or return undef; my $row = $sth->fetchrow_hashref() or return undef;
# check if they suck # check if they suck
return undef if ($row->{"kwote_count"}>=$MAX_KWOTES_PER_IP); return undef if ($row->{"kwote_count"}>=$Conf::MAX_KWOTES_PER_IP);
# prepare statement # prepare statement
my $sth = $dbh->prepare( my $sth = $dbh->prepare(
@ -306,14 +429,14 @@ sub list_kwotes {
## ##
# Connect to the database # Connect to the database
sub get_db_connection { sub get_db_connection {
if (!$GLOBAL_DBH) { if (!$Lib::GLOBAL_DBH) {
$GLOBAL_DBH = DBI->connect( $Lib::GLOBAL_DBH = DBI->connect(
"dbi:$DB_TYPE:$DB_NAME:$DB_HOST", "dbi:".$Conf::DB_TYPE.":".$Conf::DB_NAME.":".$Conf::DB_HOST,
$DB_USER, $Conf::DB_USER,
$DB_PASS $Conf::DB_PASS
); );
} }
return $GLOBAL_DBH; return $Lib::GLOBAL_DBH;
} }
## ##
@ -351,10 +474,11 @@ sub xml_escape {
# on the template # on the template
sub get_template_headers { sub get_template_headers {
my ($template) = @_; my ($template) = @_;
open(IN, "templates/$template/$HTTP_HEADERS"); open(IN, "templates/$template/$Lib::HTTP_HEADERS");
my $data = join("",<IN>); my $data = join("",<IN>);
close(IN); close(IN);
return $data; return $data;
} }
## ##
@ -364,7 +488,7 @@ sub wrap_template {
open(IN,"templates/$template/$template_file"); open(IN,"templates/$template/$template_file");
my $data = join("",<IN>); my $data = join("",<IN>);
close(IN); close(IN);
foreach $key (keys %vars) { foreach my $key (keys %vars) {
$data =~ s/\${$key}/$vars{$key}/ig; $data =~ s/\${$key}/$vars{$key}/ig;
} }
return $data; return $data;
@ -381,7 +505,7 @@ sub render_template {
## ##
# Parse form data # Parse form data
sub parse_form { sub parse_form {
my (@pairs, $pair, $buffer, %FORM); my (@pairs, $pair, $buffer, %FORM, $name, $value);
if ($ENV{'REQUEST_METHOD'} eq 'GET') { if ($ENV{'REQUEST_METHOD'} eq 'GET') {
@pairs = split(/&/, $ENV{'QUERY_STRING'}); @pairs = split(/&/, $ENV{'QUERY_STRING'});
} elsif ($ENV{'REQUEST_METHOD'} eq 'POST') { } elsif ($ENV{'REQUEST_METHOD'} eq 'POST') {
@ -389,7 +513,7 @@ sub parse_form {
@pairs = split(/&/, $buffer); @pairs = split(/&/, $buffer);
} }
foreach $pair (@pairs) { foreach $pair (@pairs) {
local($name, $value) = split(/=/, $pair); ($name, $value) = split(/=/, $pair);
$name =~ tr/+/ /; $name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ tr/+/ /; $value =~ tr/+/ /;

View File

@ -1,11 +1,15 @@
#!/usr/bin/perl #!/usr/bin/perl
use strict;
package Conf;
############################ ############################
## LOOK N FEEL ## ## LOOK N FEEL ##
############################ ############################
$SITE_NAME = "Kwotes"; $Conf::SITE_NAME = "Kwotes";
# the name of the site # the name of the site
@TAG_LINES = ( @Conf::TAG_LINES = (
"For happy goodness!", "For happy goodness!",
"The better kwote database.", "The better kwote database.",
"It blows goats!" "It blows goats!"
@ -13,63 +17,69 @@ $SITE_NAME = "Kwotes";
# tag lines to be randomly displayed # tag lines to be randomly displayed
# in the header # in the header
$DEFAULT_TEMPLATE = "default"; $Conf::DEFAULT_TEMPLATE = "default";
# name of the default template # name of the default template
############################ ############################
## DATABASE CONFIGURATION ## ## DATABASE CONFIGURATION ##
############################ ############################
$DB_TYPE = "mysql"; $Conf::DB_TYPE = "mysql";
# dbi database type (only MySQL is # dbi database type (only MySQL is
# supported currently, due to the # supported currently, due to the
# fact that "LIMIT X,X", and "RAND()" # fact that "LIMIT X,X", and "RAND()"
# is used # is used
$DB_NAME = "k121598_kwotes"; $Conf::DB_NAME = "kwotes";
# database name # database name
$DB_HOST = "mysql4-k"; $Conf::DB_HOST = "localhost";
# database host # database host
$DB_USER = "k121598rw"; $Conf::DB_USER = "root";
# database user # database user
$DB_PASS = "kw0t3s"; $Conf::DB_PASS = "bejane";
# database password # database password
############################ ############################
## GENERAL STUFF ## ## GENERAL STUFF ##
############################ ############################
$SECS_BETWEEN_KWOTES = 60*60; $Conf::CAPTCHA_SALT = "Kw0t3zCapTchASal7";
# The "Salt" to add to the captcha
# md5s that are sent to the user,
# It's a good idea to change this
$Conf::SECS_BETWEEN_KWOTES = 60*60;
# seconds a user must wait after # seconds a user must wait after
# submitting MAX_KWOTES_PER_IP # submitting MAX_KWOTES_PER_IP
# kwotes to the system before they # kwotes to the system before they
# are allowed to submit another # are allowed to submit another
# kwote # kwote
$KWOTE_DEATH_RATING = -1; $Conf::KWOTE_DEATH_RATING = -1;
# lowest rating a quote can be # lowest rating a quote can be
# before it's deleted. A kwote is # before it's deleted. A kwote is
# only deleted if it's been this # only deleted if it's been this
# number (or lower) for longer than # number (or lower) for longer than
# the KWOTE_TTL # the KWOTE_TTL
$KWOTE_TTL = (60*60)*24; $Conf::MAX_KWOTES_PER_IP = 5;
# maximum kwotes allowed per ip
# in SECS_BETWEEN_KWOTES
$Conf::KWOTE_TTL = (60*60)*24;
# seconds before a "dead" # seconds before a "dead"
# quote is moved to the kwote # quote is moved to the kwote
# backup table and deleted # backup table and deleted
$VOTE_TTL = (60*60)*24; $Conf::MAX_VOTES_PER_IP = 4;
# seconds a vote log lasts, the vote
# log is the mechanism that keeps
# people from voting over and over
$MAX_VOTES_PER_IP = 4;
# maximum votes per ip address per # maximum votes per ip address per
# VOTE_TTL seconds. # VOTE_TTL seconds.
$MAX_KWOTES_PER_IP = 5; $Conf::SECS_BETWEEN_VOTES = 60*60;
# maximum kwotes allowed per ip # seconds a user must wait after
# in SECS_BETWEEN_KWOTES # submiting MAX_VOTES_PER_IP
# votes to a single kwote before
# they are allowed to submit
# another vote for it
1; 1;

105
kwotes.pl
View File

@ -15,22 +15,23 @@
# bring in the required libs # bring in the required libs
require "kwotes-lib.pl"; require "kwotes-lib.pl";
# bring in the config # we're strict
require "kwotes.conf.pl"; package Main;
use strict;
# is this getting called by the "delete" cronjob? # is this getting called by the "delete" cronjob?
if ($ARGV[0] eq "cleanup") { if ($ARGV[0] eq "cleanup") {
exit cleanup(); exit Lib::cleanup();
} }
# parse the form data # parse the form data
my %FORM = parse_form(); my %FORM = Lib::parse_form();
# some vars # some vars
my $action = $FORM{"action"}; my $action = $FORM{"action"};
my $main_content; my $main_content;
my %vars; my %vars;
my $template = ($FORM{"template"}) ? $FORM{"template"} : $DEFAULT_TEMPLATE; my $template = ($FORM{"template"}) ? $FORM{"template"} : $Conf::DEFAULT_TEMPLATE;
# populate %vars with ENV # populate %vars with ENV
foreach my $key (keys %ENV) { foreach my $key (keys %ENV) {
@ -38,47 +39,54 @@ foreach my $key (keys %ENV) {
} }
# add information that can be displayed on every page # add information that can be displayed on every page
$vars{KWOTE_COUNT} = get_kwote_count(); $vars{KWOTE_COUNT} = Lib::get_kwote_count();
$vars{KWOTE_BACKUP_COUNT} = get_kwote_backup_count(); $vars{KWOTE_BACKUP_COUNT} = Lib::get_kwote_backup_count();
$vars{SITE_NAME} = $SITE_NAME; $vars{SITE_NAME} = $Conf::SITE_NAME;
$vars{TAG_LINE} = get_tagline(); $vars{TAG_LINE} = Lib::get_tagline();
$vars{TEMPLATE_DIR} = "templates/$template"; $vars{TEMPLATE_DIR} = "templates/$template";
# send header
print get_template_headers($template)."\n\n";
############ ############
# action: add (show add form) # action: add (show add form)
if ($action eq "add") { if ($action eq "add") {
$vars{TITLE} = "Add Kwote"; $vars{TITLE} = "Add Kwote";
$main_content = wrap_template($template, $CONTENT_ADD, %vars); $vars{CAPTCHA_ID} = Lib::gen_captcha_phrase();
$vars{KWOTE_TEXT} = "";
$main_content = Lib::wrap_template($template, $Lib::CONTENT_ADD, %vars);
############ ############
# action: doadd (add the kwote to the db) # action: doadd (add the kwote to the db)
} elsif ($action eq "doadd") { } elsif ($action eq "doadd") {
if ($FORM{"content"} eq "") { # check the captcha
if (!Lib::validate_captcha($FORM{"cid"}, $FORM{"phrase"})) {
$vars{TITLE} = "Add Kwote";
$vars{ERROR_MESSAGE} = "Captcha validation failed";
$vars{CAPTCHA_ID} = Lib::gen_captcha_phrase();
$vars{KWOTE_TEXT} = $FORM{"content"};
$main_content = Lib::wrap_template($template, $Lib::CONTENT_ADD, %vars);
} elsif ($FORM{"content"} eq "") {
$vars{TITLE} = "An Error Occured"; $vars{TITLE} = "An Error Occured";
$vars{ERROR_MESSAGE} = "No text entered"; $vars{ERROR_MESSAGE} = "No text entered";
$main_content = wrap_template($template, $CONTENT_ERROR, %vars); $main_content = Lib::wrap_template($template, $Lib::CONTENT_ERROR, %vars);
} else { } else {
# add the kwote # add the kwote
my $dbh = get_db_connection(); my $dbh = Lib::get_db_connection();
my $kid = add_kwote($dbh, $FORM{"content"}, $ENV{"REMOTE_ADDR"}); my $kid = Lib::add_kwote($dbh, $FORM{"content"}, $ENV{"REMOTE_ADDR"});
# wtf? errors? in my code? noooo. # wtf? errors? in my code? noooo.
if (!defined($kid)) { if (!defined($kid)) {
$vars{TITLE} = "An Error Occured"; $vars{TITLE} = "An Error Occured";
$vars{ERROR_MESSAGE} = "Couldn't add kwote: ".$DBI::errstr; $vars{ERROR_MESSAGE} = "Couldn't add kwote: ".$DBI::errstr;
$main_content = wrap_template($template, $CONTENT_ERROR, %vars); $main_content = Lib::wrap_template($template, $Lib::CONTENT_ERROR, %vars);
# all was good # all was good
} else { } else {
$vars{TITLE} = "Kwote Added"; $vars{TITLE} = "Kwote Added";
$vars{KWOTE_ID} = $kid; $vars{KWOTE_ID} = $kid;
$main_content = wrap_template($template, $CONTENT_ADD_THANKS, %vars); $main_content = Lib::wrap_template($template, $Lib::CONTENT_ADD_THANKS, %vars);
} }
} }
@ -88,24 +96,24 @@ if ($action eq "add") {
} elsif ($action eq "show") { } elsif ($action eq "show") {
# get the kwote # get the kwote
my $dbh = get_db_connection(); my $dbh = Lib::get_db_connection();
my $kwote = get_kwote($dbh, $FORM{"id"}); my $kwote = Lib::get_kwote($dbh, $FORM{"id"});
# wtf? errors? in my code? noooo. # wtf? errors? in my code? noooo.
if (!defined($kwote)) { if (!defined($kwote)) {
$vars{TITLE} = "Kwote Does Not Exist"; $vars{TITLE} = "Kwote Does Not Exist";
$vars{ERROR_MESSAGE} = "That kwote does not exist"; $vars{ERROR_MESSAGE} = "That kwote does not exist";
$main_content = wrap_template($template, $CONTENT_ERROR, %vars); $main_content = Lib::wrap_template($template, $Lib::CONTENT_ERROR, %vars);
# all was good # all was good
} else { } else {
$vars{TITLE} = "Kwote \#$kwote->{'id'}"; $vars{TITLE} = "Kwote \#$kwote->{'id'}";
$vars{KWOTE_ID} = $kwote->{'id'}; $vars{KWOTE_ID} = $kwote->{'id'};
$vars{KWOTE_TEXT_HTML} = html_escape($kwote->{'content'}); $vars{KWOTE_TEXT_HTML} = Lib::html_escape($kwote->{'content'});
$vars{KWOTE_TEXT_XML} = xml_escape($kwote->{'content'}); $vars{KWOTE_TEXT_XML} = Lib::xml_escape($kwote->{'content'});
$vars{KWOTE_TEXT_PLAIN} = $kwote->{'content'}; $vars{KWOTE_TEXT_PLAIN} = $kwote->{'content'};
$vars{KWOTE_RATING} = $kwote->{'rating'}; $vars{KWOTE_RATING} = $kwote->{'rating'};
$main_content = wrap_template($template, $KWOTE_EVEN, %vars); $main_content = Lib::wrap_template($template, $Lib::KWOTE_EVEN, %vars);
} }
@ -143,8 +151,8 @@ if ($action eq "add") {
my $min_rating = $FORM{"minr"}; my $min_rating = $FORM{"minr"};
# get the kwote # get the kwote
my $dbh = get_db_connection(); my $dbh = Lib::get_db_connection();
my @rows = list_kwotes( my @rows = Lib::list_kwotes(
$dbh, $dbh,
$sort, $sort,
$sort_order, $sort_order,
@ -172,74 +180,81 @@ if ($action eq "add") {
# forward, no back # forward, no back
if ($FORM{"o"} ne "random" && $start_index<=0 && @rows>=$max_returned if ($FORM{"o"} ne "random" && $start_index<=0 && @rows>=$max_returned
&& ($start_index+$max_returned)<$max_records) { && ($start_index+$max_returned)<$max_records) {
$navigation_template = $NAVIGATION_NO_BACK; $navigation_template = $Lib::NAVIGATION_NO_BACK;
# forward and back # forward and back
} elsif ($FORM{"o"} ne "random" && $start_index>0 && @rows>=$max_returned } elsif ($FORM{"o"} ne "random" && $start_index>0 && @rows>=$max_returned
&& ($start_index+$max_returned)<$max_records ) { && ($start_index+$max_returned)<$max_records ) {
$navigation_template = $NAVIGATION; $navigation_template = $Lib::NAVIGATION;
# back only # back only
} elsif ($FORM{"o"} ne "random" && $start_index>0 && @rows<$max_returned) { } elsif ($FORM{"o"} ne "random" && $start_index>0 && @rows<$max_returned) {
$navigation_template = $NAVIGATION_NO_FORWARD; $navigation_template = $Lib::NAVIGATION_NO_FORWARD;
} }
# wrap the navigation template # wrap the navigation template
$main_content .= wrap_template($template, $navigation_template, %vars); $main_content .= Lib::wrap_template($template, $navigation_template, %vars);
# wrap up the "before list" template # wrap up the "before list" template
$main_content .= wrap_template($template, $BEFORE_LIST, %vars); $main_content .= Lib::wrap_template($template, $Lib::BEFORE_LIST, %vars);
# loop through the results # loop through the results
if (defined(@rows)) { if (defined(@rows)) {
for (my $i=0; $i<@rows && ($i+$start_index)<$max_records; $i++) { for (my $i=0; $i<@rows && ($i+$start_index)<$max_records; $i++) {
my $row = $rows[$i]; my $row = $rows[$i];
my $kwote_template = (($i % 2) != 0) ? $KWOTE_ODD : $KWOTE_EVEN; my $kwote_template = (($i % 2) != 0) ? $Lib::KWOTE_ODD : $Lib::KWOTE_EVEN;
$vars{KWOTE_ID} = $row->{'id'}; $vars{KWOTE_ID} = $row->{'id'};
$vars{KWOTE_TEXT_HTML} = html_escape($row->{'content'}); $vars{KWOTE_TEXT_HTML} = Lib::html_escape($row->{'content'});
$vars{KWOTE_TEXT_XML} = xml_escape($row->{'content'}); $vars{KWOTE_TEXT_XML} = Lib::xml_escape($row->{'content'});
$vars{KWOTE_TEXT_PLAIN} = $row->{'content'}; $vars{KWOTE_TEXT_PLAIN} = $row->{'content'};
$vars{KWOTE_RATING} = $row->{'rating'}; $vars{KWOTE_RATING} = $row->{'rating'};
$main_content .= wrap_template($template, $kwote_template, %vars); $main_content .= Lib::wrap_template($template, $kwote_template, %vars);
} }
} }
# wrap up the "after list" template # wrap up the "after list" template
$main_content .= wrap_template($template, $AFTER_LIST, %vars); $main_content .= Lib::wrap_template($template, $Lib::AFTER_LIST, %vars);
# wrap the navigation template # wrap the navigation template
$main_content .= wrap_template($template, $navigation_template, %vars); $main_content .= Lib::wrap_template($template, $navigation_template, %vars);
########## ##########
# action: search (show the search page) # action: search (show the search page)
} elsif ($action eq "search") { } elsif ($action eq "search") {
$vars{TITLE} = "Search"; $vars{TITLE} = "Search";
$main_content = wrap_template($template, $CONTENT_SEARCH, %vars); $main_content = Lib::wrap_template($template, $Lib::CONTENT_SEARCH, %vars);
########## ##########
# action: love # action: love
} elsif ($action eq "love") { } elsif ($action eq "love") {
vote($ENV{"REMOTE_ADDR"}, $FORM{"kid"}, "1"); Lib::vote($ENV{"REMOTE_ADDR"}, $FORM{"kid"}, "1");
$vars{TITLE} = "Love"; $vars{TITLE} = "Love";
$main_content = "Vote Counted"; $main_content = "Vote Counted";
########## ##########
# action: hate # action: hate
} elsif ($action eq "hate") { } elsif ($action eq "hate") {
vote($ENV{"REMOTE_ADDR"}, $FORM{"kid"}, "-1"); Lib::vote($ENV{"REMOTE_ADDR"}, $FORM{"kid"}, "-1");
$vars{TITLE} = "Hate"; $vars{TITLE} = "Hate";
$main_content = "Vote Counted"; $main_content = "Vote Counted";
##########
# action: captcha
} elsif ($action eq "captcha") {
Lib::serve_captcha($FORM{'cid'});
exit;
########## ##########
# show the homepage # show the homepage
} else { } else {
$vars{TITLE} = "The Better kwote Database"; $vars{TITLE} = "The Better kwote Database";
$main_content = wrap_template($template, $CONTENT_DEFAULT, %vars); $main_content = Lib::wrap_template($template, $Lib::CONTENT_DEFAULT, %vars);
} }
# finish the HTML # send the HTML
render_template($template, $HEADER, %vars); print Lib::get_template_headers($template)."\n\n";
Lib::render_template($template, $Lib::HEADER, %vars);
print STDOUT $main_content; print STDOUT $main_content;
render_template($template, $FOOTER, %vars); Lib::render_template($template, $Lib::FOOTER, %vars);

View File

@ -19,10 +19,16 @@ CREATE TABLE kwote_backup (
CREATE TABLE vote ( CREATE TABLE vote (
id INT AUTO_INCREMENT, id INT AUTO_INCREMENT,
ip_address VARCHAR(15),
kwote_id INT, kwote_id INT,
vote INT,
ip_address VARCHAR(15),
vote_dt DATETIME, vote_dt DATETIME,
PRIMARY KEY(id), PRIMARY KEY(id)
FOREIGN KEY(kwote_id) REFERENCES kwote(id) );
CREATE TABLE captchas (
id INT AUTO_INCREMENT,
phrase VARCHAR(255),
PRIMARY KEY(id)
); );

View File

@ -1,9 +1,20 @@
 <form action="${SCRIPT_NAME}" method="post">  <form action="${SCRIPT_NAME}" method="post">
<div style="margin: 5px;"> <div style="margin: 5px;">
<input type="hidden" name="action" value="doadd" /> <input type="hidden" name="action" value="doadd" />
<textarea cols="80" rows="20" name="content" style="width: 100%;"></textarea> <input type="hidden" name="cid" value="${CAPTCHA_ID}" />
<textarea cols="80" rows="20" name="content" style="width: 100%;">${KWOTE_TEXT}</textarea>
<br /> <br />
<span style="float: left;">
<img src="${SCRIPT_NAME}?action=captcha&amp;cid=${CAPTCHA_ID}" width="120" height="30" border="0" />
</span>
<span style="float: left;">
&nbsp;
Enter the letters you see to the left:
<input type="text" name="phrase" />
</span>
<span style="float: right;"> <span style="float: right;">
<input type="submit" value="Submit Quote" /> <input type="submit" value="Submit Quote" />
</span> </span>

View File

@ -52,7 +52,7 @@
<form id="searchbox" action="${SCRIPT_NAME}" method="get"> <form id="searchbox" action="${SCRIPT_NAME}" method="get">
<div> <div>
<input type="hidden" name="action" value="show" /> <input type="hidden" name="action" value="show" />
Kwote #&nbsp;<input type="text" size="5" name="kwoteid" id="kwoteid" /> Kwote #&nbsp;<input type="text" size="5" name="id" id="kwoteid" />
</div> </div>
</form> </form>