Introduction A 12-year-old can build a nice Web service using the tools that came standard with any Linux or Windows machine. Thus it is worth asking ourselves "What is challenging, interesting, and inspiring about Internet-based applications?"
MIT: OpenCourseware The Andrew W. Mellon Foundation and the William and Flora Hewlett Foundation will fund the first phase of MIT OpenCourseWare, the Massachusetts Institute of Technology's bold initiative to make nearly all of its course materials available for free on the World Wide Web.
Developed a perl staging mechanism that acted as a web site staging mechanissm when used in conjunction with Dreamweaver. This script filters pages and publishes them to a live server after an editorial process is completed. This was developed as a low-cost, easily maintained alternative to complicated content management software. This is currently in use by the Joslin Diabetes Clinic, for whom this was developed. This is version 2, which added the functionality of using FTP to move files to a remote server. The earlier version is here.
#!/usr/bin/perl
#
# stage.pl
# Greg Rushton
# http://www.gregrushton.com/
#
# Modified, June 2001
# Added remote FTP capability
use File::Copy;
use File::Path;
use CGI::Carp qw(fatalsToBrowser);
use Net::FTP;
&config;
&get_template;
&parse_form;
if ($FORM{request_type} eq "review") {
&send_review;
$body = "Your submission was successfully
submitted.<p><small>$now</small>";
&reply_html ($body);
}
if ($FORM{request_type} eq "publish") {
&send_publish;
$body = "Your submission was successfully
submitted.<p><small>$now</small>";
&reply_html ($body);
}
if ($FORM{request_type} eq "approve") {
if ($FORM{password} eq "******") {
&write_new;
$body = "<p><a href=\"$new_url\">
Newly published page</a></p>";
&reply_html ($body);
&send_published;
}
else {
$error = "Sorry, wrong password";
&reply_error ($error);
}
}
if ($FORM{request_type} eq "revise") {
if ($FORM{publisher} == "") {
$from = $FORM{editor};
}
else {
$from = $FROM{publisher};
}
&send_revise;
$body = "Your revision notice was successfully
submitted.<p><<small>$now</small>";
&reply_html ($body);
}
#################################
# This subroutine writes the stripped file
# to its new location outside of the staging
# folder. It just moves the file one directory up
# after stripping out the form area.
# Altered program logic here for FTP capabilities.
# Now, we copy the modified file to the same directory
# and then ftp that new file to the remote site.
# This alters the $new_path variable and adds a
# block for FTP ability.
sub write_new {
# Copy original file to temp location:
open (IN, "< $local_path.$file_name") ||
die "Cant open $local_path.$file_name: $!";
flock (IN, 1) || die "Cant flock $old_path: $!";
while (<IN>) {
push(@page_lines, $_);
}
close (IN);
# Strip the staging form area of the page:
&strip_page (@page_lines);
# And write to the new file.
open (TMP, "> $local_path.$file_name.tmp") ||
die "Cant open $local_path.$file_name.tmp: $!";
flock (TMP, 2) ||
die "Cant flock $local_path.$file_name.tmp: $!";
foreach (@page_lines) {
print TMP $_;
}
close (TMP);
# FTP the new file to the remote server.
$ftp = Net::FTP->new($remote_host, Debug => 0);
$ftp->login($remote_un,$remote_pw);
$ftp->cwd($remote_root.$remote_path);
$ftp->put($local_path.$file_name."tmp",$file_name);
$ftp->quit;
}
#################################
# Strip out the form area of the page
# that calls this script. Run through each
# element of the @page_lines array, and delete
# it if its between the matched comment tags.
sub strip_page {
local($pop_flag=0, $counter=0);
foreach (@page_lines) {
if (m/<!--BEGINPUBFORM-->/) {
$pop_flag = 1;
}
if (m/<!--ENDPUBFORM-->/) {
$pop_flag = 0;
$_ = "";
}
if ($pop_flag){
$_ = "";
}
}
}
#################################
# This subroutine sends out an email to
# the editor after a request for
# review is made.
sub send_review {
open(MAIL,"|$mail_prog -t");
print MAIL "To: $FORM{editor}\n";
print MAIL "From: $FORM{contributor_email}\n";
print MAIL "Subject: Request for Editor Review\n\n";
print MAIL "-" x 75 . "\n\n";
print MAIL "$FORM{contributor_name} has requested that you\n";
print MAIL "review the following page: $referer\n";
print MAIL "for publication. Please review and reply.\n\n";
print MAIL "$now\n";
print MAIL "-" x 75 . "\n\n";
close(MAIL);
}
#################################
# This subroutine sends out an email to
# page authors after a request for
# revisions is made.
sub send_revise {
open(MAIL,"|$mail_prog -t");
print MAIL "To: $FORM{contributor_email}, $FORM{editor}\n";
print MAIL "From: $from\n";
print MAIL "Subject: Revision Notification\n\n";
print MAIL "-" x 75 . "\n\n";
print MAIL "$from has requested revisions \n";
print MAIL "for this page citing the following reasons: \n\n";
print MAIL "$FORM{notes}\n\n";
print MAIL "Please review and re-submit\n";
print MAIL "this page for publication: \n$referer\n\n";
print MAIL "$now\n";
print MAIL "-" x 75 . "\n\n";
close(MAIL);
}
#################################
# This subroutine sends out an email to
# publisher after a request for
# publishing is made.
sub send_publish {
open(MAIL,"|$mail_prog -t");
print MAIL "To: $FORM{publisher}\n";
print MAIL "From: $FORM{editor}\n";
print MAIL "Subject: Request for Publication\n\n";
print MAIL "-" x 75 . "\n\n";
print MAIL "$FORM{editor} has requested that you\n";
print MAIL "review the following page: $referer\n";
print MAIL "for publication. Please review and reply.\n\n";
print MAIL "$now\n";
print MAIL "-" x 75 . "\n\n";
close(MAIL);
}
#################################
# This subroutine sends out an email to
# publisher after a page has been
# successfully published.
sub send_published {
open(MAIL,"|$mail_prog -t");
print MAIL "To: $FORM{editor},$FORM{contributor_email}\n";
print MAIL "From: $FORM{publisher}\n";
print MAIL "Subject: Notice of Publication\n\n";
print MAIL "-" x 75 . "\n\n";
print MAIL "$FORM{publisher} has published
the following page:\n";
print MAIL "$new_url\n";
print MAIL "Please review this page.\n\n";
print MAIL "$now\n";
print MAIL "-" x 75 . "\n\n";
close(MAIL);
}
##################################
# Standard reply html. Pass this subroutine
# the $body variable to customize the returned
# html.
sub reply_html {
$template =~ s/<<title>>/Reply/m;
$template =~ s/<<bodytext>>/<p>$body<\/p>/m;
print "Content-type: text/html", "\n\n";
print $template;
}
##################################
# Standard error html. Uses $error variable
# to hold the error message. Pass this that
# variable to customize the returned html.
sub reply_error {
$template =~ s/<<title>>/Error/m;
$template =~ s/<<bodytext>>/<p>$error<\/p>/m;
print "Content-type: text/html", "\n\n";
print $template;
}
#################################
# The template is stored in /bin/template.html
# This subroutine stores it in $template for
# use by other subroutines. To use it, replace
# <<title>> with a title, and <> with
# text for the body of the page.
sub get_template {
open (TEMPLATE, "$templ_loc") ||
die "Cant open $template: $!";
flock (TEMPLATE, 1) || die "Cant flock $template: $!";
undef $/;
$template = <TEMPLATE>;
close (TEMPLATE) or die "cant close $template: $!";
}
#################################
# standard form parser.
sub parse_form {
# Get the input
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
# Split the name-value pairs
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
}
#################################
# Configuration options set here.
sub config {
$mail_prog = "/usr/lib/sendmail";
$templ_loc = "/path/to/template.html";
$referer = $ENV{'HTTP_REFERER'};
($new_link = $referer) =~ s{/development.site.com/}{/www.joslin.org/};
$body = "";
$new_path = "";
$old_path = "";
$now = localtime(time);
$default_index = "index.html";
$ext_regex = "\.(htm|asp|shtm)";
$remote_host = "www.joslin.org";
$remote_un = "username";
$remote_pw = "******";
$remote_root = "/path/to/remote/root/";
$local_root = "/path/to/local/root/";
# Begin section where file paths and names are determined.
@referers = split /\//, $referer;
# Remove the http://blah.blah.blah/ from the @referers
shift @referers; shift @referers; shift @referers;
# If this is a generic page, the last element of @referers
# should be the name of an html page. If not, it is a
# directory and this page is an index page. Check on a match
# with approved file extenstions, assign appropriate name.
if (@referers[-1] =~ m/$ext_regex/i) {
$file_name = pop (@referers);
} else {
$file_name = $default_index;
}
# Construct the path of the file to move
$local_path = $local_root . join @referers, "/";
$remote_path = $remote_root . join @referers, "/";
$new_url = "http://".$remote_host.$remote_path.$file_name;
}