--- loncom/interface/londocs.pm 2017/08/27 02:23:02 1.636 +++ loncom/interface/londocs.pm 2017/11/30 14:41:20 1.644 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.636 2017/08/27 02:23:02 raeburn Exp $ +# $Id: londocs.pm,v 1.644 2017/11/30 14:41:20 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -52,6 +52,7 @@ use File::MMagic; use File::Copy; use Apache::lonlocal; use Cwd; +use UUID::Tiny ':std'; use LONCAPA qw(:DEFAULT :match); my $iconpath; @@ -659,7 +660,7 @@ sub group_import { my $marker = $2; my $info = $3; my ($toolid,%toolhash,%toolsettings); - my @extras = ('linktext','explanation','crslabel','crstitle'); + my @extras = ('linktext','explanation','crslabel','crstitle','crsappend'); my @toolinfo = split(/:/,$info); if ($residx) { %toolsettings=&Apache::lonnet::dump('exttool_'.$marker,$coursedom,$coursenum); @@ -670,13 +671,13 @@ sub group_import { $toolid =~ s/\D//g; ($toolhash{'target'},$toolhash{'width'},$toolhash{'height'}, $toolhash{'linktext'},$toolhash{'explanation'}, - $toolhash{'crslabel'},$toolhash{'crstitle'}) = @toolinfo; + $toolhash{'crslabel'},$toolhash{'crstitle'},$toolhash{'crsappend'}) = @toolinfo; foreach my $item (@extras) { $toolhash{$item} = &unescape($toolhash{$item}); } if (ref($ltitoolsref) eq 'HASH') { - my @deleted; if (ref($ltitoolsref->{$toolid}) eq 'HASH') { + my @deleted; $toolhash{'id'} = $toolid; if (($toolhash{'target'} eq 'iframe') || ($toolhash{'target'} eq 'tab') || ($toolhash{'target'} eq 'window')) { @@ -751,6 +752,16 @@ sub group_import { } } } + if ($toolhash{'passback'}) { + my $gradesecret = UUID::Tiny::create_uuid_as_string(UUID_V4); + $toolhash{'gradesecret'} = $gradesecret; + $toolhash{'gradesecretdate'} = time; + } + if ($toolhash{'roster'}) { + my $rostersecret = UUID::Tiny::create_uuid_as_string(UUID_V4); + $toolhash{'rostersecret'} = $rostersecret; + $toolhash{'rostersecretdate'} = time; + } my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$coursedom,$coursenum); if ($putres eq 'ok') { if (@deleted) { @@ -4104,7 +4115,7 @@ END } } if ($url ne '') { - $url.=(($url=~/\?/)?'&':'?').'symb='.&HTML::Entities::encode($shownsymb,'"<>&'); + $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($shownsymb); } } elsif (!$env{'request.role.adv'}) { my $checkencrypt; @@ -4125,7 +4136,7 @@ END my $shownsymb = &Apache::lonenc::encrypted($symb); my $shownurl = &Apache::lonenc::encrypted($url); if (&Apache::lonnet::symbverify($shownsymb,$shownurl)) { - $url = $shownurl.(($shownurl=~/\?/)?'&':'?').'symb='.&HTML::Entities::encode($shownsymb,'"<>&'); + $url = $shownurl.(($shownurl=~/\?/)?'&':'?').'symb='.&escape($shownsymb); if ($env{'request.enc'} ne '') { delete($env{'request.enc'}); } @@ -4588,7 +4599,7 @@ sub untiehash { sub checkonthis { - my ($r,$url,$level,$title)=@_; + my ($r,$url,$level,$title,$checkstale)=@_; $url=&unescape($url); $alreadyseen{$url}=1; $r->rflush(); @@ -4603,10 +4614,22 @@ sub checkonthis { $r->print(''. ($title?$title:$url).' '); if ($url=~/^\/res\//) { + my $updated; + if (($checkstale) && ($url !~ m{^/res/lib/templates/}) && + ($url !~ /\.\d+\.\w+$/)) { + $updated = &Apache::lonnet::remove_stale_resfile($url); + } my $result=&Apache::lonnet::repcopy( &Apache::lonnet::filelocation('',$url)); if ($result eq 'ok') { $r->print(''.&mt('ok').''); + if ($updated) { + $r->print('
'); + for (my $i=0;$i<=$level*5;$i++) { + $r->print(' '); + } + $r->print('- '.&mt('Outdated copy removed')); + } $r->rflush(); &Apache::lonnet::countacc($url); $url=~/\.(\w+)$/; @@ -4640,7 +4663,7 @@ sub checkonthis { &Apache::lonnet::metadata($url,'dependencies'); foreach my $dep (split(/\,/,$dependencies)) { if (($dep=~/^\/res\//) && (!$alreadyseen{$dep})) { - &checkonthis($r,$dep,$level+1); + &checkonthis($r,$dep,$level+1,'',$checkstale); } } } elsif ($result eq 'unavailable') { @@ -4654,6 +4677,9 @@ sub checkonthis { } else { $r->print(''.&mt('access denied').''); } + if (($updated) && ($result ne 'ok')) { + $r->print('
'.&mt('Outdated copy removed')); + } } } } @@ -4706,9 +4732,29 @@ sub list_symbs { $r->print(&endContentScreen()); } +sub contentverifyform { + my ($r) = @_; + my $crstype = &Apache::loncommon::course_type(); + $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Content')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Content')); + $r->print(&startContentScreen('tools')); + $r->print('

'.&mt($crstype.' content verification').'

'); + $r->print('

'. + &mt('Include a check if files copied from elsewhere are up to date (will increase verification time)?'). + ' '. + ''.(' 'x2). + '

'. + ''. + ''. + '

'); + $r->print(&endContentScreen()); + return; +} sub verifycontent { - my ($r) = @_; + my ($r,$checkstale) = @_; my $crstype = &Apache::loncommon::course_type(); $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Content')); $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Content')); @@ -4729,7 +4775,7 @@ sub verifycontent { } } if (($key=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$key})})) { - &checkonthis($r,$hash{$key},0,$hash{'title_'.$1}); + &checkonthis($r,$hash{$key},0,$hash{'title_'.$1},$checkstale); } } &untiehash(); @@ -4737,7 +4783,6 @@ sub verifycontent { $r->print(&endContentScreen()); } - sub devalidateversioncache { my $src=shift; &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'. @@ -5208,7 +5253,17 @@ sub handler { if ($allowed && $env{'form.verify'}) { &init_breadcrumbs('verify','Verify Content','Docs_Verify_Content'); - &verifycontent($r); + if (!$canedit) { + &verifycontent($r); + } elsif (($env{'form.checkstale'} ne '') && ($env{'form.checkstale'} =~ /^\d$/)) { + &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?tools=1&verify=1&checkstale=$env{'form.checkstale'}", + text=>'Results', + faq=>273, + bug=>'Instructor Interface'}); + &verifycontent($r,$env{'form.checkstale'}); + } else { + &contentverifyform($r); + } } elsif ($allowed && $env{'form.listsymbs'}) { &init_breadcrumbs('listsymbs','List Content IDs'); &list_symbs($r); @@ -5546,7 +5601,7 @@ sub handler { } } my $tabidstr = join("','",@tabids); - %ltitools = &Apache::lonnet::get_domain_ltitools($coursedom); + %ltitools = &Apache::lonnet::get_domain_lti($coursedom,'consumer'); my $posslti = keys(%ltitools); my $hostname = $r->hostname(); $script .= &editing_js($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti, @@ -5634,6 +5689,7 @@ sub handler { undef($hadchanges); $uploadphase = &process_file_upload(\$upload_output,$coursenum,$coursedom, \%allfiles,\%codebase,$context,$crstype); + undef($navmap); if ($hadchanges) { &mark_hash_old(); } @@ -6433,8 +6489,10 @@ unless ($container eq 'page') { $r->print('

'.$error.'

'); } if ($hadchanges) { - &mark_hash_old(); - } + unless (&is_hash_old()) { + &mark_hash_old(); + } + } &changewarning($r,''); } @@ -7056,8 +7114,13 @@ sub editing_js { } else { $url = $res; } - $backtourl = &HTML::Entities::encode(&Apache::lonnet::clutter($url),'<>&"').'?symb='. - &HTML::Entities::encode($caller,'<>&"'); + $backtourl = &HTML::Entities::encode(&Apache::lonnet::clutter($url),'<>&"'); + if ($backtourl =~ m{^\Q/uploaded/$coursedom/$coursenum/\Edefault_\d+\.sequence$}) { + $backtourl .= '?navmap=1'; + } else { + $backtourl .= '?symb='. + &HTML::Entities::encode($caller,'<>&"'); + } if ($backtourl =~ m{^\Q/public/$coursedom/$coursenum/syllabus\E}) { if (($ENV{'SERVER_PORT'} == 443) && ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) {