--- loncom/imspackages/imsprocessor.pm 2005/03/23 19:54:27 1.17 +++ loncom/imspackages/imsprocessor.pm 2005/07/13 20:25:12 1.25 @@ -24,6 +24,9 @@ package Apache::imsprocessor; use Apache::lonnet; +use Apache::loncleanup; +use LWP::UserAgent; +use HTTP::Request::Common; use LONCAPA::Configuration; use strict; @@ -95,7 +98,7 @@ sub uploadzip { my ($context,$tempdir,$source) = @_; my $fname; if ($context eq 'DOCS') { - $fname=$ENV{'form.uploadname.filename'}; + $fname=$env{'form.uploadname.filename'}; # Replace Windows backslashes by forward slashes $fname=~s/\\/\//g; # Get rid of everything but the actual filename @@ -107,9 +110,9 @@ sub uploadzip { # See if there is anything left unless ($fname) { return 'error: no uploaded file'; } # Save the file - chomp($ENV{'form.uploadname'}); + chomp($env{'form.uploadname'}); open(my $fh,'>'.$tempdir.'/'.$fname); - print $fh $ENV{'form.uploadname'}; + print $fh $env{'form.uploadname'}; close($fh); } elsif ($context eq 'CSTR') { if ($source =~ m/\/([^\/]+)$/) { @@ -128,14 +131,8 @@ sub expand_zip { return 'no zip'; } if ($filename =~ m|\.zip$|i) { - # unzip can cause an sh launch which can pass along all of %ENV - # which can be too large for /bin/sh to handle - my %oldENV=%ENV; - undef(%ENV); open(OUTPUT, "unzip -o $zipfile -d $tempdir 2> /dev/null |"); close(OUTPUT); - %ENV=%oldENV; - undef(%oldENV); } else { return 'nozip'; } @@ -519,15 +516,15 @@ sub process_resinfo { } } elsif ($$resources{$key}{type} eq "assessment/x-bb-pool") { %{$$resinfo{$key}} = (); - &process_assessment($cms,$context,$key,$docroot,'pool',$dirname,$destdir,\%{$$resinfo{$key}},$total,$udom,$uname,$pagesfiles,$sequencesfiles,$randompicks,\$dbparse,$resources,$items,\%catinfo,\%qzdbsettings); + &process_assessment($cms,$context,$key,$docroot,'pool',$dirname,$destdir,\%{$$resinfo{$key}},$total,$udom,$uname,$pagesfiles,$sequencesfiles,$randompicks,\$dbparse,$resources,$items,\%catinfo,\%qzdbsettings,$hrefs); push @{$pools}, $key; } elsif ($$resources{$key}{type} eq "assessment/x-bb-quiz") { %{$$resinfo{$key}} = (); - &process_assessment($cms,$context,$key,$docroot,'quiz',$dirname,$destdir,\%{$$resinfo{$key}},$total,$udom,$uname,$pagesfiles,$sequencesfiles,$randompicks,\$dbparse,$resources,$items,\%catinfo,\%qzdbsettings); + &process_assessment($cms,$context,$key,$docroot,'quiz',$dirname,$destdir,\%{$$resinfo{$key}},$total,$udom,$uname,$pagesfiles,$sequencesfiles,$randompicks,\$dbparse,$resources,$items,\%catinfo,\%qzdbsettings,$hrefs); push @{$quizzes}, $key; } elsif ($$resources{$key}{type} eq "assessment/x-bb-survey") { %{$$resinfo{$key}} = (); - &process_assessment($cms,$context,$key,$docroot,'survey',$dirname,$destdir,\%{$$resinfo{$key}},$total,$udom,$uname,$pagesfiles,$sequencesfiles,$randompicks,\$dbparse,$resources,$items,\%catinfo,\%qzdbsettings); + &process_assessment($cms,$context,$key,$docroot,'survey',$dirname,$destdir,\%{$$resinfo{$key}},$total,$udom,$uname,$pagesfiles,$sequencesfiles,$randompicks,\$dbparse,$resources,$items,\%catinfo,\%qzdbsettings,$hrefs); push @{$surveys}, $key; } elsif ($$resources{$key}{type} eq "assessment/x-bb-group") { %{$$resinfo{$key}} = (); @@ -569,7 +566,7 @@ sub process_resinfo { %{$$resinfo{$key}} = (); &webct4_content($key,$docroot,$destdir,\%{$$resinfo{$key}},$udom,$uname,$$resources{$key}{type},$$items{$$resources{$key}{revitm}}{title},$resrcfiles); } elsif ($$resources{$key}{type} eq "webctquiz") { - &process_assessment($cms,$context,$key,$docroot,'quiz',$dirname,$destdir,\%{$$resinfo{$key}},$total,$udom,$uname,$pagesfiles,$sequencesfiles,$randompicks,\$dbparse,$resources,$items,\%catinfo,\%qzdbsettings); + &process_assessment($cms,$context,$key,$docroot,'quiz',$dirname,$destdir,\%{$$resinfo{$key}},$total,$udom,$uname,$pagesfiles,$sequencesfiles,$randompicks,\$dbparse,$resources,$items,\%catinfo,\%qzdbsettings,$hrefs); } } } @@ -679,8 +676,12 @@ sub build_structure { if (grep/^$res$/,@{$packages}) { $packageflag = 1; } - $src = &make_structure($cms,$key,$srcstem,\%flag,\%count,$timestamp,$boardnum,$hrefs,\%pagecontents,$res,$type,$file,$resinfo,$contitem,$uname,$cdom,$contcount,$packageflag,$contitemcount); + $src = &make_structure($cms,$key,$srcstem,\%flag,\%count,$timestamp,$boardnum,$hrefs,\%pagecontents,$res,$type,$file,$resinfo,$contitem,$uname,$cdom,$contcount,$packageflag,$contitemcount,$$randompicks{$contitem}); unless ($flag{$key}{page} == 1) { + if ($$randompicks{$contitem}) { + $seqtext{$key} .= qq| +\n|; + } $seqtext{$key} .= qq| - +\n|; + if ($$randompicks{$contitem}) { + $seqtext{$key} .= qq| +|; + } + $seqtext{$key} .= qq| - +\n|; + if ($$randompicks{$contitem}) { + $seqtext{$key} .= qq| +\n|; + } + $seqtext{$key} .= qq| 0)) { $src = $srcstem.'/sequences/'.$contitem.'.sequence'; $$flag{$key}{page} = 0; $$flag{$key}{seq} = 1; $$count{$key}{seq} ++; + } elsif ($cms eq 'webct4' && $randompick) { + $src = $srcstem.'/sequences/'.$res.'.sequence'; + $$flag{$key}{page} = 0; + $$flag{$key}{seq} = 1; + $$count{$key}{seq} ++; } elsif ($cms eq 'angel' && $type eq 'BOARD') { $src = '/adm/'.$cdom.'/'.$uname.'/'.$$timestamp[$$boardnum{$res}].'/bulletinboard'; $$flag{$key}{page} = 0; @@ -918,6 +933,8 @@ sub make_structure { } elsif ($cms eq 'webct4') { if ($type eq 'webctquiz') { $src = $srcstem.'/pages/'.$res.'.page'; + $$count{$key}{page} ++; + $$flag{$key}{seq} = 0; } else { if (grep/^$file$/,@{$$hrefs{$res}}) { my $filename; @@ -1710,7 +1727,7 @@ sub parse_bb5_assessment { $id = $attr->{id}; } elsif ( ($state[0] eq $toptag{$container}) && ($state[1] =~ m/^QUESTION_(\w+)$/) && ($state[2] eq "BODY") && ($state[3] eq "FLAGS") ) { if ($state[4] eq "ISHTML") { - $$settings{$id}{html} = $attr->{value}; + $$settings{$id}{ishtml} = $attr->{value}; } elsif ($state[4] eq "ISNEWLINELITERAL") { $$settings{$id}{newline} = $attr->{value}; } @@ -1860,15 +1877,6 @@ sub parse_webct4_quizprops { [sub { my ($tagname, $attr) = @_; push @state, $tagname; - my $depth = 0; - my @seq = (); - if ($state[0] eq 'properties' && $state[1] eq 'processing') { - if ($state[2] eq 'scores' && $state[3] eq 'score') { - $$qzparams{$res}{weight} = $attr->{linkrefid}; - } elsif ($state[2] eq 'selection' && $state[3] eq 'select') { - $$qzparams{$res}{numpick} = $attr->{linkrefid}; - } - } }, "tagname, attr"], text_h => [sub { @@ -1877,15 +1885,23 @@ sub parse_webct4_quizprops { if ($state[2] eq 'time_available') { $$qzparams{$res}{opendate} = $text; } elsif ($state[2] eq 'time_due') { - $$qzparams{$res}{opendate} = $text; + $$qzparams{$res}{duedate} = $text; } elsif ($state[3] eq 'max_attempt') { $$qzparams{$res}{tries} = $text; } elsif ($state[3] eq 'post_submission') { $$qzparams{$res}{posts} = $text; + } elsif ($state[3] eq 'method') { + $$qzparams{$res}{method} = $text; + } + } elsif ($state[0] eq 'properties' && $state[1] eq 'processing') { + if ($state[2] eq 'scores' && $state[3] eq 'score') { + $$qzparams{$res}{weight} = $text; + } elsif ($state[2] eq 'selection' && $state[3] eq 'select') { + $$qzparams{$res}{numpick} = $text; } } elsif ($state[0] eq 'properties' && $state[1] eq 'result') { if ($state[2] eq 'display_answer') { - $$qzparams{$res}{answerdate} = $text; + $$qzparams{$res}{showanswer} = $text; } } }, "dtext"], @@ -2257,7 +2273,7 @@ sub parse_webct4_questionDB { } sub process_assessment { - my ($cms,$context,$res,$docroot,$container,$dirname,$destdir,$settings,$total,$udom,$uname,$pagesfiles,$sequencesfiles,$randompicks,$dbparse,$resources,$items,$catinfo,$qzdbsettings) = @_; + my ($cms,$context,$res,$docroot,$container,$dirname,$destdir,$settings,$total,$udom,$uname,$pagesfiles,$sequencesfiles,$randompicks,$dbparse,$resources,$items,$catinfo,$qzdbsettings,$hrefs) = @_; my @allids = (); my %allanswers = (); my %allchoices = (); @@ -2271,7 +2287,7 @@ sub process_assessment { my $randompickflag = 0; my ($cid,$cdom,$cnum); if ($context eq 'DOCS') { - $cid = $ENV{'request.course.id'}; + $cid = $env{'request.course.id'}; ($cdom,$cnum) = split/_/,$cid; } my $destresdir = $destdir; @@ -2329,7 +2345,7 @@ sub process_assessment { if (!-e "$destdir/problems/$seqname") { mkdir("$destdir/problems/$seqname",0755); } - my $newdir = "$destdir/problems/$seqname"; + $newdir = "$destdir/problems/$seqname"; my $dbcontainerdir; &build_problem_container($cms,$seqname,$destdir,'database',$seqname,$total,$sequencesfiles,$pagesfiles,$randompickflag,$context,\@{$$catinfo{$category}{contents}},$udom,$uname,$dirname,\$dbcontainerdir,$cid,$cdom,$cnum,$catinfo,$qzdbsettings); } @@ -2338,13 +2354,11 @@ sub process_assessment { $$dbparse = 1; } &parse_webct4_assessment($res,$docroot,$$resources{$res}{file},$container,\@allids); - &parse_webct4_quizprops($res,$docroot,$$resources{$$items{$$resources{$res}{revitm}}{properties}}{file},$container,\%qzparams); - foreach (sort keys %qzparams) { - if (exists($qzparams{$res}{numpick})) { - if ($qzparams{$res}{numpick} < @allids) { - $$randompicks{$res} = $qzparams{$res}{numpick}; - $randompickflag = 1; - } + &parse_webct4_quizprops($res,$docroot,$$hrefs{$$items{$$resources{$res}{revitm}}{properties}}[0],$container,\%qzparams); + if (exists($qzparams{$res}{numpick})) { + if ($qzparams{$res}{numpick} < @allids) { + $$randompicks{$$resources{$res}{revitm}} = $qzparams{$res}{numpick}; + $randompickflag = 1; } } } @@ -2359,14 +2373,18 @@ sub process_assessment { if (!-e "$destdir/problems/$dirtitle") { mkdir("$destdir/problems/$dirtitle",0755); } - my $newdir = "$destdir/problems/$dirtitle"; + $newdir = "$destdir/problems/$dirtitle"; } - &build_problem_container($cms,$dirtitle,$destdir,$container,$res,$total,$sequencesfiles,$pagesfiles,$randompickflag,$context,\@allids,$udom,$uname,$dirname,\$containerdir,$cid,$cdom,$cnum,$catinfo,$qzdbsettings); + if ($cms eq 'webct4') { + &build_problem_container($cms,$dirtitle,$destdir,$container,$res,$total,$sequencesfiles,$pagesfiles,$randompickflag,$context,\@allids,$udom,$uname,$dirname,\$containerdir,$cid,$cdom,$cnum,$catinfo,$qzdbsettings); + } else { + &build_problem_container($cms,$dirtitle,$destdir,$container,$res,$total,$sequencesfiles,$pagesfiles,$randompickflag,$context,\@allids,$udom,$uname,$dirname,\$containerdir,$cid,$cdom,$cnum,$catinfo,$settings); + } if ($cms eq 'bb5') { - &write_bb5_questions(\@allids,$containerdir,$context,$settings,$dirname,$res,\%allanswers,\%allchoices,$total,$newdir,$cid,$cdom,$cnum); + &write_bb5_questions(\@allids,$containerdir,$context,$settings,$dirname,$destdir,$res,\%allanswers,\%allchoices,$total,$newdir,$cid,$cdom,$cnum,$docroot); } elsif ($cms eq 'bb6') { - &write_bb6_questions(\@allids,$containerdir,$context,$settings,$dirname,$res,\%allanswers,\%allchoices,$total,$newdir,$cid,$cdom,$cnum); + &write_bb6_questions(\@allids,$containerdir,$context,$settings,$dirname,$destdir,$res,\%allanswers,\%allchoices,$total,$newdir,$cid,$cdom,$cnum); } } @@ -2400,7 +2418,11 @@ sub build_problem_container { my $probsrc = "/res/lib/templates/simpleproblem.problem"; if ($context eq 'CSTR') { foreach my $id (@{$allids}) { - $probtitle{$id} = $$settings{$id}{title}; + if ($cms eq 'webct4') { + $probtitle{$id} = $$settings{$id}{title}; + } else { + $probtitle{$id} = $$settings{title}; + } $probtitle{$id} =~ s/\s/_/g; $probtitle{$id} =~ s/\W//g; $probtitle{$id} .= '_'.$id; @@ -2412,7 +2434,7 @@ sub build_problem_container { $probdir =~ s/\W//g; $probsrc = "$dirname/problems/$probdir/$probtitle{$$allids[0]}.problem"; } else { - $probsrc="$dirname/problems/$dirtitle/$$allids[0].problem"; + $probsrc="$dirname/problems/$dirtitle/$probtitle{$$allids[0]}.problem"; } } print $fh qq||; @@ -2436,7 +2458,7 @@ sub build_problem_container { $probdir =~ s/\W//g; $probsrc = "$dirname/problems/$probdir/$probtitle{$$allids[$j]}.problem"; } else { - $probsrc = "$dirname/problems/$dirtitle/$$allids[$j].problem"; + $probsrc = "$dirname/problems/$dirtitle/$probtitle{$$allids[$j]}.problem"; } } print $fh qq| @@ -2454,9 +2476,19 @@ sub build_problem_container { } sub write_bb5_questions { - my ($allids,$containerdir,$context,$settings,$dirname,$res,$allanswers,$allchoices,$total,$newdir,$cid,$cdom,$cnum) = @_; + my ($allids,$containerdir,$context,$settings,$dirname,$destdir,$res,$allanswers,$allchoices,$total,$newdir,$cid,$cdom,$cnum,$docroot) = @_; my $qnum = 0; foreach my $id (@{$allids}) { + if ($$settings{$id}{ishtml} eq 'true') { + $$settings{$id}{text} = &HTML::Entities::decode($$settings{$id}{text}); + } + if ($$settings{$id}{text} =~ m#]*>#) { + if (&retrieve_image($context,$res,$dirname,$cdom,$cnum,$docroot,$destdir,$1,$2) eq 'ok') { + $$settings{$id}{text} =~ s#(]*>)#$1../../resfiles/$res/webimages/$3$4#g; + } + } + $$settings{$id}{text} =~ s#(]+)/*>#$1 />#gi; + $$settings{$id}{text} =~ s#
#
#g; $qnum ++; my $output; my $permcontainer = $containerdir; @@ -2800,7 +2832,11 @@ sub write_bb5_questions { if ($context eq 'CSTR') { $output .= qq| |; - open(PROB,">$newdir/problems/$id.problem"); + my $title = $$settings{title}; + $title =~ s/\s/_/g; + $title =~ s/\W//g; + $title .= '_'.$id; + open(PROB,">:utf8", "$newdir/$title.problem"); print PROB $output; close PROB; } else { @@ -2829,14 +2865,14 @@ sub write_webct4_questions { } if ($$settings{$id}{texttype} eq 'text/html') { $$settings{$id}{text} = &HTML::Entities::decode($$settings{$id}{text}); - $$settings{$id}{text} = &Apache::lonxml::htmlclean($$settings{$id}{text}); - $$settings{$id}{text} =~ s#(]+)(/?>)#$1../../resfiles/$2 />#gi; + $$settings{$id}{text} =~ s#<([bh])r>#<$1r />#g; # $$settings{$id}{text} =~ s#

#

#g; # $$settings{$id}{text} =~ s#

#

#; # $$settings{$id}{text} =~ s#

##g; $$settings{$id}{text} =~ s#

#

#g; - $$settings{$id}{text} =~ s#<\\p>##g; + $$settings{$id}{text} =~ s#

##g; } if ($$settings{$id}{class} eq 'numerical') { foreach my $numid (@{$$settings{$id}{numids}}) { @@ -2857,8 +2893,10 @@ sub write_webct4_questions { $resourcedata{$symb.'randomize'} = 'yes'; $resourcedata{$symb.'maxfoils'} = 10; if ($context eq 'CSTR') { - $output = qq| + unless ($$settings{$id}{class} eq 'numerical') { + $output = qq| |; + } } $$total{prob} ++; if (exists($$settings{$id}{uri})) { @@ -2919,7 +2957,7 @@ sub write_webct4_questions { } if ($$settings{$id}{$list}{$$allanswers{$id}{$list}[$k]}{texttype} eq 'text/html') { $$settings{$id}{$list}{$$allanswers{$id}{$list}[$k]}{text} = &HTML::Entities::decode($$settings{$id}{$list}{$$allanswers{$id}{$list}[$k]}{text}); - $$settings{$id}{$list}{$$allanswers{$id}{$list}[$k]}{text} = &Apache::lonxml::htmlclean($$settings{$id}{$list}{$$allanswers{$id}{$list}[$k]}{text}); + $$settings{$id}{$list}{$$allanswers{$id}{$list}[$k]}{text} = &Apache::loncleanup::htmlclean($$settings{$id}{$list}{$$allanswers{$id}{$list}[$k]}{text}); $$settings{$id}{$list}{$$allanswers{$id}{$list}[$k]}{text} =~ s#(]+)>#$1../../resfiles/$2 />#gi; $$settings{$id}{$list}{$$allanswers{$id}{$list}[$k]}{text} =~ s###g; @@ -2993,7 +3031,7 @@ sub write_webct4_questions { $$settings{$id}{$grp}{$answer_id}{text} = &HTML::Entities::decode($$settings{$id}{$grp}{$answer_id}{text}); $test_for_html = &test_for_html($$settings{$id}{$grp}{$answer_id}{text}); - $$settings{$id}{$grp}{$answer_id}{text} = &Apache::lonxml::chtmlclean($$settings{$id}{$grp}{$answer_id}{text}); + $$settings{$id}{$grp}{$answer_id}{text} = &Apache::loncleanup::htmlclean($$settings{$id}{$grp}{$answer_id}{text}); $$settings{$id}{$grp}{$answer_id}{text} =~ s#( - + |; } } else { @@ -3056,7 +3094,7 @@ sub write_webct4_questions { for (my $k=0; $k<@{$$allchoices{$id}}; $k++) { if ($$settings{$id}{$$allchoices{$id}[$k]}{texttype} eq 'text/html') { $$settings{$id}{$$allchoices{$id}[$k]}{text} = &HTML::Entities::decode($$settings{$id}{$$allchoices{$id}[$k]}{text}); - $$settings{$id}{$$allchoices{$id}[$k]}{text} = &Apache::lonxml::htmlclean($$settings{$id}{$$allchoices{$id}[$k]}{text}); + $$settings{$id}{$$allchoices{$id}[$k]}{text} = &Apache::loncleanup::htmlclean($$settings{$id}{$$allchoices{$id}[$k]}{text}); $$settings{$id}{$$allchoices{$id}[$k]}{text} =~ s#( |; foreach my $numid (@{$$settings{$id}{numids}}) { my $formula = $$settings{$id}{$numid}{formula}; + my $pattern = join('|',(sort (keys (%mathfns)))); + $formula =~ s/($pattern)/\&$mathfns{$1}/g; foreach my $var (keys %{$$settings{$id}{$numid}{vars}}) { my $decnum = $$settings{$id}{$numid}{vars}{$var}{dec}; my $increment = '0.'; @@ -3231,9 +3292,7 @@ sub write_webct4_questions { } $increment .= '1'; } - $formula =~ s/{($var)}/\$$1/g; - $formula =~ s/ln\(?([^\)])\)?/ &log($1) /g; - $formula =~ s/sqrt/\&sqrt/g; + $formula =~ s/{($var)}/(\$$1)/g; $scriptblock .= qq| \$$var=&random($$settings{$id}{$numid}{vars}{$var}{min},$$settings{$id}{$numid}{vars}{$var}{max},$increment); |; @@ -3243,7 +3302,7 @@ sub write_webct4_questions { |; if ($context eq 'CSTR') { - $output = $scriptblock.$output; + $output = "\n".$scriptblock.$output; my $ansformat = ''; my $sigfig = '0,15'; if ($$settings{$id}{$numid}{format} eq 'sig') { @@ -3321,7 +3380,49 @@ sub test_for_html { } sub write_bb6_questions { - my ($allids,$containerdir,$context,$settings,$dirname,$res,$allanswers,$allchoices) = @_; + my ($allids,$containerdir,$context,$settings,$dirname,$destdir,$res,$allanswers,$allchoices) = @_; +} + +sub retrieve_image { + my ($context,$res,$dirname,$cdom,$cname,$docroot,$destdir,$urlpath,$filename) = @_; + my $contents; + my $url = $urlpath.$filename; + my $ua=new LWP::UserAgent; + my $request=new HTTP::Request('GET',$url); + my $response=$ua->request($request); + if ($response->is_success) { + $contents = $response->content; + if (!-e "$docroot/$res") { + mkdir("$docroot/$res",0755); + } + if (!-e "$docroot/$res/webimages") { + mkdir("$docroot/$res/webimages",0755); + } + open(my $fh,">$docroot/$res/webimages/$filename"); + print $fh $contents; + close($fh); + if ($context eq 'DOCS') { + my $chome = &Apache::lonnet::homeserver($cname,$cdom); + my $copyfile = $dirname.'/'.$filename; + my $source = "$docroot/$res/webimages/$filename"; + my $fileresult; + if (-e $source) { + $fileresult = &Apache::lonnet::process_coursefile('copy',$cname,$cdom,$chome,$copyfile,$source); + } + return $fileresult; + } elsif ($context eq 'CSTR') { + if (!-e "$destdir/resfiles/$res") { + mkdir("$destdir/resfiles/$res",0755); + } + if (!-e "$destdir/resfiles/$res/webimages") { + mkdir("$destdir/resfiles/$res/webimages",0755); + } + rename("$docroot/$res/webimages/$filename","$destdir/resfiles/$res/webimages/$filename"); + return 'ok'; + } + } else { + return -1; + } } # ---------------------------------------------------------------- Process Blackboard Announcements