--- rat/lonratedt.pm 2006/06/08 13:56:40 1.79 +++ rat/lonratedt.pm 2010/08/24 09:11:40 1.101 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Edit Handler for RAT Maps # -# $Id: lonratedt.pm,v 1.79 2006/06/08 13:56:40 www Exp $ +# $Id: lonratedt.pm,v 1.101 2010/08/24 09:11:40 wenzelju Exp $ # # Copyright Michigan State University Board of Trustees # @@ -29,391 +29,22 @@ 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::lonsequence(); +use Apache::loncommon(); use Apache::lonlocal; +use LONCAPA::map(); use File::Copy; -use lib '/home/httpd/lib/perl/'; use LONCAPA; - - -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; -} +use HTML::Entities(); # --------------------------------------------------------- Build up RAT screen sub ratedt { my ($r,$url)=@_; - my %layout = ('border' => "0"); - if ($env{'environment.remote'} eq 'off') { - $layout{'rows'} = "1,250,*"; - } else { - $layout{'rows'} = "1,70,*"; - } + my %layout = ('border' => "0", + 'rows' => "1,250,*"); my $js =' ENDJS - my $start_page = &Apache::loncommon::start_page(undef,$js). - &Apache::loncommon::help_open_menu('', - 'Sequence_Simple_Editor_Creation', - 'Sequence_Simple_Editor_Creation', - '',6,'RAT'); + &Apache::lonhtmlcommon::clear_breadcrumbs(); + &Apache::lonhtmlcommon::add_breadcrumb({ + text => 'Construction Space', + href => &Apache::loncommon::authorspace(), + faq => 6, + bug => 'RAT', + help => 'Sequence_Simple_Editor_Creation',}); + &Apache::lonhtmlcommon::add_breadcrumb({ + text => 'RAT', + title => 'Resource Assembly Tool', + href => '',}); + &Apache::lonhtmlcommon::add_breadcrumb({ + text => 'Editor', + title => 'Simple Editor', + href => '',}); + + # Breadcrumbs are included by &start_page + my $start_page = &Apache::loncommon::start_page('Construction Space',$js) + .&Apache::loncommon::head_subbox( + &Apache::loncommon::CSTR_pageheader() + .&buttons(2)); my $end_page = &Apache::loncommon::end_page(); $r->print(<$errtext -
- - - - +$errtext + + + + + - -
$lt{'ta'}   File: $url
- - + + $lt{'as'} -
- - + +
- - - +value="Select Map" />
+ + +
  - - - + + + + $lt{'as'} -
- - - -
$targetmsg - - - +
+ + + +
$targetmsg + + +
-$lt{'cs'}
-

-


-$lt{'ps'}
-

-


-$lt{'pas'}
- +$lt{'cs'}
+

+


+$lt{'ps'}
+

+ +$lt{'pas'}
+

- - - - + + + +
$end_page ENDSMPHEAD @@ -1181,48 +645,80 @@ ENDSMPHEAD # ----------------------------------------------------------------- No such dir sub nodir { my ($r,$dir)=@_; - $dir=~s{^/home/\w+/public_html}{}; - $r->print(&Apache::loncommon::start_page(undef,undef, - {'only_body' => 1, - 'bgcolor' => '#FFFFFF',}). - "

No such directory: $dir

". - &Apache::loncommon::end_page()); + $dir=~s{^/home/$LONCAPA::username_re/public_html}{}; + my $brcrum = [{'href' => &Apache::loncommon::authorspace(), + 'text' => 'Construction Space'}]; +# {'href' => '', +# 'text' => 'No such directory'}]; + $r->print(&Apache::loncommon::start_page('Construction Space', + undef, + {'bread_crumbs' => $brcrum,}) + .&Apache::loncommon::head_subbox( + &Apache::loncommon::CSTR_pageheader()) + .'

' + .&mt('No such directory: [_1]',''.$dir.'' + .'

' + .&Apache::loncommon::end_page()) + ); } # ---------------------------------------------------------------- View Handler sub viewmap { my ($r,$url,$adv,$errtext)=@_; - $r->print( - &Apache::loncommon::start_page('Edit Content of a Map'). - &Apache::loncommon::help_open_menu('','','','',6,'RAT'). - &buttons($adv)); + + &Apache::lonhtmlcommon::clear_breadcrumbs(); + &Apache::lonhtmlcommon::add_breadcrumb({ + text => 'Construction Space', + href => &Apache::loncommon::authorspace(), + faq => 6, + bug => 'RAT', + help => 'Sequence_Simple_Editor_Creation',}); + &Apache::lonhtmlcommon::add_breadcrumb({ + text => 'RAT', + title => 'Resource Assembly Tool', + href => '',}); + + # Breadcrumbs are included by &start_page + $r->print(&Apache::loncommon::start_page('Edit Content of a Map') + .&Apache::loncommon::head_subbox( + &Apache::loncommon::CSTR_pageheader() + .&buttons($adv)) + ); if ($errtext) { - $r->print($errtext.'
'); + $r->print('
' + .$errtext + .'
' + .'
' + ); } my $idx=0; - $r->print('

'.$url.'

'); + $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))) { + $r->print('

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


' + ); + } + $r->print(&Apache::loncommon::start_data_table() + .&Apache::loncommon::start_data_table_header_row() + .'' + .'' + .'' + .'' + .'' + .&Apache::loncommon::end_data_table_header_row() + ); + foreach (&LONCAPA::map::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; + $title= &LONCAPA::map::qtescape($title); + $url = &LONCAPA::map::qtescape($url); unless ($title) { $title=(split(/\//,$url))[-1] }; unless ($title) { $title=''.&mt('Empty').''; } - my $resurl = &Apache::lonratsrv::qtescape($url); + my $resurl = $url; my $resfilepath = $Apache::lonnet::perlvar{'lonDocRoot'}.$resurl; my $filename; if ($resurl =~ m#/([^/]+)$#) { @@ -1230,23 +726,34 @@ sub viewmap { } my $cstrurl = $resurl; $cstrurl =~ s#^/res/[^/]+/([^/]+)/#/priv/$1/#; - my $bgcol = $idx%2; - $r->print('' + .'' + .'' + .''."\n"); + $r->print('' + .&Apache::loncommon::end_data_table_row() + ); } } - $r->print('
'.&mt('Type').''.&mt('Title in map').''.&mt('Filename of resource').''.&mt('Link to published resource').''.&mt('Link to resource in Construction Space').'
'.&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.''); + $r->print(&Apache::loncommon::start_data_table_row() + .'' + .'' + .'' + .&HTML::Entities::encode(&LONCAPA::map::qtescape($title)) + .''.$filename.'' + ); if ($url) { $r->print(''.&mt('Resource space').''); + } else { + $r->print(' '); } $r->print(''); if ($url) { $r->print(''. &mt('Construction space').''); + } else { + $r->print(' '); } - $r->print('
'); + $r->print(&Apache::loncommon::end_data_table()); $r->print(&Apache::loncommon::end_page()); } @@ -1290,7 +797,7 @@ sub handler { my $fatal=0; # -------------------------------------------------------------------- Load map - ($errtext,$fatal)=&mapread($fn,$errtext); + ($errtext,$fatal)=&LONCAPA::map::mapread($fn,$errtext); if ($fatal==1) { $adv=1; } @@ -1311,7 +818,140 @@ __END__ +=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