--- loncom/imspackages/imsprocessor.pm 2007/09/30 13:20:08 1.41
+++ loncom/imspackages/imsprocessor.pm 2008/08/25 13:43:39 1.44
@@ -25,6 +25,7 @@ package Apache::imsprocessor;
use Apache::lonnet;
use Apache::loncleanup;
+use Apache::lonlocal;
use LWP::UserAgent;
use HTTP::Request::Common;
use LONCAPA::Configuration;
@@ -75,7 +76,7 @@ sub ims_config {
survey => 'webctsurvey',
doc => 'webcontent'
);
- %{$areaname} = (
+ %{$areaname} = &Apache::lonlocal::texthash (
announce => 'Announcements',
board => 'Discussion Boards',
doc => 'Documents, pages, and folders',
@@ -308,7 +309,6 @@ sub parse_manifest {
if ($cms eq 'bb5' || $cms eq 'bb6' ||
$cms eq 'webctce4' || $cms eq 'webctvista4') {
push @{$$hrefs{$identifier}},$attr->{href};
-
if ($$resources{$identifier}{type} eq
'webct.manifest') {
my $manifestfile = $tempdir.'/'.$attr->{href};
@@ -409,7 +409,7 @@ sub target_resources {
}
sub copy_resources {
- my ($context,$cms,$hrefs,$tempdir,$targets,$url,$crs,$cdom,$destdir,$timenow,$assessmentfiles) = @_;
+ my ($context,$cms,$hrefs,$tempdir,$targets,$url,$crs,$cdom,$destdir,$timenow,$assessmentfiles,$total) = @_;
if ($context eq 'DOCS') {
foreach my $key (sort keys %{$hrefs}) {
if (grep/^$key$/,@{$targets}) {
@@ -466,10 +466,18 @@ sub copy_resources {
mkdir("$fulldir",0770);
}
}
+ my $renameres;
if ($cms eq 'angel') {
- rename("$tempdir/_assoc/$key/$file","$destdir/resfiles/$key/$file");
+ $renameres = rename("$tempdir/_assoc/$key/$file","$destdir/resfiles/$key/$file");
} elsif ($cms eq 'bb5' || $cms eq 'bb6') {
- rename("$tempdir/$key/$file","$destdir/resfiles/$key/$file");
+ $renameres = rename("$tempdir/$key/$file","$destdir/resfiles/$key/$file");
+ }
+ if ($renameres) {
+ if (ref($total) eq 'HASH') {
+ $$total{'file'} ++;
+ }
+ } else {
+ &Apache::lonnet::logthis("IMS import error: $cms - renaming failed for file $file");
}
} elsif ($cms eq 'webctce4') {
if ($file =~ m-/my_files/(.+)$-) {
@@ -486,7 +494,14 @@ sub copy_resources {
}
}
if (-e "$tempdir/$file") {
- rename("$tempdir/$file","$destdir/resfiles/$copyfile");
+ my $renameres = rename("$tempdir/$file","$destdir/resfiles/$copyfile");
+ if ($renameres) {
+ if (ref($total) eq 'HASH') {
+ $$total{'file'} ++;
+ }
+ } else {
+ &Apache::lonnet::logthis("IMS import error: WebCT4 - renaming failed for file $file");
+ }
}
} elsif ($file !~ m-/data/(.+)$-) {
&Apache::lonnet::logthis("IMS import error: WebCT4 - file $file is in unexpected location");
@@ -620,7 +635,11 @@ sub process_resinfo {
if (grep/^$key$/,@{$targets}) {
if ($$resources{$key}{type} eq "webcontent") {
%{$$resinfo{$key}} = ();
- &webct4_content($key,$docroot,$destdir,\%{$$resinfo{$key}},$udom,$uname,$$resources{$key}{type},$$items{$$resources{$key}{revitm}}{title},$resrcfiles);
+ if ($$resources{$key}{file} eq 'questiondb.xml') {
+ &process_assessment($cms,$context,$key,$docroot,'quiz',$dirname,$destdir,\%{$$resinfo{$key}},$total,$udom,$uname,$pagesfiles,$sequencesfiles,$randompicks,\$dbparse,$resources,$items,\%catinfo,\%qzdbsettings,$hrefs,\%allquestions);
+ } else {
+ &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,$hrefs,\%allquestions);
}
@@ -735,7 +754,11 @@ sub build_structure {
my $curr_id = 1;
my $resnum = $$items{$key}{resnum};
my $type = $$resources{$resnum}{type};
- my $contentscount = $$items{$key}{'contentscount'};
+ my $contentscount = $$items{$key}{'contentscount'};
+ my $seqtitle = $$items{$key}{'title'};
+ $seqtitle =~ s|/+|_|g;
+ $seqtitle =~ s/\s+/_/g;
+ $seqtitle .= '_'.$key;
if (($cms eq 'angel' && $type eq "FOLDER") || (($cms eq 'bb5' || $cms eq 'bb6') && $$resinfo{$resnum}{'isfolder'} eq "true") && (($type eq "resource/x-bb-document") || ($type eq "resource/x-bb-staffinfo") || ($type eq "resource/x-bb-externallink")) || ($cms eq 'webctce4' && $contentscount > 0)) {
unless (($cms eq 'bb5') && $key eq 'Top') {
$seqtext{$key} = "\n";
- open(LOCFILE,">$destdir/sequences/$key.sequence");
+ if ($cms eq 'webctce4' && $key ne 'Top') {
+ push @{$seqfiles}, "$seqtitle.sequence";
+ open(LOCFILE,">$destdir/sequences/$seqtitle.sequence");
+ } else {
+ push @{$seqfiles}, "$key.sequence";
+ open(LOCFILE,">$destdir/sequences/$key.sequence");
+ }
print LOCFILE $seqtext{$key};
close(LOCFILE);
- push @{$seqfiles}, "$key.sequence";
}
$count{$key}{page} ++;
$$total{page} += $count{$key}{page};
@@ -972,10 +1000,16 @@ sub build_structure {
}
sub make_structure {
- my ($cms,$key,$srcstem,$flag,$count,$timestamp,$boardnum,$hrefs,$pagecontents,$res,$type,$file,$resinfo,$contitem,$uname,$cdom,$contcount,$packageflag,$contitemcount,$randompick) = @_;
+ my ($cms,$key,$srcstem,$flag,$count,$timestamp,$boardnum,$hrefs,$pagecontents,$res,$type,$file,$resinfo,$contitem,$uname,$cdom,$contcount,$packageflag,$contitemcount,$randompick,$title) = @_;
my $src ='';
if (($cms eq 'angel' && $type eq 'FOLDER') || (($cms eq 'bb5' || $cms eq 'bb6') && (($$resinfo{$res}{'isfolder'} eq 'true') || $key eq 'Top')) || ($cms eq 'webctce4' && $contitemcount > 0)) {
$src = $srcstem.'/sequences/'.$contitem.'.sequence';
+ if ($cms eq 'webctce4') {
+ $title =~ s|/+|_|g;
+ $title =~ s/\s+/_/g;
+ $title .= '_'.$contitem;
+ $src = $srcstem.'/sequences/'.$title.'.sequence';
+ }
$$flag{$key}{page} = 0;
$$flag{$key}{seq} = 1;
$$count{$key}{seq} ++;
@@ -1038,14 +1072,16 @@ sub make_structure {
if ($file =~ m-/([^/]+)$-) {
$filename = $1;
}
- $src = $srcstem.'/resfiles/'.$res.'/'.$filename;
+ $src = $srcstem.'/resfiles/'.$filename;
} else {
foreach my $file (@{$$hrefs{$res}}) {
my $filename;
- if ($file =~ m-/([^/]+)$-) {
+ if ($file =~ m-/my_files/(.+)$-) {
+ $filename = $1;
+ } elsif ($file =~ m-/([^/]+)$-) {
$filename = $1;
}
- $src = $srcstem.'/resfiles/'.$res.'/'.$filename;
+ $src = $srcstem.'/resfiles/'.$filename;
}
}
$$flag{$key}{page} = 0;
@@ -2743,8 +2779,13 @@ sub parse_webct4_quizprops {
sub parse_webct4_questionDB {
my ($docroot,$href,$catinfo,$settings,$allanswers,$allchoices,$allids) = @_;
- $href =~ s#[^/]+$##;
- my $xmlfile = $docroot.'/'.$href.'questionDB.xml'; #quizDB file
+ my $xmlfile;
+ if ($href eq 'questiondb.xml') {
+ $xmlfile = $docroot.'/'.$href;
+ } else {
+ $href =~ s#[^/]+$##;
+ $xmlfile = $docroot.'/'.$href.'questionDB.xml'; #quizDB file
+ }
my @state = ();
my $category; # the current category ID
my $id; # the current question ID
@@ -2765,14 +2806,19 @@ sub parse_webct4_questionDB {
action => '',
);
my $currtexttype;
- my $currimagtype;
+ my $currimagtype;
+ my $is_objectbank;
my $p = HTML::Parser->new
(
xml_mode => 1,
start_h =>
[sub {
my ($tagname, $attr) = @_;
- push @state, $tagname;
+ if (("@state" eq "questestinterop") && ($tagname eq 'objectbank')) {
+ $is_objectbank = 1;
+ } else {
+ push @state, $tagname;
+ }
if ("@state" eq "questestinterop section") {
$category = $attr->{ident};
%{$$catinfo{$category}} = ();
@@ -2861,6 +2907,10 @@ sub parse_webct4_questionDB {
$$settings{$id}{$list}{$answer_id}{texttype} = $attr->{texttype};
$currtexttype = $attr->{texttype};
}
+ if ("@state" eq "questestinterop section item presentation flow response_lid render_choice flow_label response_label flow_mat material mattext") {
+ $$settings{$id}{$list}{$answer_id}{texttype} = $attr->{texttype};
+ $currtexttype = $attr->{texttype};
+ }
# Numerical
if ("@state" eq "questestinterop section item presentation material mat_extension webct:x_webct_v01_dynamicmattext") {
@@ -2947,7 +2997,9 @@ sub parse_webct4_questionDB {
}
}
if ("@state" eq "questestinterop section item resprocessing respcondition setvar") {
- $setvar{varname} = $attr->{varname};
+ foreach my $key (keys(%{$attr})) {
+ $setvar{$key} = $attr->{$key};
+ }
if ($setvar{varname} eq 'WebCT_Correct') {
push(@{$$settings{$id}{$grp}{correctanswer}},$answer_id);
}
@@ -2978,6 +3030,7 @@ sub parse_webct4_questionDB {
}
if ("@state" eq "questestinterop section item itemfeedback") {
$fdbk = $attr->{ident};
+ push(@{$$settings{$id}{feedback}},$fdbk);
$$settings{$id}{$fdbk}{view} = $attr->{view};
}
if ("@state" eq "questestinterop section item itemfeedback material mattext") {
@@ -3021,6 +3074,9 @@ sub parse_webct4_questionDB {
if ("@state" eq "questestinterop section item presentation flow response_lid render_choice flow_label response_label material mattext") {
$$settings{$id}{$list}{$answer_id}{text} = $text;
}
+ if ("@state" eq "questestinterop section item presentation flow response_lid render_choice flow_label response_label flow_mat material mattext") {
+ $$settings{$id}{$list}{$answer_id}{text} = $text;
+ }
# Numerical
if ("@state" eq "questestinterop section item presentation material mat_extension webct:x_webct_v01_dynamicmattext") {
@@ -3071,6 +3127,14 @@ sub parse_webct4_questionDB {
push(@{$$settings{$id}{$list}{correctanswer}},$answer_id);
}
}
+ } elsif ($is_objectbank) { #Multiple Choice WebCT 4.1 D2L objectbank
+ if ($setvar{action} eq "Set") {
+ if ($text =~ /^\d+\.?\d*$/) {
+ if ($text > 0.000000001) {
+ push(@{$$settings{$id}{$list}{correctanswer}},$answer_id);
+ }
+ }
+ }
}
}
if ("@state" eq "questestinterop section item resprocessing itemproc_extension webct:x_webct_v01_autocalculate webct:x_webct_v01_anstolerance") {
@@ -3087,7 +3151,11 @@ sub parse_webct4_questionDB {
end_h =>
[sub {
my ($tagname) = @_;
- pop @state;
+ if (("@state" eq "questestinterop") && ($tagname eq 'objectbank')) {
+ $is_objectbank = '';
+ } else {
+ pop @state;
+ }
}, "tagname"],
);
$p->unbroken_text(1);
@@ -3105,6 +3173,22 @@ sub parse_webct4_questionDB {
}
}
}
+ } elsif ($$settings{$id}{class} eq 'multiplechoice') {
+ if (ref($$settings{$id}) eq 'HASH') {
+ foreach my $list (keys(%{$$settings{$id}})) {
+ if (ref($$settings{$id}{$list}) eq 'HASH') {
+ if (defined($$settings{$id}{$list}{rcardinality})) {
+ if ($$settings{$id}{$list}{rcardinality} eq 'Multiple') {
+ if (ref($$settings{$id}{$list}{correctanswer}) eq 'ARRAY') {
+ if (@{$$settings{$id}{$list}{correctanswer}} == 1) {
+ $$settings{$id}{$list}{rcardinality} = 'Single';
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
}
}
@@ -3183,7 +3267,9 @@ sub process_assessment {
}
if ($cms eq 'webctce4') {
- &build_problem_container($cms,$dirtitle,$destdir,$container,$res,$total,$sequencesfiles,$pagesfiles,$randompickflag,$context,\@allids,$udom,$uname,$dirname,\$containerdir,$cid,$cdom,$cnum,$catinfo,$qzdbsettings);
+ if (@allids > 0 && $allids[0] ne '') {
+ &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,$qzdbsettings,\%qzparams);
}
@@ -3296,6 +3382,7 @@ sub build_problem_container {
}
$probtitle{$id} =~ s/\s+/_/g;
$probtitle{$id} =~ s/:/_/g;
+ $probtitle{$id} =~ s/\//_/g;
$probtitle{$id} .= '_'.$id;
}
if (($cms eq 'webctce4' && $container ne 'database') ||
@@ -3755,10 +3842,12 @@ sub write_webct4_questions {
my $questionimage;
foreach my $fdbk (@{$$settings{$id}{feedback}}) {
my $feedback = $$settings{$id}{$fdbk}{text};
- if ($$settings{$id}{$fdbk}{texttype} eq 'text/html') {
- $feedback = &HTML::Entities::decode($feedback);
+ if ($feedback ne '') {
+ if ($$settings{$id}{$fdbk}{texttype} eq 'text/html') {
+ $feedback = &HTML::Entities::decode($feedback);
+ }
+ $allfeedback .= $feedback;
}
- $allfeedback .= $feedback;
}
if ($$settings{$id}{texttype} eq 'text/html') {
if ($$settings{$id}{text}) {
@@ -3818,9 +3907,6 @@ sub write_webct4_questions {
'.$$settings{$id}{text}.'
'.$questionimage; @@ -4331,11 +4417,19 @@ $$settings{$id}{$list}{jumbledtext}[$k] if (!-e "$destdir/problems/$probdir") { mkdir("$destdir/problems/$probdir",0755); } + if ($allfeedback ne '') { + $output .= qq| +