--- loncom/publisher/testbankimport.pm 2010/11/27 22:43:32 1.26 +++ loncom/publisher/testbankimport.pm 2014/02/11 19:11:18 1.44 @@ -1,5 +1,5 @@ # Handler for parsing text upload problem descriptions into .problems -# $Id: testbankimport.pm,v 1.26 2010/11/27 22:43:32 raeburn Exp $ +# $Id: testbankimport.pm,v 1.44 2014/02/11 19:11:18 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -28,7 +28,6 @@ package Apache::testbankimport; use strict; use Apache::Constants qw(:common :http :methods); -use Apache::loncacc; use Apache::loncommon(); use Apache::lonnet; use HTML::Entities(); @@ -90,7 +89,7 @@ function createWin() { newWindow.document.write("") newWindow.document.write("") newWindow.document.write("$webpath") - newWindow.document.write("") + newWindow.document.write("") newWindow.document.write('$end_page') newWindow.document.close() newWindow.focus() @@ -290,18 +289,20 @@ function colSet(caller) { else { if ((poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "MC") || (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "MA") || (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "Ord")) { poolForm.elements[caller*5+4].options[0] = new Option("Select","-1",true,true) - poolForm.elements[caller*5+4].options[1] = new Option("a.","lcperiod",false,false) - poolForm.elements[caller*5+4].options[2] = new Option("A.","ucperiod",false,false) - poolForm.elements[caller*5+4].options[3] = new Option("(a)","lcparen",false,false) - poolForm.elements[caller*5+4].options[4] = new Option("(A)","ucparen",false,false) - poolForm.elements[caller*5+4].options[5] = new Option("a)","lconeparen",false,false) - poolForm.elements[caller*5+4].options[6] = new Option("A)","uconeparen",false,false) - poolForm.elements[caller*5+4].options[7] = new Option("a.)","lcdotparen",false,false) - poolForm.elements[caller*5+4].options[8] = new Option("A.)","ucdotparen",false,false) - poolForm.elements[caller*5+4].options[9] = new Option("(i)","romparen",false,false) - poolForm.elements[caller*5+4].options[10] = new Option("i)","romoneparen",false,false) - poolForm.elements[caller*5+4].options[11] = new Option("i.)","romdotparen",false,false) - poolForm.elements[caller*5+4].options[12] = new Option("i.","romperiod",false,false) + poolForm.elements[caller*5+4].options[1] = new Option("a ","lcspace",false,false) + poolForm.elements[caller*5+4].options[2] = new Option("A ","ucspace",false,false) + poolForm.elements[caller*5+4].options[3] = new Option("a.","lcperiod",false,false) + poolForm.elements[caller*5+4].options[4] = new Option("A.","ucperiod",false,false) + poolForm.elements[caller*5+4].options[5] = new Option("(a)","lcparen",false,false) + poolForm.elements[caller*5+4].options[6] = new Option("(A)","ucparen",false,false) + poolForm.elements[caller*5+4].options[7] = new Option("a)","lconeparen",false,false) + poolForm.elements[caller*5+4].options[8] = new Option("A)","uconeparen",false,false) + poolForm.elements[caller*5+4].options[9] = new Option("a.)","lcdotparen",false,false) + poolForm.elements[caller*5+4].options[10] = new Option("A.)","ucdotparen",false,false) + poolForm.elements[caller*5+4].options[11] = new Option("(i)","romparen",false,false) + poolForm.elements[caller*5+4].options[12] = new Option("i)","romoneparen",false,false) + poolForm.elements[caller*5+4].options[13] = new Option("i.)","romdotparen",false,false) + poolForm.elements[caller*5+4].options[14] = new Option("i.","romperiod",false,false) poolForm.elements[caller*5+4].selectedIndex = 0 } else { @@ -445,7 +446,7 @@ function verify() { if ($numitems > 0) { my $maxnum = $numitems - 1; my %lt = &Apache::lonlocal::texthash( - fnmb => 'File names must be unique', + fnmb => 'Filenames must be unique', isum => 'is used more than once', ); $$jsref .= qq| @@ -485,12 +486,12 @@ function backPage() { # ---------------------------------------------------------------- Display Zero sub display_zero { - my ($r,$uname,$fn,$page,$webpath) = @_; + my ($r,$fn,$page,$webpath) = @_; my $go_default = 'NextPage'; if ($fn eq '') { - $r->print(''.&mt('Incomplete file upload').' '.&mt('Return to the [_1]construction space menu[_2] to upload a file','','')); + $r->print(''.&mt('Incomplete file upload').' '.&mt('Return to the [_1]Authoring Space menu[_2] to upload a file','','')); } - $r->print(&mt('The Testbank Upload utility can be used by LON-CAPA authors to generate LON-CAPA problem files from a testbank file of questions/answers.').'
'. + $r->print(&mt('The [_1]Testbank Upload[_2] utility can be used by LON-CAPA authors to generate LON-CAPA problem files from a testbank file of questions/answers.','','').'
'. &mt('The following question types can be converted:').' '. - &page_footer($env{'form.newdir'},$uname,$fn,$page).' + &page_footer($env{'form.newdir'},$fn,$page).' '); return; } # ---------------------------------------------------------------- Display Three sub display_three { - my ($r,$uname,$fn,$page,$textref,$res,$header,$urlpath,$qcount) = @_; + my ($r,$fn,$page,$textref,$res,$header,$webpath,$qcount) = @_; my $qnumformat = $env{'form.qnumformat'}; my $filename = $env{'form.filename'}; my $source = $env{'form.go'}; @@ -682,7 +683,7 @@ sub display_three { my %lt = &Apache::lonlocal::texthash ( crt => 'Create?', typ => 'Type', - fnam => 'File Name', + fnam => 'Filename', ques => 'Question', answ => 'Answer', chka => 'check all', @@ -715,7 +716,7 @@ sub display_three { if ($header ne '') { $showheader = &HTML::Entities::decode($header); if ($res eq 'text/html') { - $showheader = &build_image_url($urlpath,$showheader); + $showheader = &build_image_url($webpath,$showheader); } } } @@ -764,7 +765,7 @@ sub display_three { if (($res eq 'application/rtf') || ($res eq 'text/html')) { $showqn = &HTML::Entities::decode($showqn); if ($res eq 'text/html') { - $showqn = &build_image_url($urlpath,$showqn); + $showqn = &build_image_url($webpath,$showqn); } } $r->print(&Apache::loncommon::start_data_table_row(). @@ -775,7 +776,12 @@ sub display_three { ''.$showqn.'

'."\n"); } else { my $foiltag = ''; - if ($foilformats[$i] eq "lcperiod") { + if ($foilformats[$i] eq "lcspace") { + $foiltag = $alphabet->[$k-1].' '; + } elsif ($foilformats[$i] eq "ucspace") { + $foiltag = $alphabet->[$k-1].' '; + $foiltag =~ tr/a-z/A-Z/; + } elsif ($foilformats[$i] eq "lcperiod") { $foiltag = $alphabet->[$k-1].'.'; } elsif ($foilformats[$i] eq "lcparen") { $foiltag = '('.$alphabet->[$k-1].')'; @@ -808,7 +814,7 @@ sub display_three { if ($res eq 'application/rtf' || $res eq 'text/html') { $showfoil = &HTML::Entities::decode($showfoil); if ($res eq 'text/html') { - $showfoil = &build_image_url($urlpath,$showfoil); + $showfoil = &build_image_url($webpath,$showfoil); } } $r->print("$foiltag $showfoil
\n"); @@ -859,13 +865,13 @@ sub display_three { '); } } - $r->print('

'.&page_footer($env{'form.newdir'},$uname,$fn,$page).' + $r->print('

'.&page_footer($env{'form.newdir'},$fn,$page).' '); } # ---------------------------------------------------------------- Final Display sub final_display { - my ($r,$uname,$fn,$page,$textref,$res,$header,$css,$js,$webpath,$dirpath,$subdir) = @_; + my ($r,$fn,$page,$textref,$res,$header,$css,$js,$webpath,$dirpath,$subdir) = @_; my $qnumformat = $env{'form.qnumformat'}; my $blocks = $env{'form.blocks'}; my $question_id = ''; @@ -925,7 +931,7 @@ sub final_display { $items->[$k] =~ tr/A-Z/a-z/; $items->[$k] =~ s/<\/?[^>]+>//g; $items->[$k] =~ s/\W//g; - if ($foilformats[$i] eq "lcperiod" || $foilformats[$i] eq "lcparen" || $foilformats[$i] eq "lconeparen" || $foilformats[$i] eq "lcdotparen" || $foilformats[$i] eq "ucparen" || $foilformats[$i] eq "ucperiod" || $foilformats[$i] eq "uconeparen" || $foilformats[$i] eq "ucdotparen") { + if ($foilformats[$i] eq "lcspace" || $foilformats[$i] eq "ucspace" || $foilformats[$i] eq "lcperiod" || $foilformats[$i] eq "lcparen" || $foilformats[$i] eq "lconeparen" || $foilformats[$i] eq "lcdotparen" || $foilformats[$i] eq "ucparen" || $foilformats[$i] eq "ucperiod" || $foilformats[$i] eq "uconeparen" || $foilformats[$i] eq "ucdotparen") { for (my $j=0; $j<@{$alphabet}; $j++) { if ($alphabet->[$j] eq $items->[$k]) { push @{$answers{$qnum}}, $j; @@ -958,7 +964,7 @@ sub final_display { } else { $correct =~s/\W//g; } - if ($foilformats[$i] eq "lcperiod" || $foilformats[$i] eq "lcparen" || $foilformats[$i] eq "ucparen" || $foilformats[$i] eq "ucperiod") { + if ($foilformats[$i] eq "lcspace" || $foilformats[$i] eq "ucspace" || $foilformats[$i] eq "lcperiod" || $foilformats[$i] eq "lcparen" || $foilformats[$i] eq "ucparen" || $foilformats[$i] eq "ucperiod") { if (($qtype[$i] eq "Ord") && (@tied > 0)) { my @ties; foreach my $tie (@tied) { @@ -1042,7 +1048,7 @@ sub final_display { if (@createprobs == 0) { $state = 'unchecked'; $r->print('

'.&mt('No questions were selected for conversion.').'

'. - &page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath,$subdir,$state).''); + &page_footer($env{'form.newdir'},$fn,$page,$webpath,$subdir,$state).''); } elsif (($destdir ne '') && (-e $destdir)) { my (@qn_file,@result,@numid); my $qcount = 0; @@ -1130,11 +1136,11 @@ sub final_display { $r->print('

'.&mt('The following files already existed, and were not overwritten so these problems generated from the testbank have not been saved:').'
'.$existing.'

'); $state = 'existing'; } - $r->print(&page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath,$subdir,$state).''); + $r->print(&page_footer($env{'form.newdir'},$fn,$page,$webpath,$subdir,$state).''); } else { $state = 'nodir'; $r->print('

'.&mt('No destination directory was available so import of questions could not proceed.').'

'. - &page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath,$subdir,$state).''); + &page_footer($env{'form.newdir'},$fn,$page,$webpath,$subdir,$state).''); } return; } @@ -1159,7 +1165,7 @@ sub show_uploaded_data { } sub page_footer { - my ($newdir,$uname,$fn,$page,$webpath,$subdir,$state) = @_; + my ($newdir,$fn,$page,$webpath,$subdir,$state) = @_; my $prevval = &mt('Previous Page'); my $nextval = &mt('Next Page'); my $prevclick = 'javascript:backPage();'; @@ -1184,7 +1190,6 @@ sub page_footer { } my $output = ' - @@ -1277,7 +1282,11 @@ sub file_split { if (${$numsref}[$i] > 0) { if ((${$qtyperef}[$i] eq "MC") || (${$qtyperef}[$i] eq "MA") || (${$qtyperef}[$i] eq "Ord")) { my $splitstr = ''; - if (${$foilsref}[$i] eq "lcperiod") { + if (${$foilsref}[$i] eq "lcspace") { + $splitstr = '[a-z]\s'; + } elsif (${$foilsref}[$i] eq "ucspace") { + $splitstr = '[A-Z]\s'; + } elsif (${$foilsref}[$i] eq "lcperiod") { $splitstr = '[a-z]\.'; } elsif (${$foilsref}[$i] eq "lcparen") { $splitstr = '\([a-z]\)'; @@ -1330,7 +1339,11 @@ sub create_mcq { my $numfoils = scalar(@{$qstnref}) - 1; my $datestamp = localtime; my $numansrs = scalar(@{$answerref}); - my $output = ' + my $output = ''; + if ($qtype eq 'MC') { + $output .= "\n".''; + } + $output .= ' '; if ($res eq 'application/rtf' || $res eq 'text/html') { if ($header ne '') { @@ -1576,6 +1589,7 @@ sub create_ess { if (open(PROB,">$destdir$libfile")) { print PROB $output; close(PROB); + $result = 'ok'; } else { $result = 'failed'; } @@ -1600,18 +1614,21 @@ sub probfile_name { } sub file_error { - my ($r,$uname,$fn,$current_page,$webpath,$res) = @_; + my ($r,$fn,$current_page,$webpath,$res) = @_; $r->print('

'.&mt('The file you uploaded does not appear to be in the correct format.'). '

'.&mt('Extraction of questions is only possible for the following file types:'). - '

  • '.&mt('plain text').'
  • RTF
  • HTML
'. + '
    '. + '
  • '.&mt('plain text').'
  • '. + '
  • '.&mt('RTF').'
  • '. + '
  • '.&mt('HTML').'
'. &mt('The file type identified for the file you uploaded is [_1].',''.$res.'').'

'); - $r->print(&page_footer($env{'form.newdir'},$uname,$fn,$current_page,$webpath,undef,'badfile'). + $r->print(&page_footer($env{'form.newdir'},$fn,$current_page,$webpath,undef,'badfile'). '
'); return; } sub parse_datafile { - my ($r,$uname,$filename,$pathname,$dirpath,$urlpath,$page_name,$subdir,$timestamp) = @_; + my ($r,$filename,$dirpath,$webpath,$page_name,$subdir,$timestamp) = @_; my ($badfile,$res,%allfiles,%codebase); my $mm = new File::MMagic; my ($text,$header,$css,$js); @@ -1626,7 +1643,7 @@ sub parse_datafile { my $html = ''; my $image_uri = $timestamp; if ($page_name eq 'Target') { - $image_uri = $urlpath.'/'.$timestamp; + $image_uri = "$webpath/$timestamp"; } my $image_dir; if ($page_name eq 'Blocks') { @@ -1764,16 +1781,16 @@ sub parse_htmlcontent { } sub build_image_url { - my ($urlpath,$item) = @_; - $item =~ s/(]+src=["']?\s*)(\.?\.?\/?)/$1$urlpath/gsi; - return $item; + my ($webpath,$item) = @_; + $item =~ s/(]+src=["']?\s*)(\.?\.?\/?)/$1$webpath/gsi; + return $item; } sub print_header { my ($uname,$udom,$javascript,$loadentries,$title,$current_page,$pagesref, $namesref) = @_; - my $brcrum = [{'href' => &Apache::loncommon::authorspace(), - 'text' => 'Construction Space'}]; + my $brcrum = [{'href' => &Apache::loncommon::authorspace("/priv/$udom/$uname/"), + 'text' => 'Authoring Space'}]; if ($env{'form.phase'} eq 'three') { if (ref($pagesref) eq 'ARRAY') { for (my $i=0; $i<$current_page; $i++) { @@ -1800,7 +1817,7 @@ sub print_header { {'bread_crumbs' => $brcrum, 'add_entries' => $loadentries}); if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) { - $output .= '

' + $output .= '

' .&mt('Co-Author [_1]',$uname.':'.$udom) .'

'; } @@ -1810,54 +1827,45 @@ sub print_header { # ---------------------------------------------------------------- Main Handler sub handler { my $r=shift; - my $uname; - my $udom; - my $javascript = ''; - my $page_name = ''; - my $current_page = ''; - my $qcount = ''; - my $title = 'Upload testbank questions to Construction Space'; - if ($env{'form.uploaduname'}) { - $env{'form.filename'}='/priv/'.$env{'form.uploaduname'}.'/'. - $env{'form.filename'}; - } - ($uname,$udom)= - &Apache::loncacc::constructaccess($env{'form.filename'}, - $r->dir_config('lonDefDomain')); - unless (($uname) && ($udom)) { - $r->log_reason($uname.':'.$udom.' trying to convert testbank file '. - $env{'form.filename'}.' - not authorized',$r->filename); - return HTTP_NOT_ACCEPTABLE; + my $fn=$env{'form.filename'}; + + if ($env{'form.filename1'}) { + $fn=$env{'form.filename1'}.$env{'form.filename2'}; } + $fn=~s{\+}{}g; - my ($fn,$filename); - if ($env{'form.filename'}) { - $fn=$env{'form.filename'}; - $fn=~s/^https?\:\/\/[^\/]+\///; - $fn=~s/^\///; - $fn=~s{(~|priv/)($LONCAPA::username_re)}{}; - $fn=~s/\/+/\//g; - } else { + unless ($fn) { $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}. ' unspecified filename for upload', $r->filename); return HTTP_NOT_FOUND; } + my ($uname,$udom) = &Apache::lonnet::constructaccess($fn); + if (($uname eq '') || ($udom eq '')) { + $r->log_reason($uname.':'.$udom.' trying to convert testbank file '. + $fn.' - not authorized',$r->filename); + return HTTP_NOT_ACCEPTABLE; + } + + my $javascript = ''; + my $page_name = ''; + my $current_page = ''; + my $qcount = ''; + my $title = 'Upload testbank questions to Authoring Space'; + # ----------------------------------------------------------- Start page output &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; - my ($filename,$pathname) = &File::Basename::fileparse($fn); - my $webpath = '/priv/'.$uname.$pathname; - my $urlpath = '/~'.$uname.$pathname; - my $dirpath = '/home/'.$uname.'/public_html'.$pathname; + my ($filename,$webpath) = &File::Basename::fileparse($fn); + my $dirpath = $r->dir_config('lonDocRoot').$webpath; my ($res,$subdir,$badfile,$textref,$header,$css,$js,%loadentries,@pages,%names); if ($env{'form.phase'} eq 'three') { $current_page = &display_control(); @pages = ('Welcome','Blocks','Format','Target','Confirmation'); - %names = ( + %names = &Apache::lonlocal::texthash( Welcome => 'Testbank Format', Blocks => 'Classification', Format => 'Selection', @@ -1873,8 +1881,8 @@ sub handler { } } ($res,$badfile,$textref,$header,$css,$js) = - &parse_datafile($r,$uname,$filename,$pathname,$dirpath,$urlpath, - $page_name,$subdir,$env{'form.timestamp'}); + &parse_datafile($r,$filename,$dirpath,$webpath,$page_name, + $subdir,$env{'form.timestamp'}); if ($page_name eq 'Welcome') { &jscript_zero($webpath,\$javascript); } elsif ($page_name eq 'Blocks') { @@ -1906,23 +1914,40 @@ sub handler { } $r->print(&print_header($uname,$udom,$javascript,\%loadentries,$title, - $current_page,\@pages,\%names)); + $current_page,\@pages,\%names)); - if ($env{'form.phase'} eq 'three') { - if ($env{'form.action'} eq 'upload_embedded') { - $r->print(&Apache::lonupload::phasethree($r,$fn,$uname,$udom,'testbank')); + if (($env{'form.phase'} eq 'four') || ($env{'form.phase'} eq 'three')) { + if ($env{'form.phase'} eq 'four') { + $r->print(&Apache::lonupload::phasefour($r,$fn,$uname,$udom,'testbank')); + my $current_page = 0; + my $js; + &jscript_zero($webpath,\$js); + $js = ''; + $r->print($js); + &display_zero($r,$fn,$current_page,$webpath); + } elsif ($env{'form.phase'} eq 'three') { + if ($env{'form.action'} eq 'upload_embedded') { + my ($result,$flag) = + &Apache::lonupload::phasethree($r,$fn,$uname,$udom,'testbank'); + $r->print($result); + if ($flag eq 'modify_orightml') { + undef($page_name); + $r->print('
'. + &page_footer('',$fn).'
'); + } + } } if ($badfile) { - &file_error($r,$uname,$fn,$current_page,$webpath,$res); - } else { - &display_zero ($r,$uname,$fn,$current_page,$webpath) if $page_name eq 'Welcome'; - &display_one ($r,$uname,$fn,$current_page,$textref,$header) if $page_name eq 'Blocks'; - &display_two ($r,$uname,$fn,$current_page,$textref,$header,$qcount) if $page_name eq 'Format'; - &display_three ($r,$uname,$fn,$current_page,$textref,$res,$header,$urlpath,$qcount) if $page_name eq 'Target'; - &final_display ($r,$uname,$fn,$current_page,$textref,$res,$header,$css,$js,$webpath,$dirpath,$subdir) if $page_name eq 'Confirmation'; + &file_error($r,$fn,$current_page,$webpath,$res); + } else { + &display_zero ($r,$fn,$current_page,$webpath) if $page_name eq 'Welcome'; + &display_one ($r,$fn,$current_page,$textref,$header) if $page_name eq 'Blocks'; + &display_two ($r,$fn,$current_page,$textref,$header,$qcount) if $page_name eq 'Format'; + &display_three ($r,$fn,$current_page,$textref,$res,$header,$webpath,$qcount) if $page_name eq 'Target'; + &final_display ($r,$fn,$current_page,$textref,$res,$header,$css,$js,$webpath,$dirpath,$subdir) if $page_name eq 'Confirmation'; } } elsif ($env{'form.phase'} eq 'two') { - my ($result,$flag) = &Apache::lonupload::phasetwo($r,$fn,$uname,$udom,'testbank'); + my ($result,$flag) = &Apache::lonupload::phasetwo($r,$fn,'testbank'); $r->print($result); if ($flag eq 'ok') { my $current_page = 0; @@ -1930,13 +1955,13 @@ sub handler { &jscript_zero($webpath,\$js); $js = ''; $r->print($js); - &display_zero($r,$uname,$fn,$current_page,$webpath); + &display_zero($r,$fn,$current_page,$webpath); } elsif ($flag eq 'embedded') { $r->print($js.'
'. - &page_footer('',$uname,$fn).'
'); + &page_footer('',$fn).''); } } else { - &Apache::lonupload::phaseone($r,$fn,$uname,$udom,'testbank'); + &Apache::lonupload::phaseone($r,$fn,'testbank',$uname,$udom); } $r->print(&Apache::loncommon::end_page()); return OK;