#!/usr/bin/perl use strict; use CGI qw(:standard); use URI; use HTTP::Daemon; use HTTP::Status; use HTTP::Response; use Socket; use CGI::Cookie; use SocialCalcServersideUtilities; my $datadir = "se2-data/"; my $versionstr = "2.01"; my $jsdir = "/sgi/scjstest/"; # # This whole first section lets this code run either as a CGI script on a server # or standalone on the desktop run from the Perl command line. # # The main processing starts with process_request. # if ($ENV{REQUEST_METHOD}) { # being run as a CGI on a server print "Content-type: text/html\n\n"; my $q = new CGI; print process_request($q); exit; } # running locally - do mini-server my $d = HTTP::Daemon->new ( LocalPort => 6557, Reuse => 1); if (!$d) { print "simpleedit could not start on 127.0.0.1:6557\n"; exit; } print "simpleedit14\nAccess at: http://127.0.0.1:6557/\n"; while (my $c = $d->accept) { # Make sure the request is from our machine if ($c) { my ($port, $host) = sockaddr_in(getpeername($c)); if ($host ne inet_aton("127.0.0.1")) { $c->close; # no - ignore request completely undef($c); next; } } # Process the request while ((defined $c) && (my $r = $c->get_request)) { if ($r->method eq 'POST' || $r->method eq 'GET') { $c->force_last_request; my $uri = $r->uri; if ($uri =~ /favicon/) { # if this is a request for favicon.ico, ignore $c->send_error(RC_NOT_FOUND); next; } if ($uri =~ /\/quit$/) { $c->send_file_response("quitmessage.html"); $c->close; undef($c); exit; } if ($uri =~ /\/([a-z\-0-9]+)\.(gif|js|css)$/) { # ok request $uri = "$1.$2"; $uri = "images/$uri" if $2 eq "gif"; # if ($2 eq "js") { # $res->content_type("text/html; charset=UTF-8"); # } $c->send_file_response($uri); next; } my $resp=""; if ($r->method eq 'POST') { my $q = new CGI($r->content()); $resp = process_request($q) } else { my $q = new CGI($r->uri->query()); $resp = process_request($q) } my $res = new HTTP::Response(200); $res->content_type("text/html; charset=UTF-8"); $res->expires("-1d"); $res->content($resp); $c->send_response($res); } else { $c->send_error(RC_FORBIDDEN); } } $c->close; undef($c); } # # Main routine starts here: # sub process_request { my ($request) = @_; my $q = new CGI($request); my $response; my ($statusmessage); if ($q->param("loadsheet")) { # Ajax request: loadsheet=pagename.sheetname my $fullsheetname = $q->param("loadsheet"); $fullsheetname =~ m/^(.*)\.(.*)$/; my $pagename = $1; my $sheetname = $2; my $page = {}; load_page($q, $pagename, $page); my $sheetstr = $page->{items}{$sheetname}{text}; my $htmlpos = index($sheetstr, "\nHTML:\n"); if ($htmlpos >= 0) { $sheetstr = substr($sheetstr, 0, $htmlpos); } sleep 1; return $sheetstr; } if ($q->param("wikitext")) { # Ajax request: wikitext=wikitext-url-encoded my $wikitext = $q->param("wikitext"); $wikitext = expand_wikitext($wikitext); sleep 1; return $wikitext; } my $pagename = $q->param('pagename'); if ($q->param('newpage')) { $pagename = $q->param('newpagename'); } $pagename =~ s/[^a-zA-Z0-9_\-]*//g; if (!$pagename) { $pagename = "home"; $statusmessage .= "No pagename given - using '$pagename'
"; } if ($q->param('savepageedit')) { my $newstr; $newstr = $q->param('pagetext'); if ($q->param('edittype') eq "clean") { my $page = {}; load_page($q, $pagename, $page); $newstr =~ s/^\[(spreadsheet|datatable|drawing)\:(.+?)\]/"[$1:$2:\n" . $page->{items}{$2}{text} . "\n:$1]"/gme; } open (PAGEFILEOUT, ">$datadir$pagename.page.txt"); print PAGEFILEOUT $newstr; close PAGEFILEOUT; $statusmessage .= "Saved updated page '$pagename'.
"; } if ($q->param("editpage") || $q->param("editrawpage")) { # when one of the "editpage" buttons is pressed return do_editpage($q, $pagename, $statusmessage); } foreach my $p ($q->param) { # go through all the parameters if ($p =~ /^edit(spreadsheet|datatable):(.*)/) { # "editspreadsheet:sheetname" pressed return start_editsheet($pagename, $2, $q, $statusmessage); } if ($p =~ /^editdrawing:(.*)/) { # "editdrawing:sheetname" pressed return start_editdrawing($pagename, $1, $q, $statusmessage); } } if ($q->param('savespreadsheet')) { # save the edited spreadsheet my $page = {}; load_page($q, $pagename, $page); my $pagestr = $page->{raw}; my $sheetname = $q->param('sheetname'); my $sheettype = $page->{items}{$sheetname}{type}; $pagestr =~ s/^\[$sheettype\:$sheetname:.*?\:$sheettype\]/"[$sheettype:$sheetname:\n" . $q->param('newstr') . "\n:$sheettype]"/sme; open (PAGEFILEOUT, ">$datadir$pagename.page.txt"); print PAGEFILEOUT $pagestr; close PAGEFILEOUT; $statusmessage = "Saved updated $sheettype '$sheetname' on page '$pagename'.
"; } $response = do_displaypage($q, $pagename, $statusmessage); # Otherwise, display page return $response; } # # load_page($q, $pagename, \%page) # # Loads the specified page and puts the parts into %page: # # %page{raw} - raw page text # %page{clean} - page text with embedded items' bodies removed # %page{items}{name} - hash with embedded item "name"'s info # %page{items}{name}{text} - text of embedded item's body # %page{items}{name}{type} - type embedded item (e.g., "spreadsheet") # sub load_page { my ($q, $pagename, $page) = @_; $page->{bodies} = {}; open (PAGEFILEIN, "$datadir$pagename.page.txt"); my ($rawstr, $cleanstr); while (my $line = ) { $line =~ s/\r//g; $rawstr .= $line; if ($line =~ m/^\[(spreadsheet|datatable|drawing)\:(.*?)\:/) { my $type = $1; my $name = $2; $page->{items}{$name} = {type => $type, text => ""}; my $itemstr; while (my $sline = ) { $sline =~ s/\r//g; $rawstr .= $sline; last if substr($sline, 0, length($type)+2) eq ":$type]"; $itemstr .= $sline; } $page->{items}{$name}{text} = $itemstr; $cleanstr .= "[$type:$name]\n"; } else { $cleanstr .= $line; } } close PAGEFILEIN; $page->{raw} = $rawstr; $page->{clean} = $cleanstr; return; } # # $response = do_displaypage($q, $pagename, $statusmessage) - Display page # sub do_displaypage { my ($q, $pagename, $statusmessage) = @_; my $response; my $page = {}; load_page($q, $pagename, $page); open (PAGEFILEIN, "$datadir$pagename.page.txt"); my $pagestr; while (my $line = ) { $line =~ s/\r//g; if ($line =~ m/^\[(spreadsheet|datatable|drawing)\:(.*?)\:/) { my $sheettype = $1; my $sheetname = $2; my $sheetstr; while (my $sline = ) { $sline =~ s/\r//g; last if $sline =~ m/^:(spreadsheet|datatable|drawing)]/; $sheetstr .= $sline; } my $htmlpos = index($sheetstr, "\nHTML:\n"); my $html=""; my $localhtml=""; if ($htmlpos >= 0) { $html = substr($sheetstr, $htmlpos+7); $sheetstr = substr($sheetstr, 0, $htmlpos); my $sheet = CreateSheet(); my $parts = DecodeSpreadsheetSave($sheetstr); ParseSheetSave($sheet, $parts->{sheet}); my $context = CreateRenderContext($sheet); $localhtml = RenderSheet($context); } else { $html = "Sheet goes here"; $localhtml = "Sheet goes here"; } $sheetstr = special_chars($sheetstr); $pagestr .= <<"EOF";
$localhtml
EOF } else { $pagestr .= expand_wikitext($line); } } close PAGEFILEIN; $response = <<"EOF"; Simple Page Editor With Spreadsheets $versionstr
SIMPLE SYSTEM FOR EDITING PAGES WITH SPREADSHEETS AND MORE
$statusmessage  
Viewing page: $pagename  
Show item
edit buttons
$pagestr
Pages:
EOF my @pagefiles = glob("$datadir*.page.txt"); # Get list of all pages for (my $pnum=0; $pnum <= $#pagefiles; $pnum++) { $pagefiles[$pnum] =~ m/^(?:.*\/){0,1}(.*).page.txt$/; $response .= ", " if $pnum!=0; $response .= qq!$1!; } $response .= <<"EOF";


EOF return $response; } # # do_editpage($q, $pagename, $statusmessage) - Show page editing display # sub do_editpage { my ($q, $pagename, $statusmessage) = @_; my $response; my $page = {}; load_page($q, $pagename, $page); my $edittype = $q->param("editpage") ? "clean" : "raw"; my $pagestr = special_chars($page->{$edittype}); $response = <<"EOF"; Simple Page Editor With Spreadsheets $versionstr
SIMPLE SYSTEM FOR EDITING PAGES WITH SPREADSHEETS AND MORE
$statusmessage  
Editing page: $pagename
EOF if ($edittype eq "clean") { $response .= <<"EOF"; EOF } $response .= <<"EOF";
EOF return $response; } # # start_editsheet($pagename, $sheetname, $q, $statusmessage) # - render initial editing display # sub start_editsheet { my ($pagename, $sheetname, $q, $statusmessage) = @_; my ($response, $sheetstr); my $page = {}; load_page($q, $pagename, $page); $sheetstr = $page->{items}{$sheetname}{text}; my $htmlpos = index($sheetstr, "\nHTML:\n"); if ($htmlpos >= 0) { $sheetstr = substr($sheetstr, 0, $htmlpos); } $response = <<"EOF"; # output page with edit JS code Simple Page Editor With Spreadsheets $versionstr
SIMPLE SYSTEM FOR EDITING PAGES WITH SPREADSHEETS AND MORE
$statusmessage  
Editing page: $pagename


editor goes here
EOF return $response; } # # start_editdrawing($pagename, $sheetname, $q, $statusmessage) # - render initial editing display # sub start_editdrawing { my ($pagename, $sheetname, $q, $statusmessage) = @_; my ($response, $sheetstr); my $page = {}; load_page($q, $pagename, $page); $sheetstr = $page->{items}{$sheetname}{text}; $response = <<"EOF"; # output page with edit JS code Simple Page Editor With Spreadsheets $versionstr
SIMPLE SYSTEM FOR EDITING PAGES WITH SPREADSHEETS AND MORE
$statusmessage  
Editing page: $pagename
EOF return $response; } # # # # # # # # # # # special_chars($string) # # Returns $estring where &, <, >, " are HTML escaped # sub special_chars { my $string = shift @_; $string =~ s/&/&/g; $string =~ s//>/g; $string =~ s/"/"/g; return $string; } # # decode_from_ajax($string) - Returns a string with # \n, \b, and \c escaped to \n, \, and : # sub decode_from_ajax { my $string = shift @_; $string =~ s/\\n/\n/g; $string =~ s/\\c/:/g; $string =~ s/\\b/\\/g; return $string; } # # encode_for_ajax($string) - Returns a string with # \n, \, :, and ]]> escaped to \n, \b, \c, and \e # sub encode_for_ajax { my $string = shift @_; $string =~ s/\\/\\b/g; $string =~ s/\n/\\n/g; $string =~ s/\r//g; $string =~ s/:/\\c/g; $string =~ s/]]>/\\e/g; return $string; } # # expand_wikitext($string) - Returns $string doing wiki-style formatting # sub expand_wikitext { my $string = shift @_; # Process forms that use URL encoding first # [page:pagename text] to link to other pages on this site $string =~ s!\[page:(.+?)\s+(.+?)?]!'{{lt}}a href={{quot}}?pagename=' . $1 . "{{quot}}{{gt}}$2\{{lt}}/a{{gt}}"!xegs; # [url:url text] to link to other pages on other sites $string =~ s!\[url:(.+?)\s+(.+?)?]!'{{lt}}a href={{quot}}' . $1 . "{{quot}} target={{quot}}_blank{{quot}}{{gt}}$2\{{lt}}/a{{gt}}"!xegs; # Convert &, <, >, " $string = special_chars($string); $string =~ s/^\= (.*) \=$/$1<\/span>/gs; $string =~ s/\n/
/g; # Line breaks are preserved $string =~ s/('*)'''(.*?)'''/$1$2<\/b>/gs; # Wiki-style bold/italics $string =~ s/''(.*?)''/$1<\/i>/gs; $string =~ s/\{\{amp}}/&/gs; # {{amp}} for ampersand $string =~ s/\{\{lt}}//gs; # {{gt}} for greater than $string =~ s/\{\{quot}}/"/gs; # {{quot}} for quote $string =~ s/\{\{lbracket}}/[/gs; # {{lbracket}} for left bracket $string =~ s/\{\{rbracket}}/]/gs; # {{rbracket}} for right bracket $string =~ s/\{\{lbrace}}/{/gs; # {{lbrace}} for brace return $string; }