--- rat/lonratedt.pm 2001/05/26 19:55:07 1.3 +++ rat/lonratedt.pm 2002/05/15 19:50:37 1.17 @@ -1,15 +1,241 @@ # The LearningOnline Network with CAPA # Edit Handler for RAT Maps +# +# $Id: lonratedt.pm,v 1.17 2002/05/15 19:50: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/ +# # (TeX Content Handler # # 05/29/00,05/30 Gerd Kortemeyer) -# 7/1 Gerd Kortemeyer +# 7/1,6/30 Gerd Kortemeyer package Apache::lonratedt; use strict; use Apache::Constants qw(:common); use Apache::lonnet; +use Apache::lonratsrv; + +my @order=(); +my @resources=(); + + +# 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; + + 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') { + $resources[$number]=$content; + } + if ($command eq 'objlinks') { + $links[$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 + ('Map has branchings. Use advanced editor.',1); + } + $starters[$start]=1; + $endings[$end]=1; + if ($cond) { + return + ('Map has conditions. Use advanced editor.',1); + } + } + + } + for (my $i=0; $i<=$#resources; $i++) { + if (defined($resources[$i])) { + unless (($starters[$i]) || ($endings[$i])) { + return + ('Map has unconnected resources. Use advanced editor.',1); + } + } + } + +# -------------------------------------------------- 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 + +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') { + $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 { @@ -32,17 +258,372 @@ sub ratedt { ENDDOCUMENT } +# ---------------------------------------------------------------- Make buttons + +sub buttons { + my $adv=shift; + my $output='
'; + if ($adv==1) { + $output.=''; + } else { + unless ($adv==2) { + $output.=''; + } + $output.=''; + } + return $output.'

'; +} + sub smpedt { - my ($r,$fn)=@_; + my ($r,$errtext)=@_; + my $buttons=&buttons(2); + +# ---------------------------------------------------------- Process form input + + my @importselect=(); + my @targetselect=(); + undef @importselect; + undef @targetselect; + if (defined($ENV{'form.import'})) { + if (ref($ENV{'form.import'})) { + @importselect=sort($ENV->{'form.import'}); + } else { + @importselect=($ENV{'form.import'}); + } + } + if (defined($ENV{'form.target'})) { + if (ref($ENV{'form.target'})) { + @targetselect=sort($ENV->{'form.target'}); + } else { + @targetselect=($ENV{'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.='&'.&Apache::lonnet::escape($name).'='. + &Apache::lonnet::escape($url); + } + } + + $importdetail.='&'.$ENV{'form.importdetail'}; + + for (my $i=$lastsel+1;$i<=$#curimport;$i++) { + my ($name,$url)=split(/\=/,$curimport[$i]); + if ($url) { + $importdetail.='&'.&Apache::lonnet::escape($name).'='. + &Apache::lonnet::escape($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.='&'.&Apache::lonnet::escape($name).'='. + &Apache::lonnet::escape($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.='&'.&Apache::lonnet::escape($name).'='. + &Apache::lonnet::escape($url); + } + } + + foreach ( + &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.='&'.&Apache::lonnet::escape($name).'='. + &Apache::lonnet::escape($url); + } + } + $importdetail=~s/\&+/\&/g; + $importdetail=~s/^\&//; + +# ------------------------------------ + } + +# ------------------------------------------------------------ Assemble windows + + my $idx=-1; + 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; + 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++; + ''; + } @order); + +# ----------------------------------------------------- Start simple RAT screen $r->print(< + + + -
-
+$buttons +$errtext + + + + + + + + + + +
Import Target
+ + +after selected +
+ +
+ + + + +
  + + + +after selected +
+
+ +Cut selected
+

+


+Paste after selected
+ +
+
+ + + + +
+ ENDSMPHEAD - $r->print( - ''); +} + +# ----------------------------------------------------------------- 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(''.&buttons($adv)); + if ($errtext) { + $r->print($errtext.'
'); + } + foreach (&attemptread(&Apache::lonnet::filelocation('',$url))) { + if (defined($_)) { + my ($title,$url)=split(/\:/,$_); + $title=~s/\&colon\;/\:/g; + $url=~s/\&colon\;/\:/g; + unless ($title) { $title=(split(/\//,$url))[-1] }; + unless ($title) { $title='Empty'; } + if ($url) { + $r->print(''); + } + $r->print(&Apache::lonratsrv::qtescape($title)); + if ($url) { $r->print(''); } + $r->print('
'); + } + } + $r->print(''); } # ================================================================ Main Handler @@ -57,6 +638,13 @@ sub handler { 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'}) { @@ -68,10 +656,22 @@ sub handler { } } - if ($adv) { + 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,$errtext); } else { - &smpedt($r,$fn); + &viewmap($r,$url,$adv,$errtext); } return OK; }