# The LearningOnline Network with CAPA # Construct and maintain state and binary representation of course for user # # (Server for RAT Maps # # (Edit Handler for RAT Maps # (TeX Content Handler # # 05/29/00,05/30 Gerd Kortemeyer) # 7/1 Gerd Kortemeyer) # 7/1,7/3,7/4,7/7,7/8,7/10 Gerd Kortemeyer) # # 7/15,7/17,7/18,8/1,8/2 Gerd Kortemeyer package Apache::lonuserstate; use strict; use Apache::Constants qw(:common :http); use Apache::File; use HTML::TokeParser; use Apache::lonnet(); use GDBM_File; # ---------------------------------------------------- Globals for this package my $pc; # Package counter my %hash; # The big tied hash my @cond; # Array with all of the conditions my $errtext; # variable with all errors # --------------------------------------------------------- Loads map from disk sub loadmap { my $uri=shift; if ($hash{'map_pc_'.$uri}) { return OK; } $pc++; my $lpc=$pc; $hash{'map_pc_'.$uri}=$lpc; $hash{'map_id_'.$lpc}=$uri; my $fn='/home/httpd/html'.$uri; unless (($fn=~/\.course$/) || ($fn=~/\.sequence$/) || ($fn=~/\.page$/)) { $errtext.="Invalid map: $fn\n"; return OK; } unless (-e $fn) { my $returned=Apache::lonnet::repcopy($fn); unless ($returned eq OK) { $errtext.="Could not import: $fn - "; if ($returned eq HTTP_SERVICE_UNAVAILABLE) { $errtext.="Server unavailable\n"; } if ($returned eq HTTP_NOT_FOUND) { $errtext.="File not found\n"; } if ($returned eq FORBIDDEN) { $errtext.="Access forbidden\n"; } return OK; } } if (-e $fn) { my @content; { my $fh=Apache::File->new($fn); @content=<$fh>; } my $instr=join('',@content); my $parser = HTML::TokeParser->new(\$instr); my $token; my $linkpc=0; $fn=~/\.(\w+)$/; $hash{'map_type_'.$lpc}=$1; while ($token = $parser->get_token) { if ($token->[0] eq 'S') { if ($token->[1] eq 'resource') { # -------------------------------------------------------------------- Resource my $rid=$lpc.'.'.$token->[2]->{'id'}; $hash{'kind_'.$rid}='res'; $hash{'title_'.$rid}=$token->[2]->{'title'}; my $turi=$token->[2]->{'src'}; $hash{'src_'.$rid}=$turi; if (defined($hash{'ids_'.$turi})) { $hash{'ids_'.$turi}.=','.$rid; } else { $hash{'ids_'.$turi}=''.$rid; } if ($token->[2]->{'src'}=~/\/\//) { $hash{'ext_'.$rid}='true:'; } else { $hash{'ext_'.$rid}='false:'; } if ($token->[2]->{'type'}) { $hash{'type_'.$rid}=$token->[2]->{'type'}; if ($token->[2]->{'type'} eq 'start') { $hash{'map_start_'.$uri}="$rid"; } if ($token->[2]->{'type'} eq 'finish') { $hash{'map_finish_'.$uri}="$rid"; } } else { $hash{'type_'.$rid}='normal'; } if (($turi=~/\.course$/) || ($turi=~/\.sequence$/) || ($turi=~/\.page$/)) { $hash{'is_map_'.$rid}=1; &loadmap($turi); } } elsif ($token->[1] eq 'condition') { # ------------------------------------------------------------------- Condition my $rid=$lpc.'.'.$token->[2]->{'id'}; $hash{'kind_'.$rid}='cond'; $cond[$#cond+1]=$token->[2]->{'value'}; $hash{'condid_'.$rid}=$#cond; if ($token->[2]->{'type'}) { $cond[$#cond].=':'.$token->[2]->{'type'}; } else { $cond[$#cond].=':normal'; } } elsif ($token->[1] eq 'link') { # ----------------------------------------------------------------------- Links $linkpc++; my $linkid=$lpc.'.'.$linkpc; my $goesto=$lpc.'.'.$token->[2]->{'to'}; my $comesfrom=$lpc.'.'.$token->[2]->{'from'}; my $undercond=0; if ($token->[2]->{'condition'}) { $undercond=$lpc.'.'.$token->[2]->{'condition'}; } $hash{'goesto_'.$linkid}=$goesto; $hash{'comesfrom_'.$linkid}=$comesfrom; $hash{'undercond_'.$linkid}=$undercond; if (defined($hash{'to_'.$comesfrom})) { $hash{'to_'.$comesfrom}.=','.$linkid; } else { $hash{'to_'.$comesfrom}=''.$linkid; } if (defined($hash{'from_'.$goesto})) { $hash{'from_'.$goesto}.=','.$linkid; } else { $hash{'from_'.$goesto}=''.$linkid; } } } } } else { $errtext.='Map not loaded: The file does not exist. '; } } # -------------------------------------------------------- Build condition hash sub traceroute { my ($sofar,$rid,$beenhere)=shift; unless ($beenhere=~/\&$rid\&/) { $beenhere.=$rid.'&'; if (defined($hash{'conditions_'.$rid})) { $hash{'conditions_'.$rid}= '('.$hash{'conditions_'.$rid}.')|('.$sofar.')'; } else { $hash{'conditions_'.$rid}=$sofar; } if (defined($hash{'is_map_'.$rid})) { if () { &traceroute($sofar,$startrid,'&'); } } if (defined($hash{'to_'.$rid})) { map { my $further=$sofar; if ($hash{'undercond_'.$_}) { if (defined($hash{'condid_'.$hash{'undercond_'.$_}})) { $further.='&'.$hash{'condid_'.$hash{'undercond_'.$_}}; } else { $errtext.='Undefined condition ID: ' .$hash{'undercond_'.$_}.'. '; } } &traceroute($further,$hash{'goesto_'.$_},$beenhere); } split(/\,/,$hash{'to_'.$rid}); } } } # ---------------------------------------------------- Read map and all submaps sub readmap { my $uri=shift; @cond=(); %hash=(); $errtext=''; $pc=0; loadmap($uri); } # ---------------------------------------------------------------- Testing only sub handler { my $r = shift; $r->content_type('text/html'); $r->send_http_header; return OK if $r->header_only; readmap('/res/msu/korte/foo.course'); $r->print("\n"); my $hashkey; foreach $hashkey (sort keys %hash) { $r->print("$hashkey: $hash{$hashkey}
\n"); } my $i; $r->print('
'); for ($i=0;$i<=$#cond;$i++) { $r->print($i.' : '.$cond[$i]."
\n"); } $r->print("

$errtext

\n"); return OK; } 1; __END__