#!/usr/bin/perl -w use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); $error=''; $mailprog = '/usr/sbin/sendmail'; $recipient = 'js3104@nyu.edu'; ## COMMON HTML ELEMENTS $type="Content-type: text/html\n\n"; $htmlheader = " My Topics Page

My Wiki Topics

"; $formheader= '

'; $formfooter= '
'; $htmlfooter = ""; # CHECK IF THE SCRIPT WAS ACTIVATED VIA A LINK AND THE URL CONTAINS A TOPIC TO VIEW if (length ($ENV{'QUERY_STRING'}) > 0){ $buffer = $ENV{'QUERY_STRING'}; @pairs = split(/&/, $buffer); foreach $pair (@pairs){ ($name, $val) = split(/=/, $pair); $q{$name}=$val; } $topic=$q{'topp'}; if (index($topic, ":") == -1 ){ # LINK FROM A VIEW PAGE (TOPIC NAME) &view_page($topic); } else { $topic_name=$topic; $topic_rev=$topic; # LINK FROM A SEARCH PAGE (TOPIC NAME + REV) $topic_name=~ s/(.*):.*/$1/; $topic_rev=~ s/.*:(.*)/$1/; &view_rev_page($topic_name, $topic_rev); } } else{ $lastform=param("formname"); # USE A HIDDEN FORM FIELD TO KEEP STATE $page=param('action1') || "home"; # SCREEN NAVIGATION if ($page eq "upload photos"){ print "Location: https://cs.nyu.edu/~js3104/cgi-bin/unixtool/photoupload.html\n\n"; } elsif ($page eq "home" && ($lastform eq '' || $lastform eq 'statistics') ){ &home_page(); } elsif ($page eq "home" && $lastform eq "view"){ &home_page(param("topicname")); } elsif ($page eq "preview" && $lastform eq "edit"){ &preview_page(param("topicname")); } elsif ($page eq "submit" && $lastform eq "revisions"){ # REVISIONS PROCESSING @lrev=param('revisionsl'); if ($#lrev == 0 ){ # ONE REVISION SELECTED &view_rev_page(param('topicname'), $lrev[0]); } elsif ($#lrev == 1){ # TWO REVISIONS SELECTED &compare_rev_page(param('topicname'), $lrev[0], $lrev[1]); } elsif ($#lrev > 1){ $error1=" Please select 1 to view/edit or 2 to compare"; $error=" Too many revisions selected.".$error1; &revisions_page(param("topicname")); } } elsif ($page eq "delete" && $lastform eq "revisions"){ @lrev=param('revisionsl'); &delete_rev(param('topicname'), $lrev[0]); } elsif ($page eq "submit" && $lastform eq "home" && param('revisions') ne ""){ &revisions_page(param("topicname")); } elsif ( ($page eq "cancel" && $lastform eq "revview") || ($page eq "revisions" && $lastform eq "compare")){ &revisions_page(param("topicname")); } elsif ($page eq "submit" && $lastform eq "home" && param('viewedit') eq "edit"){ &edit_page(param("topicname")); } elsif ($page eq "submit" && $lastform eq "home" && param('viewedit') eq "view"){ &view_page(param("topicname")); } elsif ($page eq "cancel" && $lastform eq "preview" ){ &edit_page(param("topicname"), param("origtext")); } elsif ($page eq "cancel" && $lastform eq "edit"){ &home_page(param("topicname")); } elsif ($page eq "cancel" && $lastform eq "revisions"){ &home_page(param("topicname")); } elsif ($page eq "save" ){ &edit_page(param("topicname"),param("origtext")); } elsif ($page eq "edit" && $lastform eq "view" ){ &edit_page(param("topicname")); } elsif ($page eq "FIND"){ &search_keyword(param('keyword'), param('topicname')); } elsif ($page eq "home" && $lastform eq "search"){ &home_page("", param('searchkey')); } elsif ($page eq "GO"){ $top=param("popular"); if (param('revisions') ne ""){ &revisions_page($top); } elsif (param('viewedit') eq "edit"){ &edit_page($top); } else{ &view_page($top); } } elsif ($page eq "BROWSE"){ &search_topic(param('topicbyname')); } elsif ($page eq "home" && $lastform eq "searchtopic"){ &home_page("", "",param('searchtkey')); } elsif ($page eq "statistics"){ &statistics_page(); } } exit(); #-------------------------------------------------------------------------------------------------- sub home_page { ############# THE FIRST PAGE DISPLAYS A SIMPLE INTERFACE $topic_n=$_[0]; my $last_search=$_[1]; my $searchtt=$_[2]; $instructions= "
USAGE:
1. Choose View or Edit (edit can create a new topic or add revision)
2. Enter topic name (existing for view), or select from recent edits
3. (Optionally check revisions) Press Submit
4. A topic may be selected from the popular list for View/Edit/Revisions
* For keyword across topics, use bottom search, top for topic name (regex) *
"; $screen="

HOME

"; open (RECEDIT, "; # BUILD POPULAR TOPIC LIST my $command2="/home/js3104/simplestore lookup N15928458/mostviewed"; my @pop_topics=`$command2`; &arrange_popular(@pop_topics); ## CREATING THE PAGE print "$type"; print "$htmlheader"; print "$formheader"; print ""; print "$screen"; print ""; print "$instructions"; print "

"; # ADD POPULAR TOPIC DROP-DOWN print "
"; print ""; print "   "; print "Popular: "; print ""; print "                        Search name:
"; ## print "


"; ### print "$instructions"; print "



"; print ""; if ($last_search ne ""){ print ""; } else { print ""; } print ""; print "
"; if ( param("viewedit") eq "view"){ # TOGGLE BETWEEN VIEW AND EDIT print " View Edit
"; } else{ print " View Edit
"; } print "
   SEARCH keyword across topics
"; if ( $topic_n eq "" ){ print "

Topic Name: "; } else{ print "

Topic Name: "; } print "

"; print "   revisions   
   
          "; print "              "; print "      "; print "
"; print ""; print "
Recent Edits "; print "          "; print submit(-NAME=>"action1", -VALUE=>"submit"); print "
"; if ($error ne ''){ print p("$error"); } print "$formfooter"; print ""; print "


$htmlfooter"; } #-------------------------------------------------------------------------------------------------- sub edit_page { ############# THIS SUBROUTINE DISPLAYS THE "EDIT" PAGE $topic_n=param('recent') || $_[0]; $txt=""; if (param("action1") eq "submit" && $topic_n eq ''){ # CHECK LEGALITY OF TOPIC NAME $error="Topic name not entered"; &home_page(); exit(); } if ($lastform eq "home" || $lastform eq "view"){ $ret= alphanum($topic_n); if (!$ret){ # CHECK IF TOPIC ALPHANUMERIC $error="Topic name is not alphanumeric"; home_page($topic_n); exit(); } # LOCATE TOPIC my $command="/home/js3104/simplestore lookup N15928458/topic/$topic_n"; my @keylist=`$command`; @keylist= sort reverse_numerically @keylist; my $mostrecentkey=$keylist[0]; $command="/home/js3104/simplestore lookup N15928458/topic/$topic_n/$mostrecentkey"; my $foundtext=`$command`; if ( "$?" == 0 ){ ## simplestore FOUND THE TOPIC IN THE DATABASE $txt=$foundtext; } else{ $error="New topic, please type in the text in the white area"; } $topicn=$topic_n; } elsif ($lastform eq "preview" && $page eq "cancel"){ # IF WE CANCELED FROM 'PREVIEW', SHOW BACK THE TOPIC NAME & EDITTED CONTENT if ($_[0] ne ""){ $topicn=$_[0]; $txt=$_[1]; } $error="Back from preview"; } elsif ($page eq "save"){ $topicn=$_[0]; $txt=$_[1]; &check_dup($topicn, $txt);# SAVE ONLY UNIQUE REVISIONS OF A TOPIC. if ($dup == 0){ $topictime=time(); # EPOCH TIME WILL BE THE KEY (IN SECONDS GRANULARITY) # WRITE A NEW VERSION (OR FIRST) OF A TOPIC @args = ("/home/js3104/simplestore", "write", "N15928458/topic/$topicn/$topictime", "$txt"); system(@args); # == 0 or die "system @args failed: $? $!"; # DEBUG PURPOSE if ( "$?" != 0 ){ $error="Cannot update topic at the moment, please try later"; } else{ $error="save successful!"; &add_to_recent($topicn); &mailnotify($topicn, param('emailadd')); } } else { $error="An identical topic content exists. No new Version created."; } } ## WE ARE READY TO DISPLAY THE PAGE NOW $screen="

EDIT


"; print "$type"; print "$htmlheader"; print "$formheader"; print "$screen"; $einstructions= "
USAGE:
1. Type/Edit document
2. Click preview to see HTML formatting
3. cancel takes you back to the home page
4. reset! - erases \"just typed\" text (not after preview)
"; print "$einstructions"; print "

Topic Name:

"; print '

'; print ""; print '

'; print "
"; print submit(-NAME =>"action1", -VALUE=>"preview"); print ""; print submit(-NAME =>"action1", -VALUE=>"cancel"); print ""; print ""; print "
"; print ""; print p("$error"); print endform; ## PUT THE FOCUS ON THE CONTENT print ""; print end_html; } #-------------------------------------------------------------------------------------------------- sub preview_page{ # PRESENT TOPIC CONTENT AS HTML DOCUMENT $screen="


PREVIEW


"; $topicn=$_[0]; $text_convert=param("topiccont"); if ( $text_convert eq ""){ $error="No text to preview, please enter some text."; edit_page($_[0]); exit(); } else{ $preview_text=""; # GLOBAL VARIABLE TO KEEP THE HTML FORMATTED TEXT &convert_t_html($text_convert); &create_hyperlinks($text_convert); print "$type"; print "$htmlheader"; print "$formheader"; print "$screen"; print "

Topic Name:

"; print "$preview_text"; # CONVERTED TEXT print ""; print ""; print '
'; print '

'; print ""; print "
"; print ""; print ""; print "Email to notify: save will send E-mail
"; print submit(-NAME =>"action1", -VALUE=>"save"); print submit(-NAME =>"action1", -VALUE=>"cancel"); print p("$error"); print endform; print end_html; } } #--------------------------------------------------------------------------------------------------- sub view_page { ############# THIS SUBROUTINE DISPLAYS THE "VIEW" PAGE $topic_n=param('recent') || $_[0]; if (param("action1") eq "submit" && $topic_n eq ''){ # CHECK LEGALITY OF TOPIC NAME $error="Topic name not entered"; &home_page(); exit(); } $ret=alphanum($topic_n); if (!$ret){ $error="Topic name is not alphanumeric"; home_page($topic_n); exit(); } else{ ## PASSED ALPHANUMERIC TEST ## ACTIVATE simplestore my $command="/home/js3104/simplestore lookup N15928458/topic/$topic_n"; my @keylist=`$command`; my @keylist= sort reverse_numerically @keylist; # REVERSE SORT my $mostrecentkey=$keylist[0]; # HIGHEST KEY IS TOPIC'S CURRENT VERSION $command="/home/js3104/simplestore lookup N15928458/topic/$topic_n/$mostrecentkey"; my $foundtext=`$command`; $EPOCH=$mostrecentkey; if ( "$?" != 0 ){ # TOPIC MUST EXIST IN ORDER TO VIEW IT $error="Topic is not found on the Database, perhaps misspelled, or select edit, for a new one."; home_page($topic_n); exit(); } else{ ### TOPIC IS FOUND, PRESENT IT IN HTML $date_created=scalar(localtime($EPOCH)); $screen="


VIEW

                                       Last modified: $date_created

"; if ( $foundtext eq ""){ $error="Topic does not contain any text."; home_page($topic_n); exit(); } else{ # RECORD ONE MORE VIEWING FOR THIS TOPIC $topicview= $topic_n . "count"; $command="/home/js3104/simplestore increment N15928458/mostviewed/$topicview 1"; $try=`$command`; $preview_text=""; convert_t_html($foundtext); # HTML CONVERSION &create_hyperlinks($foundtext); print "$type"; print "$htmlheader"; print "$formheader"; print "$screen"; print "

Topic Name:

"; print "$preview_text"; # CONVERTED TEXT print ""; print ""; print '

'; print submit(-NAME =>"action1", -VALUE=>"home"); print submit(-NAME =>"action1", -VALUE=>"edit"); print p("$error"); print endform; print end_html; } } } } #--------------------------------------------------------------------------------------------------- sub alphanum { # CHECKS IF A STRING IS ALPHANUMERIC my $val=$_[0]; $val=~ /^[a-zA-Z0-9]+$/; } #--------------------------------------------------------------------------------------------------- sub convert_t_html{ my $topic_text=$_[0]; my @lines=split(/\r\n/,$topic_text); # HERE IS THE ORDER OF CONVERSION IN ORDER foreach $line (@lines) { # TO AVOID INTERFERENCE WITH HTML TAGS: $line=~ s/&/&/g; # FIRST CONVERT &, SO NO CONFLICT $line=~ s//>/g; # LATTER TWO if ($line=~ /^---([\+]{1,3}) (.*$)/){ $p=length($1); $new_line=""."$2".""; } else{ $new_line=$line; } $new_line=~ s/\*([^\*]+)\*/$1<\/b>/g; # CONVERT TO BOLD TEXT $new_line=~ s/_([^_]+)_/$1<\/i>/g; # CONVERT TO ITALICS $new_line=~ s/^\s*$/

<\/p>/; # EMPTY LINE CONVERT TO

# EMBED IMAGES $new_line=~ s/(.*)img:url:(.*):(.*)/$1

<\/p>/g; push(@newtext,$new_line); # THIS DONE AT THE END. $line=~ /()()/; # RESET $1, $2 FOR NEXT ITERATION } &convert_bullet(); $preview_text=join "\n", @afterbullet; } #--------------------------------------------------------------------------------------------------- sub reverse_numerically { $b <=> $a } #--------------------------------------------------------------------------------------------------- sub numerically { $a <=> $b } #--------------------------------------------------------------------------------------------------- sub check_dup{ # CHECK IF ANOTHER VERSION IS IDENTICAL TO THE ONE BEING SAVED ############# $comm="/home/js3104/simplestore lookup N15928458/topic/$_[0]"; @keys=`$comm`; $dup=0; $str1=$_[1]; $str1=~ s/\s//g; # TRIM ALL INVISIBLE CHARACTER TO MAKE THE COMPARE MEANINGFUL foreach(@keys){ $comm1="/home/js3104/simplestore lookup N15928458/topic/$_[0]/$_"; $str2=`$comm1`; chomp($str2); $str2=~ s/\s//g; if ($str1 eq $str2){ $dup=1; last; } } } #--------------------------------------------------------------------------------------------------- sub create_hyperlinks{ ## CREATING THE PAGE #print "$type"; #print "$htmlheader"; #print "$formheader"; $original=$_[0]; # Orig text @lines= split "\n", $preview_text; # THE HTML PREVIOUSLY GENERATED @olines= split "\r\n", $original; foreach(@olines){ $temp=$_; #print "

$temp"; $temp=~ s/[^A-Za-z0-9]/ /g; @words= split /\s+/, $temp; foreach(@words){ # NOW CHECK FOR EVERY WORD IF IT IS A TOPIC $ret= alphanum($_); if ($ret){ my $command="/home/js3104/simplestore lookup N15928458/topic/$_ | wc -l"; my $keys=`$command`; if ($keys > 0 ){ # WORD IS A TOPIC ON THE DB $topic_link{"$_"}=$_; # CREATE A HASH OF TOPICS FOUND IN TEXT } } } } while (($word_link, $value) = each %topic_link ){ # MAKE THOSE TOPICS HYPERLINKS $preview_text=~ s/(.*)($word_link)(.*)/ $1$2<\/a>$3/g; } } #--------------------------------------------------------------------------------------------------- sub revisions_page { ################# DISPLAY PAGE THAT ALLOWS TO SELECT REVISION TO VIEW/EDIT/COMPARE $topicn=param('recent') || $_[0]; $begin_r_list=""; my $rinstructions= "
USAGE:
1. Select one revision to view or 2 revisions to compare
2. To select 2 revisions hold the ctrl (apple on Mac) and click revision #
3. Hit submit. To go back home, hit cancel
*** The top revision is always the latest (highest number) ***
"; $screen="


REVISIONS


"; if (param("action1") eq "submit" && $topicn eq ''){ # CHECK LEGALITY OF TOPIC NAME $error="Topic name not entered"; &home_page(); exit(); } $ret=alphanum($topicn); if (!$ret){ $error="Topic name is not alphanumeric"; $topic_n=$topicn; home_page($topic_n); exit(); } else{ ## PASSED ALPHANUMERIC TEST ## ACTIVATE simplestore my $command="/home/js3104/simplestore lookup N15928458/topic/$topicn"; my @keylist=`$command`; if ( "$?" == 0 ){ @keylist= sort numerically @keylist; # ASCENDING SORT (FIRST KEY OLDEST) $revcount=0; $revstring=""; foreach $rev1 (@keylist){ $revision{"$revcount"}="$rev1"; $revstring .="$revision{\"$revcount\"}"."#"."$revcount"."*"; ++$revcount; } $revstring=~ s/\s+//g; } else{ $error="Topic not found on the Database"; home_page($topicn); exit(); } } # PREPARE REVISION LIST $rev_num= keys %revision; $latest=$rev_num-1; $r_list=""; --$latest; while( $latest >= 0){ $r_list .=""; --$latest; } my $table_ver_s= "
Topic Name: Revisions: "; my $table_ver_m="
"; my $table_ver_e="
"; ## CREATING THE PAGE print "$type"; print "$htmlheader"; print "$formheader"; print "$screen"; print "$rinstructions"; print "



"; print "$table_ver_s"; print $begin_r_list; print $r_list; print $end_r_list; print $table_ver_m; print submit(-NAME=>"action1", -VALUE=>"submit"); print submit(-NAME=>"action1", -VALUE=>"cancel"); print submit(-NAME=>"action1", -VALUE=>"delete"); print $table_ver_e print ""; print ""; print ""; print "

"; if ($error ne ''){ print p("$error"); } print "$formfooter"; print "


$htmlfooter"; } #--------------------------------------------------------------------------------------------------- sub view_rev_page{ $topicn=$_[0]; $key_selected=$_[1]; my $command="/home/js3104/simplestore lookup N15928458/topic/$topicn/$key_selected"; $EPOCH=$key_selected; my $text_convert=`$command`; # RECORD ONE MORE VIEWING FOR THIS TOPIC $topicview= $topicn . "count"; $command="/home/js3104/simplestore increment N15928458/mostviewed/$topicview 1"; $try=`$command`; $preview_text=""; # GLOBAL VARIABLE TO KEEP THE HTML FORMATTED TEXT convert_t_html($text_convert); &create_hyperlinks($text_convert); print "$type"; print "$htmlheader"; print "$formheader"; $date_created=scalar(localtime($EPOCH)); $screen="

REVISION VIEW

                                       Last modified: $date_created

"; print "$screen"; print "

Topic Name:

"; print "$preview_text"; # CONVERTED TEXT print ""; print ""; print '

'; print submit(-NAME =>"action1", -VALUE=>"cancel"); print p("$error"); print endform; print end_html; } #--------------------------------------------------------------------------------------------------- sub compare_rev_page{ $topicn=$_[0]; $revs[0]=$_[1]; $revs[1]=$_[2]; my $revkeys=param('allrevs'); my @keyrev=split /\*/, $revkeys; foreach $keyrev1 (@keyrev){ @temp=(); @temp=split /#/, $keyrev1; $keys1{"$temp[0]"}=$temp[1]; } @revs=sort numerically @revs; # THE OLDER FILE WILL BE FIRST, THE NEWER SECOND my $command1= "/home/js3104/simplestore lookup N15928458/topic/$topicn/$revs[0]"; my $command2= "/home/js3104/simplestore lookup N15928458/topic/$topicn/$revs[1]"; $file1=`$command1`; $file2=`$command2`; @oldf= split /\n/, $file1; @newf= split /\n/, $file2; chomp(@oldf); chomp(@newf); # CREATE TEMPORARY FILES, IN ORDER TO USE diff COMMAND open (OUT1,">tmp/$revs[0]"); open (OUT2,">tmp/$revs[1]"); print OUT1 $file1; print OUT2 $file2; $comprev=`diff -e tmp/$revs[0] tmp/$revs[1]`; @comparr= split /\n/, $comprev; chomp(@comparr); $screen="


COMPARE


"; print "$type"; print "$htmlheader"; print "$formheader"; print "$screen"; print "

"; print "

Topic Name:

"; print ""; print ""; print ""; print "
OLDER REVISION ($keys1{$revs[0]}) NEWER REVISION ($keys1{$revs[1]})
"; foreach (@oldf){ print $_; print "
"; } print "
"; foreach (@newf){ print $_; print "
"; } print "
HERE IS A SET OF INSTRUCTIONS (ed script) TO CHANGE FROM THE OLD TO NEW
"; foreach (@comparr){ print $_; print "
"; } print "
"; $error="Legend: number is line in the old revision. a for append, c for change, d for delete."; print submit(-NAME =>"action1", -VALUE=>"revisions"); print ""; print p("$error"); print endform; print end_html; # CLEAN UP TEMPORARY FILES $command01="rm tmp/$revs[0]"; `$command01`; $command02="rm tmp/$revs[1]"; `$command02`; } #--------------------------------------------------------------------------------------------------- sub convert_bullet{ ################## CONVERT SYMBOLS OF :(c|d|s): TO BULLETED LIST ################## THE TERM :c: MUST BE BY ITSELF ON A LINE, THEN EACH CONSECUTIVE LINE IS ################## A BULLET UNTIL A LINE THAT STARTS WITH // IS ENCOUNTERED, OR IT IS THE END ################## OF THE TEXT. ANYTHING AFTER THE // ON THE SAME LINE IS IGNORED. $maxlines=$#newtext; $i=0; while ($i <= $maxlines){ if ($newtext[$i] !~ /^ *:(c|s|d): *$/){ push (@afterbullet, $newtext[$i]); ++$i; } else{ if ($1 eq "c"){ $bul="circle"; } elsif ($1 eq "d"){ $bul="disc"; } else{ $bul="square"; } $newtext[$i]=~ s/^ *:(c|s|d): *$/