--- loncom/publisher/testbankimport.pm 2008/09/22 01:53:33 1.17 +++ loncom/publisher/testbankimport.pm 2011/11/14 00:20:31 1.34 @@ -1,5 +1,5 @@ # Handler for parsing text upload problem descriptions into .problems -# $Id: testbankimport.pm,v 1.17 2008/09/22 01:53:33 raeburn Exp $ +# $Id: testbankimport.pm,v 1.34 2011/11/14 00:20:31 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -81,14 +81,15 @@ function createWin() { newWindow = window.open("","CreateDir","HEIGHT=400,WIDTH=750,scrollbars=yes") newWindow.document.open() newWindow.document.write('$start_page') - newWindow.document.write("[Author Header]\\n") + newWindow.document.write("[Author Header]\\n") newWindow.document.write("

$lt{'loca'}: $webpath

$lt{'newd'}

\\n") newWindow.document.write("
\\n") newWindow.document.write("$lt{'ente'}.

") - newWindow.document.write("") - newWindow.document.write("") - newWindow.document.write("") - newWindow.document.write("$webpath") + newWindow.document.write("") + newWindow.document.write("") + newWindow.document.write("") + newWindow.document.write("") + newWindow.document.write("$webpath") newWindow.document.write("
") newWindow.document.write('$end_page') newWindow.document.close() @@ -484,7 +485,7 @@ 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','','')); @@ -508,21 +509,21 @@ sub display_zero {
  • '.&mt('Review the identified questions, choose which to convert, and (optionally) override the default filename to be used for each problem file.').'
  • '.&mt('Complete the import of questions.').'
  • '. - &topic_bar(1,&mt('Optional: create a sub-directory in which the testbank questions will be saved')). + &Apache::lonhtmlcommon::topic_bar(1,&mt('Optional: create a sub-directory in which the testbank questions will be saved')). &mt('By default, LON-CAPA problems generated from the testbank file will be stored in the current directory.').' '.&mt('To store them in a new sub-directory:'). - ' '. - &page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath).' + ' '. + &page_footer($env{'form.newdir'},$fn,$page,$webpath).'
    '); } # ---------------------------------------------------------------- Display One sub display_one { - my ($r,$uname,$fn,$page,$textref,$header) = @_; + my ($r,$fn,$page,$textref,$header) = @_; my %topics; $topics{2} = &mt('Select the format of the question number - e.g., 1, 1., 1), (1 or (1) - ').'   '."\n". - '  '."\n". + '  '."\n". ' '. - &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'}; @@ -714,14 +715,14 @@ 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); } } } $r->print('

    '.&mt('Review and selection of problems to convert').'

    '."\n". '
    '."\n". &mt('Based on your previous responses your data have been split into a total of [quant,_1,question].',$numitems). - &topic_bar(5,&mt('Choose which problems to convert and names to use for individual problem files'))); + &Apache::lonhtmlcommon::topic_bar(5,&mt('Choose which problems to convert and names to use for individual problem files'))); if ($showheader) { $r->print($showheader.'
    '); } @@ -763,12 +764,12 @@ 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(). ''.$qnum.'.'."\n". - ''."\n". + ''."\n". ''.$qtype[$i].''."\n". ''. ''.$showqn.'

    '."\n"); @@ -807,7 +808,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"); @@ -829,7 +830,7 @@ sub display_three { } $r->print(&Apache::loncommon::start_data_table_row(). ''.$qnum.''."\n". - ''."\n". + ''."\n". ''.$qtype[$i].''."\n". ''."\n". ''.$items->[$j].''."\n". @@ -858,13 +859,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 = ''; @@ -1032,7 +1033,7 @@ sub final_display { for (my $i=0; $i<$numitems; $i++) { $r->print(''."\n"); } - $r->print(&topic_bar(6,&mt('Result of conversion of testbank questions to LON-CAPA problems'))); + $r->print(&Apache::lonhtmlcommon::topic_bar(6,&mt('Result of conversion of testbank questions to LON-CAPA problems'))); my $destdir = $dirpath; if ($destdir ne '' && $subdir ne '') { $subdir .= '/'; @@ -1041,7 +1042,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; @@ -1129,11 +1130,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; } @@ -1158,7 +1159,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();'; @@ -1183,11 +1184,11 @@ sub page_footer { } my $output = ' - - '; + + '; if ($page ne '') { $output .= ' @@ -1199,7 +1200,7 @@ sub page_footer { $output .= ' '; } $output .= ' @@ -1327,9 +1328,12 @@ sub create_mcq { my $qstn = ${$qstnref}[0]; my $numfoils = scalar(@{$qstnref}) - 1; my $datestamp = localtime; - my $timestamp = time; 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 '') { @@ -1599,18 +1603,18 @@ 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('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) = @_; + my ($r,$filename,$dirpath,$webpath,$page_name,$subdir,$timestamp) = @_; my ($badfile,$res,%allfiles,%codebase); my $mm = new File::MMagic; my ($text,$header,$css,$js); @@ -1623,16 +1627,18 @@ sub parse_datafile { close(TESTBANK); } elsif ($res eq 'application/rtf') { my $html = ''; -# my $image_uri = '..'.$pathname; - my $image_uri = $pathname; + my $image_uri = $timestamp; if ($page_name eq 'Target') { - $image_uri = $urlpath; + $image_uri = "$webpath/$timestamp"; } - $image_uri =~ s/\/$//; my $image_dir; if ($page_name eq 'Blocks') { $image_dir = $dirpath; $image_dir =~ s/\/$//; + $image_dir .= '/'.$timestamp; + if (!-e $image_dir) { + mkdir($image_dir,0755); + } } else { $image_dir = $r->dir_config('lonDaemons').'/tmp/'. $env{'user.name'}.'_'.$env{'user.domain'}. @@ -1651,10 +1657,10 @@ sub parse_datafile { $parser->parse(); utf8::decode($html); ($text,$header,$css,$js) = - &parse_htmlcontent($res,$subdir,$html); + &parse_htmlcontent($res,$subdir,$html,undef,$page_name); } elsif ($res eq 'text/html') { ($text,$header,$css,$js) = - &parse_htmlcontent($res,$subdir,undef,$dirpath.$filename); + &parse_htmlcontent($res,$subdir,undef,$dirpath.$filename,$page_name); } else { $badfile = 1; } @@ -1664,7 +1670,7 @@ sub parse_datafile { } sub parse_htmlcontent { - my ($res,$subdir,$html,$fullpath) = @_; + my ($res,$subdir,$html,$fullpath,$page_name) = @_; my ($p,$fh); if ($res eq 'application/rtf') { $p = HTML::TokeParser->new( \$html ); @@ -1702,7 +1708,10 @@ sub parse_htmlcontent { my $contents = $token->[4]; if ($subdir ne '') { if (($token->[1] eq 'img') && ($token->[2]->{'src'} ne '')) { - $contents =~ s/(src=\s*["']?)/$1..\//i; + if (($res eq 'text/html') || + ($res eq 'application/rtf') && ($page_name ne 'Target')) { + $contents =~ s/(src=\s*["']?)/$1..\//i; + } } } if (($line eq '') && ($current_tag eq 'font')) { @@ -1758,92 +1767,108 @@ 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) = @_; + my ($uname,$udom,$javascript,$loadentries,$title,$current_page,$pagesref, + $namesref) = @_; + my $brcrum = [{'href' => &Apache::loncommon::authorspace("/priv/$udom/$uname/"), + 'text' => 'Construction Space'}]; + if ($env{'form.phase'} eq 'three') { + if (ref($pagesref) eq 'ARRAY') { + for (my $i=0; $i<$current_page; $i++) { + my $goback = 1 + $i - $current_page; + if (ref($namesref) eq 'HASH') { + if ($namesref->{$pagesref->[$i]} ne '') { + if (ref($brcrum) eq 'ARRAY') { + my $text = $namesref->{$pagesref->[$i]}; + my $href; + if ($goback == -1) { + $href = 'javascript:backPage();'; + } else { + $href = 'javascript:history.go('.$goback.')'; + } + push(@{$brcrum}, {'href' => $href, + 'text' => $text}); + } + } + } + } + } + } my $output = &Apache::loncommon::start_page($title,$javascript, - {'add_entries' => $loadentries}); + {'bread_crumbs' => $brcrum, + 'add_entries' => $loadentries}); if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) { - $output .= '

    '.&mt('Co-Author').': '.$uname. - &mt(' at ').$udom.'

    '; + $output .= '

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

    '; } return $output; } -sub topic_bar { - my ($imgnum,$title) = @_; - my $output = ' -
    - '.&mt('Step [_1]',$imgnum).
-              '  '.$title.' -
    -'; - return $output; -} - # ---------------------------------------------------------------- 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/^http\:\/\/[^\/]+\///; - $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::loncacc::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 Construction 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 ($res,$subdir,$badfile,$textref,$header,$css,$js,%loadentries); + 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(); - my @pages = ('Welcome','Blocks','Format','Target','Confirmation'); + @pages = ('Welcome','Blocks','Format','Target','Confirmation'); + %names = ( + Welcome => 'Testbank Format', + Blocks => 'Classification', + Format => 'Selection', + Target => 'Result' + ); $page_name = $pages[$current_page]; + if ($env{'form.timestamp'} eq '') { + $env{'form.timestamp'} = time; + } if ($env{'form.newdir'} ne '') { if ($env{'form.newdir'} =~ /^\Q$dirpath\E(.+)$/) { $subdir = $1; } } ($res,$badfile,$textref,$header,$css,$js) = - &parse_datafile($r,$uname,$filename,$pathname,$dirpath,$urlpath, - $page_name,$subdir); + &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') { @@ -1874,23 +1899,41 @@ sub handler { } } - $r->print(&print_header($uname,$udom,$javascript,\%loadentries,$title)); + $r->print(&print_header($uname,$udom,$javascript,\%loadentries,$title, + $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; @@ -1898,13 +1941,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'); } $r->print(&Apache::loncommon::end_page()); return OK;
      - +