Annotation of rat/lonratsrv.pm, revision 1.34

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Server for RAT Maps
                      3: #
1.34    ! albertel    4: # $Id: lonratsrv.pm,v 1.33 2005/09/26 19:47:52 albertel Exp $
1.16      www         5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
1.1       www        28: 
                     29: package Apache::lonratsrv;
                     30: 
                     31: use strict;
                     32: use Apache::Constants qw(:common);
1.2       www        33: use Apache::File;
                     34: use HTML::TokeParser;
1.30      albertel   35: use Apache::lonnet;
1.2       www        36: 
1.4       www        37: # ------------------------------------------------------------- From RAT to XML
1.2       www        38: 
                     39: sub qtescape {
                     40:     my $str=shift;
1.34    ! albertel   41:     $str=~s/\:/\:/g;
1.4       www        42:     $str=~s/\&\#58\;/\:/g;
                     43:     $str=~s/\&\#39\;/\'/g;
                     44:     $str=~s/\&\#44\;/\,/g;
1.15      www        45:     $str=~s/\"/\&\#34\;/g;
1.2       www        46:     return $str;
                     47: }
                     48: 
1.4       www        49: # ------------------------------------------------------------- From XML to RAT
1.2       www        50: 
1.4       www        51: sub qtunescape {
1.2       www        52:     my $str=shift;
1.14      www        53:     $str=~s/\:/\&colon\;/g;
1.4       www        54:     $str=~s/\'/\&\#39\;/g;
                     55:     $str=~s/\,/\&\#44\;/g;
                     56:     $str=~s/\"/\&\#34\;/g;
1.2       www        57:     return $str;
                     58: }
                     59: 
                     60: # --------------------------------------------------------- Loads map from disk
                     61: 
                     62: sub loadmap {
1.28      www        63:     my ($fn,$errtext,$infotext)=@_;
                     64:     if ($errtext) { return('',$errtext); }
1.2       www        65:     my $outstr='';
                     66:     my @obj=();
                     67:     my @links=();
1.21      www        68:     my $instr='';
                     69:     if ($fn=~/^\/*uploaded\//) {
                     70:         $instr=&Apache::lonnet::getfile($fn);
                     71:     } elsif (-e $fn) {
                     72:         my @content=();
1.2       www        73:         {
                     74: 	    my $fh=Apache::File->new($fn);
                     75:             @content=<$fh>;
                     76:         }
1.21      www        77:         $instr=join('',@content);
                     78:     }
1.25      albertel   79:     if ($instr eq -2) {
                     80:         $errtext.='Map not loaded: An error occured while trying to load the map.';
                     81:     } elsif ($instr) {
1.2       www        82:         my $parser = HTML::TokeParser->new(\$instr);
                     83:         my $token;
                     84:         my $graphmode=0;
                     85: 
                     86:         $fn=~/\.(\w+)$/;
                     87:         $outstr="mode<:>$1";
                     88: 
                     89:         while ($token = $parser->get_token) {
                     90: 	    if ($token->[0] eq 'S') {
                     91:                 if ($token->[1] eq 'map') {
                     92: 		    $graphmode=($token->[2]->{'mode'} eq 'rat/graphical');
                     93:                 } elsif ($token->[1] eq 'resource') {
1.3       www        94: # -------------------------------------------------------------------- Resource
                     95:                     $outstr.='<&>objcont';
1.33      albertel   96:                     if (defined($token->[2]->{'id'})) {
1.3       www        97: 			$outstr.='<:>'.$token->[2]->{'id'};
                     98:                         if ($obj[$token->[2]->{'id'}]==1) {
                     99:                            $errtext.='Error: multiple use of ID '.
                    100:                                      $token->[2]->{'id'}.'. ';
                    101:                         }
                    102:                         $obj[$token->[2]->{'id'}]=1; 
                    103:                     } else {
                    104:                         my $i=1;
                    105:                         while (($i<=$#obj) && ($obj[$i]!=0)) { $i++; }
                    106:                         $outstr.='<:>'.$i;
                    107:                         $obj[$i]=1;
                    108:                     }
                    109:                     $outstr.='<:>';
1.4       www       110:                     $outstr.=qtunescape($token->[2]->{'title'}).":";
                    111:                     $outstr.=qtunescape($token->[2]->{'src'}).":";
1.14      www       112:                     if ($token->[2]->{'external'} eq 'true') {
1.4       www       113:                         $outstr.='true:';
                    114:                     } else {
                    115:                         $outstr.='false:';
                    116:                     }
1.33      albertel  117:                     if (defined($token->[2]->{'type'})) {
1.4       www       118: 			$outstr.=$token->[2]->{'type'}.':';
                    119:                     }  else {
                    120:                         $outstr.='normal:';
                    121:                     }
1.31      www       122: 		    if ($token->[2]->{'type'} ne 'zombie') {
                    123: 			$outstr.='res';
                    124: 		    } else {
                    125:                         $outstr.='zombie';
                    126: 		    }
1.2       www       127:                 } elsif ($token->[1] eq 'condition') {
1.3       www       128: # ------------------------------------------------------------------- Condition
                    129:                     $outstr.='<&>objcont';
1.33      albertel  130:                     if (defined($token->[2]->{'id'})) {
1.3       www       131: 			$outstr.='<:>'.$token->[2]->{'id'};
                    132:                         if ($obj[$token->[2]->{'id'}]==1) {
                    133:                            $errtext.='Error: multiple use of ID '.
                    134:                                      $token->[2]->{'id'}.'. ';
                    135:                         }
                    136:                         $obj[$token->[2]->{'id'}]=1; 
                    137:                     } else {
                    138:                         my $i=1;
                    139:                         while (($i<=$#obj) && ($obj[$i]!=0)) { $i++; }
                    140:                         $outstr.='<:>'.$i;
                    141:                         $obj[$i]=1;
                    142:                     }
                    143:                     $outstr.='<:>';
1.4       www       144:                     $outstr.=qtunescape($token->[2]->{'value'}).':';
1.33      albertel  145:                     if (defined($token->[2]->{'type'})) {
1.4       www       146: 			$outstr.=$token->[2]->{'type'}.':';
                    147:                     } else {
                    148:                         $outstr.='normal:';
                    149:                     }
                    150:                     $outstr.='cond';
1.2       www       151:                 } elsif ($token->[1] eq 'link') {
1.3       www       152: # ----------------------------------------------------------------------- Links
1.2       www       153:                     $outstr.='<&>objlinks';
1.7       www       154: 
1.33      albertel  155:                         if (defined($token->[2]->{'index'})) {
1.4       www       156: 			   if ($links[$token->[2]->{'index'}]) {
                    157:                                $errtext.='Error: multiple use of link index '.
1.3       www       158: 			       $token->[2]->{'index'}.'. ';
1.4       www       159:                            }
                    160: 			   $outstr.='<:>'.$token->[2]->{'index'};
                    161:                            $links[$token->[2]->{'index'}]=1;
                    162:                         } else {
                    163:                            my $i=1;
                    164:                            while (($i<=$#links) && ($links[$i]==1)) { $i++; }
                    165:                            $outstr.='<:>'.$i;
                    166:                            $links[$i]=1;
                    167: 		       }
1.7       www       168: 		    
1.2       www       169:                     $outstr.='<:>'.$token->[2]->{'from'}.
1.5       www       170:                              ':'.$token->[2]->{'to'};
1.33      albertel  171:                     if (defined($token->[2]->{'condition'})) {
1.5       www       172: 			$outstr.=':'.$token->[2]->{'condition'};
1.2       www       173:                     } else {
1.5       www       174:  			$outstr.=':0';
1.4       www       175:                     }
1.11      www       176: # ------------------------------------------------------------------- Parameter
                    177:                 } elsif ($token->[1] eq 'param') {
                    178:                     $outstr.='<&>objparms<:>'.$token->[2]->{'to'}.'<:>'.
1.13      www       179:                             $token->[2]->{'type'}.'___'.$token->[2]->{'name'}
1.11      www       180:                                                  .'___'.$token->[2]->{'value'};
1.2       www       181:                 } elsif ($graphmode) {
1.3       www       182: # --------------------------------------------- All other tags (graphical only)
                    183:                     $outstr.='<&>'.$token->[1];
1.4       www       184:                     if (defined($token->[2]->{'index'})) {
1.3       www       185: 			$outstr.='<:>'.$token->[2]->{'index'};
                    186:                         if ($token->[1] eq 'obj') {
                    187: 			    $obj[$token->[2]->{'index'}]=2;
                    188:                         }
                    189:                     }
                    190:                     $outstr.='<:>'.$token->[2]->{'value'};
1.2       www       191:                 }
                    192:             }
                    193:         }
                    194: 
                    195:     } else {
1.3       www       196:         $errtext.='Map not loaded: The file does not exist. ';
1.2       www       197:     }
1.28      www       198:     return($outstr,$errtext,$infotext);
1.2       www       199: }
                    200: 
                    201: 
                    202: # ----------------------------------------------------------- Saves map to disk
                    203: 
                    204: sub savemap {
1.20      albertel  205:     my ($fn,$errtext)=@_;
1.28      www       206:     my $infotext='';
1.13      www       207:     my %alltypes;
                    208:     my %allvalues;
1.22      www       209:     if (($fn=~/\.sequence(\.tmp)*$/) ||
                    210:         ($fn=~/\.page(\.tmp)*$/)) {
1.4       www       211: 
1.2       www       212: # ------------------------------------------------------------- Deal with input
1.30      albertel  213:         my @tags=split(/<&>/,$env{'form.output'});
1.2       www       214:         my $outstr='';
                    215:         my $graphdef=0;
                    216:         if ($tags[0] eq 'graphdef<:>yes') {
                    217: 	    $outstr='<map mode="rat/graphical">'."\n";
                    218:             $graphdef=1;
                    219:         } else {
                    220:             $outstr="<map>\n";
                    221:         }
1.23      www       222:         foreach (@tags) {
1.2       www       223: 	   my @parts=split(/<:>/,$_);
                    224:            if ($parts[0] eq 'objcont') {
                    225:                my @comp=split(/:/,$parts[$#parts]);
                    226: # --------------------------------------------------------------- Logical input
1.31      www       227: 	       if (($comp[$#comp] eq 'res') || ($comp[$#comp] eq 'zombie')) {
1.4       www       228:                    $comp[0]=qtescape($comp[0]);
                    229:                    $comp[1]=qtescape($comp[1]);
1.2       www       230:                    if ($comp[2] eq 'true') {
                    231: 		       if ($comp[1]!~/^http\:\/\//) {
                    232: 			   $comp[1]='http://'.$comp[1];
                    233:                        }
1.14      www       234:                        $comp[1].='" external="true';
1.2       www       235:                    } else {
                    236: 		       if ($comp[1]=~/^http\:\/\//) {
                    237: 			   $comp[1]=~s/^http\:\/\/[^\/]*\//\//;
                    238:                        }
                    239:                    }
                    240: 		   $outstr.='<resource id="'.$parts[1].'" src="'
1.4       www       241:                           .$comp[1].'"';
1.2       www       242: 
                    243:                    if (($comp[3] ne '') && ($comp[3] ne 'normal')) {
                    244: 		       $outstr.=' type="'.$comp[3].'"';
                    245:                    }
                    246:                    if ($comp[0] ne '') {
1.4       www       247: 		       $outstr.=' title="'.$comp[0].'"';
1.2       www       248:                    }
1.31      www       249:                    $outstr.=" />\n";
1.2       www       250:                } elsif ($comp[$#comp] eq 'cond') {
                    251:                    $outstr.='<condition id="'.$parts[1].'"';
                    252:                    if (($comp[1] ne '') && ($comp[1] ne 'normal')) {
                    253: 		       $outstr.=' type="'.$comp[1].'"';
                    254:                    }
                    255:                    $outstr.=' value="'.qtescape($comp[0]).'"';
1.31      www       256:                    $outstr.=" />\n";
1.2       www       257:                }
                    258:            } elsif ($parts[0] eq 'objlinks') {
                    259:                my @comp=split(/:/,$parts[$#parts]);
                    260:                $outstr.='<link';
                    261:                $outstr.=' from="'.$comp[0].'"';
                    262:                $outstr.=' to="'.$comp[1].'"';
                    263:                if (($comp[2] ne '') && ($comp[2]!=0)) {
                    264:                   $outstr.=' condition="'.$comp[2].'"';
                    265:                }
                    266:                $outstr.=' index="'.$parts[1].'"';
1.31      www       267:                $outstr.=" />\n";
1.11      www       268:            } elsif ($parts[0] eq 'objparms') {
1.13      www       269:                undef %alltypes;
                    270:                undef %allvalues;
1.20      albertel  271:                foreach (split(/:/,$parts[$#parts])) {
1.11      www       272:                    my ($type,$name,$value)=split(/\_\_\_/,$_);
1.13      www       273:                    $alltypes{$name}=$type;
                    274:                    $allvalues{$name}=$value;
1.20      albertel  275:                }
                    276:                foreach (keys %allvalues) {
                    277:                   if ($allvalues{$_} ne '') {
1.13      www       278:                    $outstr.='<param to="'.$parts[1].'" type="'
                    279:                           .$alltypes{$_}.'" name="'.$_
1.31      www       280:                           .'" value="'.$allvalues{$_}.'" />'
                    281:                           ."\n";
1.20      albertel  282: 	          }
                    283:                }
1.2       www       284:            } elsif (($parts[0] ne '') && ($graphdef)) {
                    285: # ------------------------------------------------------------- Graphical input
                    286:                $outstr.='<'.$parts[0];
                    287:                if ($#parts==2) {
                    288: 		   $outstr.=' index="'.$parts[1].'"';
                    289:                }
1.31      www       290:                $outstr.=' value="'.qtescape($parts[$#parts]).'" />'."\n";
1.2       www       291:            }
1.23      www       292:         }
1.2       www       293:         $outstr.="</map>\n";
1.26      raeburn   294: 	if ($fn=~/^\/*uploaded\/(\w+)\/(\w+)\/(.*)$/) {
1.30      albertel  295: 	    $env{'form.output'}=$outstr;
1.32      albertel  296:             my $result=&Apache::lonnet::finishuserfileupload($2,$1,
                    297: 							     'output',$3);
1.25      albertel  298: 	    if ($result != m|^/uploaded/|) {
                    299: 		$errtext.='Map not saved: A network error occured when trying to save the map. ';
                    300: 	    }
1.21      www       301:         } else {
1.2       www       302:           my $fh;
                    303:           if ($fh=Apache::File->new(">$fn")) {
                    304:              print $fh $outstr;
1.28      www       305:              $infotext.="Map saved as $fn. ";
1.2       www       306: 	  } else {
1.17      matthew   307:              $errtext.='Could not write file '.$fn.'.  Map not saved. ';
1.2       www       308: 	  }
                    309:         }
                    310:     } else {
                    311: # -------------------------------------------- Cannot write to that file, error
1.20      albertel  312:         $errtext.='Map not saved: The specified path does not exist. ';
1.2       www       313:     }
1.28      www       314:     return ($errtext,$infotext);
1.2       www       315: }
1.1       www       316: 
                    317: # ================================================================ Main Handler
                    318: 
                    319: sub handler {
                    320:   my $r=shift;
1.29      albertel  321:   &Apache::loncommon::content_type($r,'text/html');
1.1       www       322:   $r->send_http_header;
                    323: 
                    324:   return OK if $r->header_only;
                    325: 
                    326:   my $url=$r->uri;
1.2       www       327:   $url=~/\/(\w+)\/ratserver$/;
                    328:   my $mode=$1;
                    329: 
                    330:   $url=~s/\/loadonly\/ratserver$/\/save\/ratserver/;
                    331:   
                    332:   my $fn=$r->filename;
1.19      albertel  333:   my $lonDocRoot=$r->dir_config('lonDocRoot');
                    334:   if ( $fn =~ /$lonDocRoot/ ) {
                    335:       #internal authentication, needs fixup.
                    336:       $fn = $url;
                    337:       $fn=~s|^/~(\w+)|/home/$1/public_html|;
                    338:       $fn=~s|/[^/]*/ratserver$||;
                    339:   }
1.2       www       340:   my $errtext='';
1.28      www       341:   my $infotext='';
1.2       www       342:   my $outtext='';
                    343: 
                    344:   if ($mode ne 'loadonly') {
1.28      www       345:      ($errtext,$infotext)=&savemap($fn,$errtext);
1.2       www       346:   }
1.28      www       347:   ($outtext,$errtext,$infotext)=&loadmap($fn,$errtext,$infotext);
1.1       www       348: 
                    349:   $r->print(<<ENDDOCUMENT);
                    350: <html>
1.8       harris41  351: <body bgcolor="#FFFFFF">
1.2       www       352: <form name=storage method=post action="$url">
                    353: <input type=hidden name=output value="$outtext">
1.1       www       354: </form>
1.8       harris41  355: <script>
1.9       harris41  356:     parent.flag=1;
1.8       harris41  357: </script>
1.2       www       358: ENDDOCUMENT
1.28      www       359:     if (($errtext ne '') || ($infotext ne '')) {
1.2       www       360: 	$r->print(<<ENDSCRIPT);
                    361: <script>
1.28      www       362:     alert("$infotext $errtext");
1.2       www       363: </script>
                    364: ENDSCRIPT
                    365:     }
                    366:     $r->print("</body>\n</html>\n");
1.1       www       367: 
                    368:   return OK;
                    369: }
                    370: 
                    371: 1;
                    372: __END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.