# The LearningOnline Network with CAPA # Edit Handler for RAT Maps # # $Id: lonratedt.pm,v 1.72 2005/06/09 21:40:37 www Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # package Apache::lonratedt; =pod =head1 NAME Apache::lonratedt: simple resource assembly tool =head1 SYNOPSIS lonratedt provides the routines and the handler for the Advanced Resource Assembly Tool (RAT), and ties the various pieces together with Javascript. =head1 OVERVIEW =head2 Map Representation =begin latex % \begin{figure} \begin{center}\includegraphics[% width=0.55\paperwidth,bb = 0 0 200 100, draft, type=eps]{Map_Example}\end{center} \caption{\label{Map_In_Advanced_Editor}Example of a Map in the Advanced Editor} \end{figure} % \begin{figure} \begin{lyxcode} ~~ ~~~~ ~~ ~~~~ ~~ ~~~~ ~~ ~~~~ ~~ ~~~~ ~~ ~~~~ ~~ ~~ ~~ ~~ ~~ \end{lyxcode} \caption{\label{XML}XML for Map in Figure \ref{Map_In_Advanced_Editor}} \end{figure} =end latex Fig. "XML for Map in Figure" shows the XML representation of the resource map shown in Fig. "Example of a Map in the Advanced Editor", which is the format in which maps are stored. In the figure, however, additional graphical map layout information generated by the Advanced Resource Assembly Tool is not displayed. This graphical information is optional to re-generate the same graphical layout when the map is brought up again in the Resource Assembly Tool, and is not needed for any other system functionality. Maps can be generated by tools other than the Resource Assembly Tool. In particular, an author might have some other representation of a course sequence, which can be converted into a map using scripts. If this map then were to be brought up in the Resource Assembly Tool, the Tool would automatically generate a graphical layout for it. Each entry of the map (resources, conditions and links) is stored in a separate tag. Resources and conditionsX have to have unique ID numbers. These numbers are automatically generated by the Resource Assembly Tool when the entry is first created, or added to the entries when a map generated outside the Resource Assembly Tool is first retrieved. They can also be assigned by custom scripts or added in by hand. In the XML example, entry 1 is the start resource of the map. When this map is accessed, the source (src) URL of this tag will be the first resource rendered. Entry 2 is the finish resource of this map. This resource will be the last resource in the sequence of resources. Entry 6 is a problem resource with the given URL and title, as well as the priority "mandatory". Entry 19 is a condition, which is used by the link between entries 6, the problem, and 9, a sequence. I =cut use strict; use Apache::Constants qw(:common); use Apache::lonnet; use Apache::lonratsrv; use Apache::lonsequence; use Apache::loncommon; use Apache::lonlocal; use File::Copy; use vars qw(@order @resources @resparms @zombies); # Mapread read maps into global arrays @links and @resources, determines status # sets @order - pointer to resources in right order # sets @resources - array with the resources with correct idx # sub mapread { my $fn=shift; my @links; undef @links; undef @resources; undef @order; undef @resparms; undef @zombies; @resources=(''); @order=(); @resparms=(); @zombies=(); my ($outtext,$errtext)=&Apache::lonratsrv::loadmap($fn,''); if ($errtext) { return ($errtext,2); } # -------------------------------------------------------------------- Read map foreach (split(/\<\&\>/,$outtext)) { my ($command,$number,$content)=split(/\<\:\>/,$_); if ($command eq 'objcont') { my ($title,$src,$ext,$type)=split(/\:/,$content); if ($ext eq 'cond') { next; } if ($type ne 'zombie') { $resources[$number]=$content; } else { $zombies[$number]=$content; } } if ($command eq 'objlinks') { $links[$number]=$content; } if ($command eq 'objparms') { if ($resparms[$number]) { $resparms[$number].='&&&'.$content; } else { $resparms[$number]=$content; } } } # ------------------------------------------------------- Is this a linear map? my @starters=(); my @endings=(); undef @starters; undef @endings; foreach (@links) { if (defined($_)) { my ($start,$end,$cond)=split(/\:/,$_); if ((defined($starters[$start])) || (defined($endings[$end]))) { return (&mt('Map has branchings. Use advanced editor.'),1); } $starters[$start]=1; $endings[$end]=1; if ($cond) { return (&mt('Map has conditions. Use advanced editor.'),1); } } } for (my $i=1; $i<=$#resources; $i++) { if (defined($resources[$i])) { unless (($starters[$i]) || ($endings[$i])) { return (&mt('Map has unconnected resources. Use advanced editor.'),1); } } } # ---------------------------------------------- Did we just read an empty map? if ($#resources<1) { undef $resources[0]; $resources[1]=':::start'; $resources[2]=':::finish'; } # -------------------------------------------------- This is a linear map, sort my $startidx=0; my $endidx=0; for (my $i=0; $i<=$#resources; $i++) { if (defined($resources[$i])) { my ($title,$url,$ext,$type)=split(/\:/,$resources[$i]); if ($type eq 'start') { $startidx=$i; } if ($type eq 'finish') { $endidx=$i; } } } my $k=0; my $currentidx=$startidx; $order[$k]=$currentidx; for (my $i=0; $i<=$#resources; $i++) { foreach (@links) { my ($start,$end)=split(/\:/,$_); if ($start==$currentidx) { $currentidx=$end; $k++; $order[$k]=$currentidx; last; } } if ($currentidx==$endidx) { last; } } return $errtext; } # ---------------------------------------------- Read a map as well as possible # Also used by the sequence handler # Call lonsequence::attemptread to read from resource space # sub attemptread { my $fn=shift; my @links; undef @links; my @theseres; undef @theseres; my ($outtext,$errtext)=&Apache::lonratsrv::loadmap($fn,''); if ($errtext) { return @theseres } # -------------------------------------------------------------------- Read map foreach (split(/\<\&\>/,$outtext)) { my ($command,$number,$content)=split(/\<\:\>/,$_); if ($command eq 'objcont') { my ($title,$src,$ext,$type)=split(/\:/,$content); unless ($type eq 'zombie') { $theseres[$number]=$content; } } if ($command eq 'objlinks') { $links[$number]=$content; } } # --------------------------------------------------------------- Sort, sort of my @objsort=(); undef @objsort; my @data1=(); my @data2=(); undef @data1; undef @data2; my $k; my $kj; my $j; my $ij; for ($k=1;$k<=$#theseres;$k++) { if (defined($theseres[$k])) { $objsort[$#objsort+1]=$k; } } for ($k=1;$k<=$#links;$k++) { if (defined($links[$k])) { @data1=split(/\:/,$links[$k]); $kj=-1; for (my $j=0;$j<=$#objsort;$j++) { if ((split(/\:/,$objsort[$j]))[0]==$data1[0]) { $kj=$j; } } if ($kj!=-1) { $objsort[$kj].=':'.$data1[1]; } } } for ($k=0;$k<=$#objsort;$k++) { for ($j=0;$j<=$#objsort;$j++) { if ($k!=$j) { @data1=split(/\:/,$objsort[$k]); @data2=split(/\:/,$objsort[$j]); my $dol=$#data1+1; my $dtl=$#data2+1; if ($dol+$dtl<1000) { for ($kj=1;$kj<$dol;$kj++) { if ($data1[$kj]==$data2[0]) { for ($ij=1;$ij<$dtl;$ij++) { $data1[$#data1+1]=$data2[$ij]; } } } for ($kj=1;$kj<$dtl;$kj++) { if ($data2[$kj]==$data1[0]) { for ($ij=1;$ij<$dol;$ij++) { $data2[$#data2+1]=$data1[$ij]; } } } $objsort[$k]=join(':',@data1); $objsort[$j]=join(':',@data2); } } } } # ---------------------------------------------------------------- Now sort out @objsort=sort { my @data1=split(/\:/,$a); my @data2=split(/\:/,$b); my $rvalue=0; my $k; for ($k=1;$k<=$#data1;$k++) { if ($data1[$k]==$data2[0]) { $rvalue--; } } for ($k=1;$k<=$#data2;$k++) { if ($data2[$k]==$data1[0]) { $rvalue++; } } if ($rvalue==0) { $rvalue=$#data2-$#data1; } $rvalue; } @objsort; my @outres=(); undef @outres; for ($k=0;$k<=$#objsort;$k++) { $outres[$k]=$theseres[(split(/\:/,$objsort[$k]))[0]]; } return @outres; } # --------------------------------------------------------- Build up RAT screen sub ratedt { my ($r,$url)=@_; my $frameset = ''; if ($env{'environment.remote'} eq 'off') { $frameset = ''; } $r->print(< $frameset ENDDOCUMENT } # ---------------------------------------------------------------- Make buttons sub buttons { my $adv=shift; my $output='
'; if ($adv==1) { $output.=''. &Apache::loncommon::help_open_topic('Sequence_Advanced_Editor_Creation');; } else { unless ($adv==2) { $output.=''. &Apache::loncommon::help_open_topic('Sequence_Simple_Editor_Creation'); } $output.=''. &Apache::loncommon::help_open_topic('Sequence_Advanced_Editor_Creation'); } return $output.'

'; } # ------------------------------------- Revive zombie idx or get unused number sub getresidx { my $url=shift; my $max=1+($#resources>$#zombies?$#resources:$#zombies); unless ($url) { return $max; } for (my $i=0; $i<=$#zombies; $i++) { my ($title,$src,$ext,$type)=split(/\:/,$zombies[$i]); if ($src eq $url) { undef $zombies[$i]; return $i; } } return $max; } # --------------------------------------------------------------- Make a zombie sub makezombie { my $idx=shift; my ($name,$url,$ext)=split(/\:/,$resources[$idx]); my $now=time; $zombies[$idx]=$name. ' [('.$now.','.$env{'user.name'}.','.$env{'user.domain'}.')]:'. $url.':'.$ext.':zombie'; } # ----------------------------------------------------------- Paste into target # modifies @order, @resources sub pastetarget { my ($after,@which)=@_; my @insertorder=(); foreach (@which) { if (defined($_)) { my ($name,$url)=split(/\=/,$_); $name=&Apache::lonnet::unescape($name); $url=&Apache::lonnet::unescape($url); if ($url) { my $idx=&getresidx($url); $insertorder[$#insertorder+1]=$idx; my $ext='false'; if ($url=~/^http\:\/\//) { $ext='true'; } $url=~s/\:/\:/g; $name=~s/\:/\:/g; $resources[$idx]=$name.':'.$url.':'.$ext.':normal:res'; } } } my @oldorder=splice(@order,$after); @order=(@order,@insertorder,@oldorder); } # ------------------------------------------------ Get start and finish correct # modifies @resources sub startfinish { # Remove all start and finish foreach (@order) { my ($name,$url,$ext)=split(/\:/,$resources[$_]); if ($url=~/http\&colon\:\/\//) { $ext='true'; } $resources[$_]=$name.':'.$url.':'.$ext.':normal:res'; } # Garbage collection my $stillchange=1; while (($#order>1) && ($stillchange)) { $stillchange=0; for (my $i=0;$i<=$#order;$i++) { my ($name,$url,$ext)=split(/\:/,$resources[$order[$i]]); unless ($url) { # Take out empty resource for (my $j=$i+1;$j<=$#order;$j++) { $order[$j-1]=$order[$j]; } $#order--; $stillchange=1; last; } } } # Put in a start resource my ($name,$url,$ext)=split(/\:/,$resources[$order[0]]); $resources[$order[0]]=$name.':'.$url.':'.$ext.':start:res'; # Make sure this has at least start and finish if ($#order==0) { $resources[&getresidx()]='::false'; $order[1]=$#resources; } # Make the last one a finish resource ($name,$url,$ext)=split(/\:/,$resources[$order[$#order]]); $resources[$order[$#order]]=$name.':'.$url.':'.$ext.':finish:res'; } # ------------------------------------------------------------------- Store map sub storemap { my $realfn=shift; my $fn=$realfn; # unless this is forced to work from the original file, use a temporary file # instead unless (shift) { $fn=$realfn.'.tmp'; unless (-e $fn) { copy($realfn,$fn); } } # store data either into tmp or real file &startfinish(); my $output='graphdef<:>no'; my $k=1; for (my $i=0; $i<=$#order; $i++) { if (defined($resources[$order[$i]])) { $output.='<&>objcont<:>'.$order[$i].'<:>'.$resources[$order[$i]]; } if (defined($resparms[$order[$i]])) { foreach (split('&&&',$resparms[$order[$i]])) { if ($_) { $output.='<&>objparms<:>'.$order[$i].'<:>'.$_; } } } if (defined($order[$i+1])) { if (defined($resources[$order[$i+1]])) { $output.='<&>objlinks<:>'.$k.'<:>'. $order[$i].':'.$order[$i+1].':0'; $k++; } } } for (my $i=0; $i<=$#zombies; $i++) { if (defined($zombies[$i])) { $output.='<&>objcont<:>'.$i.'<:>'.$zombies[$i]; } } $output=~s/http\&colon\;\/\///g; $env{'form.output'}=$output; return &Apache::lonratsrv::loadmap($fn,&Apache::lonratsrv::savemap($fn,'')); } # ------------------------------------------ Store and get parameters in global sub storeparameter { my ($to,$name,$value,$ptype)=@_; my $newentry=''; my $nametype=''; foreach (split('&&&',$resparms[$to])) { my ($thistype,$thisname,$thisvalue)=split('___',$_); if ($thisname) { unless ($thisname eq $name) { $newentry.=$_.'&&&'; } else { $nametype=$thistype; } } } unless ($ptype) { $ptype=$nametype; } unless ($ptype) { $ptype='string'; } $newentry.=$ptype.'___'.$name.'___'.$value; $resparms[$to]=$newentry; } sub delparameter { my ($to,$name)=@_; my $newentry=''; my $nametype=''; foreach (split('&&&',$resparms[$to])) { my ($thistype,$thisname,$thisvalue)=split('___',$_); if ($thisname) { unless ($thisname eq $name) { $newentry.=$_.'&&&'; } } } $resparms[$to]=$newentry; } sub getparameter { my ($to,$name)=@_; my $value=undef; my $ptype=undef; foreach (split('&&&',$resparms[$to])) { my ($thistype,$thisname,$thisvalue)=split('___',$_); if ($thisname eq $name) { $value=$thisvalue; $ptype=$thistype; } } return ($value,$ptype); } # ----------------------------------------------------------------- Edit script sub editscript { my $mode=shift; my $resurl=&Apache::loncommon::lastresurl(); return(<
'; } else { $targetmsg=''.&mt('An error occured while saving.').'
'; } } if ($env{'form.revert'}) { $targetmsg=''.&mt('Reverted.').'
'; unlink($tmpfn); my ($errtext,$fatal)= &mapread(&Apache::lonnet::filelocation('',$url),''); } if (-e $tmpfn) { $targetmsg= ''.&mt('You are working with an unsaved version of your map.').'
'; my ($errtext,$fatal)=&mapread($tmpfn,''); } # ---------------------------------------------------------- Process form input my @importselect=&Apache::loncommon::get_env_multiple('form.importsel'); my @targetselect=&Apache::loncommon::get_env_multiple('form.target'); # ============================================================ Process commands my $targetdetail=$env{'form.targetdetail'}; my $importdetail=$env{'form.curimpdetail'}; # ---------------------------------------------------- Importing from groupsort if (($env{'form.importdetail'}) && (!$env{'form.impfortarget'})) { $importdetail=''; my @curimport=split(/\&/,$env{'form.curimpdetail'}); my $lastsel; if (defined($importselect[-1])) { $lastsel=$importselect[-1]; } else { $lastsel=$#curimport; } for (my $i=0;$i<=$lastsel;$i++) { my ($name,$url)=split(/\=/,$curimport[$i]); if ($url) { $importdetail.='&'.$name.'='.$url; } } $importdetail.='&'.$env{'form.importdetail'}; for (my $i=$lastsel+1;$i<=$#curimport;$i++) { my ($name,$url)=split(/\=/,$curimport[$i]); if ($url) { $importdetail.='&'.$name.'='.$url; } } $importdetail=~s/\&+/\&/g; $importdetail=~s/^\&//; # ------------------------------------------------------------------- Clear all } elsif ($env{'form.clear'}) { $importdetail=''; # ------------------------------------------------------------ Discard selected } elsif ($env{'form.discard'}) { $importdetail=''; my @curimport=split(/\&/,$env{'form.curimpdetail'}); foreach (@importselect) { $curimport[$_]=''; } for (my $i=0;$i<=$#curimport;$i++) { my ($name,$url)=split(/\=/,$curimport[$i]); if ($url) { $importdetail.='&'.$name.'='.$url; } } # --------------------------------------------------------- Loading another map } elsif ($env{'form.loadmap'}) { $importdetail=''; my @curimport=split(/\&/,$env{'form.curimpdetail'}); my $lastsel; if (defined($importselect[-1])) { $lastsel=$importselect[-1]; } else { $lastsel=$#curimport; } for (my $i=0;$i<=$lastsel;$i++) { my ($name,$url)=split(/\=/,$curimport[$i]); if ($url) { $importdetail.='&'.$name.'='.$url; } } foreach ( &Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) { my ($name,$url)=split(/\:/,$_); if ($url) { $importdetail.='&'.&Apache::lonnet::escape($name).'='. &Apache::lonnet::escape($url); } } for (my $i=$lastsel+1;$i<=$#curimport;$i++) { my ($name,$url)=split(/\=/,$curimport[$i]); if ($url) { $importdetail.='&'.$name.'='.$url; } } $importdetail=~s/\&+/\&/g; $importdetail=~s/^\&//; # ------------------------------------------------ Groupimport/search to target } elsif ($env{'form.importdetail'}) { my $lastsel; if (defined($targetselect[-1])) { $lastsel=$targetselect[-1]; } else { $lastsel=$#order+1; } &pastetarget($lastsel,split(/\&/,$env{'form.importdetail'})); &storemap(&Apache::lonnet::filelocation('',$url)); # ------------------------------------------------------------------------- Cut } elsif (($env{'form.cut'}) || ($env{'form.copy'})) { $importdetail=''; my @curimport=split(/\&/,$env{'form.curimpdetail'}); my $lastsel; if (defined($importselect[-1])) { $lastsel=$importselect[-1]; } else { $lastsel=$#curimport; } for (my $i=0;$i<=$lastsel;$i++) { my ($name,$url)=split(/\=/,$curimport[$i]); if ($url) { $importdetail.='&'.$name.'='.$url; } } foreach (@targetselect) { my ($name,$url)=split(/\:/,$resources[$order[$_-1]]); if ($url) { $importdetail.='&'.&Apache::lonnet::escape($name).'='. &Apache::lonnet::escape($url); } } for (my $i=$lastsel+1;$i<=$#curimport;$i++) { my ($name,$url)=split(/\=/,$curimport[$i]); if ($url) { $importdetail.='&'.$name.'='.$url; } } $importdetail=~s/\&+/\&/g; $importdetail=~s/^\&//; if ($env{'form.cut'}) { my @neworder=(); for (my $i=0;$i<=$#order;$i++) { my $include=1; foreach (@targetselect) { if ($_-1==$i) { $include=0; } } if ($include) { $neworder[$#neworder+1]=$order[$i]; } else { &makezombie($order[$i]); } } @order=@neworder; &storemap(&Apache::lonnet::filelocation('',$url)); } # ----------------------------------------------------------------------- Paste } elsif ($env{'form.paste'}) { my $lastsel; if (defined($targetselect[-1])) { $lastsel=$targetselect[-1]; } else { $lastsel=$#order+1; } my @newsequence; my @curimport=split(/\&/,$env{'form.curimpdetail'}); foreach (@importselect) { $newsequence[$#newsequence+1]=$curimport[$_]; } &pastetarget($lastsel,@newsequence); &storemap(&Apache::lonnet::filelocation('',$url)); # -------------------------------------------------------------------- Move up } elsif ($env{'form.moveup'}) { foreach (sort @targetselect) { if ($_-1>0) { my $movethis=$order[$_-1]; $order[$_-1]=$order[$_-2]; $order[$_-2]=$movethis; } } &storemap(&Apache::lonnet::filelocation('',$url)); # ------------------------------------------------------------------ Move down } elsif ($env{'form.movedown'}) { foreach (reverse sort @targetselect) { if ($_-1<$#order) { my $movethis=$order[$_-1]; $order[$_-1]=$order[$_]; $order[$_]=$movethis; } } &storemap(&Apache::lonnet::filelocation('',$url)); # --------------------------------------------------------------------- Rename } elsif ($env{'form.renameres'}) { my $residx=$Apache::lonratedt::order[$env{'form.renameidx'}-1]; my ($name,@resrest)=split(/\:/,$Apache::lonratedt::resources[$residx]); $name=$env{'form.renametitle'}; $name=~s/\:/\&colon\;/g; $Apache::lonratedt::resources[$residx]=$name.':'.join(':',@resrest); &storemap(&Apache::lonnet::filelocation('',$url)); } # ------------------------------------------------------------ Assemble windows my $idx=-1; $importdetail='&'.$importdetail; $importdetail=~s/^\&+/\&/; my $importwindow= ''. join("\n",map { $idx++; if ($_) { my ($name,$url)=split(/\=/,$_); unless ($name) { $name=(split(/\//,$url))[-1]; } unless ($name) { $name='EMPTY'; } ''; } } split(/\&/,$importdetail)); $idx=0; $targetdetail=''; my $targetwindow= ''. join("\n",map { my ($name,$url)=split(/\:/,$resources[$_]); unless ($name) { $name=(split(/\//,$url))[-1]; } unless ($name) { $name='EMPTY'; } $targetdetail.='&'.&Apache::lonnet::escape($name).'='. &Apache::lonnet::escape($url); $idx++; $name=~s/\:/\:/g; ''; } @order); # ----------------------------------------------------- Start simple RAT screen my $editscript=&editscript('simple'); my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef, ($env{'environment.remote'} ne 'off')). &Apache::loncommon::help_open_menu('','Sequence_Simple_Editor_Creation','Sequence_Simple_Editor_Creation','',6,'RAT'); my %lt=&Apache::lonlocal::texthash( 'sa' => 'Save', 'nt' => 'New Title', 'se' => 'Search', 'im' => 'Import', 'vi' => 'View', 'lm' => 'Load Map', 'ds' => 'Discard Selected', 'ca' => 'Clear All', 'ta' => 'Temporary Assembly Workspace', 'rv' => 'Revert to Last Saved', 'sa' => 'Save', 'mu' => 'Move Up', 'md' => 'Move Down', 're' => 'Rename', 'as' => 'after selected', 'cs' => 'Cut selected', 'ps' => 'Copy selected', 'pas' => 'Paste after selected', ); $r->print(< $bodytag $buttons $errtext
$lt{'ta'}   File: $url
$lt{'as'}

  $lt{'as'}

$targetmsg
$lt{'cs'}


$lt{'ps'}


$lt{'pas'}
ENDSMPHEAD } # ----------------------------------------------------------------- No such dir sub nodir { my ($r,$dir)=@_; $dir=~s/^\/home\/\w+\/public\_html//; $r->print(<

No such directory: $dir

ENDNODIR } # ---------------------------------------------------------------- View Handler sub viewmap { my ($r,$url,$adv,$errtext)=@_; $r->print(''. &Apache::loncommon::bodytag('Edit Content of a Map'). &Apache::loncommon::help_open_menu('','','','',6,'RAT'). &buttons($adv)); if ($errtext) { $r->print($errtext.'
'); } my $idx=0; $r->print('

'.$url.'

'); if ($adv) { $r->print('

'.&mt('Map contents are not shown in order.').'


'); } $r->print( ''. ''. ''. ''. ''. ''. ''); my @backgroundColors = ("#FFFFFF", "#F6F6F6"); foreach (&attemptread(&Apache::lonnet::filelocation('',$url))) { if (defined($_)) { $idx++; my ($title,$url,$cond)=split(/\:/,$_); if ($cond eq 'cond') { next; } $title=~s/\&colon\;/\:/g; $url=~s/\&colon\;/\:/g; unless ($title) { $title=(split(/\//,$url))[-1] }; unless ($title) { $title=''.&mt('Empty').''; } my $resurl = &Apache::lonratsrv::qtescape($url); my $resfilepath = $Apache::lonnet::perlvar{'lonDocRoot'}.$resurl; my $filename; if ($resurl =~ m#/([^/]+)$#) { $filename = $1; } my $cstrurl = $resurl; $cstrurl =~ s#^/res/[^/]+/([^/]+)/#/priv/$1/#; my $bgcol = $idx%2; $r->print(''."\n"); } } $r->print('
'.&mt('Type').''.&mt('Title in map').''.&mt('Filename of resource').''.&mt('Link to published resource').''.&mt('Link to resource in Construction Space').'
'. ''.&Apache::lonratsrv::qtescape($title). ''.$filename.''); if ($url) { $r->print(''.&mt('Resource space').''); } $r->print(''); if ($url) { $r->print(''. &mt('Construction space').''); } $r->print('
'); $r->print(''); } # ================================================================ Main Handler sub handler { my $r=shift; &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; my $target = $env{'form.grade_target'}; if ($target eq 'meta') { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK; } my $url=$r->uri; my $fn=&Apache::lonnet::filelocation('',$url); my ($dir)=($fn=~/^(.+)\/[^\/]+$/); unless (-e $dir) { &nodir($r,$dir); return OK; } # ------------------------------------------- Determine which tools can be used my $adv=0; unless ($env{'form.forcesmp'}) { if ($env{'form.forceadv'}) { $adv=1; } elsif (my $fh=Apache::File->new($fn)) { my $allmap=join('',<$fh>); $adv=($allmap=~/\]+mode\s*\=\s*(\'|\")rat/is); } } my $errtext=''; my $fatal=0; # -------------------------------------------------------------------- Load map ($errtext,$fatal)=&mapread($fn,$errtext); if ($fatal==1) { $adv=1; } # ----------------------------------- adv==1 now means "graphical MUST be used" if ($env{'form.forceadv'}) { &ratedt($r,$url); } elsif ($env{'form.forcesmp'}) { &smpedt($r,$url,$errtext); } else { &viewmap($r,$url,$adv,$errtext); } return OK; } 1; __END__