--- loncom/interface/loncommon.pm 2012/04/06 01:23:11 1.1066 +++ loncom/interface/loncommon.pm 2012/04/18 20:52:44 1.1072 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.1066 2012/04/06 01:23:11 raeburn Exp $ +# $Id: loncommon.pm,v 1.1072 2012/04/18 20:52:44 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -1374,7 +1374,7 @@ function helpMenu(target) { return; } function writeHelp(caller) { - caller.document.writeln('$start_page $end_page') + caller.document.writeln('$start_page\\n\\n\\n$end_page') caller.document.close() caller.focus() } @@ -3129,12 +3129,12 @@ sub noteswrapper { # ------------------------------------------------------------- Aboutme Wrapper sub aboutmewrapper { - my ($link,$username,$domain,$target)=@_; + my ($link,$username,$domain,$target,$class)=@_; if (!defined($username) && !defined($domain)) { return; } return ''.$link.''; + ($target?' target="'.$target.'"':'').($class?' class="'.$class.'"':'').' title="'.&mt("View this user's personal information page").'">'.$link.''; } # ------------------------------------------------------------ Syllabus Wrapper @@ -4937,7 +4937,8 @@ sub bodytag { if ($public) { undef($role); } else { - $name = &aboutmewrapper($name,$env{'user.name'},$env{'user.domain'}); + $name = &aboutmewrapper($name,$env{'user.name'},$env{'user.domain'}, + undef,'LC_menubuttons_link'); } my $titleinfo = '

'.$title.'

'; @@ -5014,7 +5015,7 @@ sub bodytag { sub dc_courseid_toggle { my ($dc_info) = @_; return ' '. - ''. + ''. &mt('(More ...)').''. '
'.$dc_info.'
'; } @@ -9164,13 +9165,20 @@ sub get_env_multiple { sub ask_for_embedded_content { my ($actionurl,$state,$allfiles,$codebase,$args)=@_; - my (%subdependencies,%dependencies,%mapping,%existing,%newfiles,%pathchanges); - my $num = 0; + my (%subdependencies,%dependencies,%mapping,%existing,%newfiles,%pathchanges, + %currsubfile,%unused); + my $counter = 0; + my $numnew = 0; my $numremref = 0; my $numinvalid = 0; my $numpathchg = 0; my $numexisting = 0; - my ($output,$upload_output,$toplevel,$url,$udom,$uname,$getpropath); + my $numunused = 0; + my ($output,$upload_output,$toplevel,$url,$udom,$uname,$getpropath,$cdom,$cnum, + $fileloc,$filename,$delete_output,$modify_output,$title,$symb,$path); + my $heading = &mt('Upload embedded files'); + my $buttontext = &mt('Upload'); + if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { my $current_path='/'; if ($env{'form.currentpath'}) { @@ -9198,8 +9206,24 @@ sub ask_for_embedded_content { } } elsif ($actionurl eq '/adm/coursedocs') { if (ref($args) eq 'HASH') { - $url = $args->{'docs_url'}; - $toplevel = $url; + $url = $args->{'docs_url'}; + $toplevel = $url; + } + } elsif ($actionurl eq '/adm/dependencies') { + if ($env{'request.course.id'} ne '') { + $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + if (ref($args) eq 'HASH') { + $url = $args->{'docs_url'}; + $title = $args->{'docs_title'}; + $toplevel = "/$url"; + ($path) = + ($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/}); + $fileloc = &Apache::lonnet::filelocation('',$toplevel); + $fileloc =~ s{^/}{}; + ($filename) = ($fileloc =~ m{.+/([^/]+)$}); + $heading = &mt('Status of dependencies in [_1]',"$title ($filename)"); + } } } my $now = time(); @@ -9238,25 +9262,44 @@ sub ask_for_embedded_content { } } } + my $dirptr = 16384; foreach my $path (keys(%subdependencies)) { - my %currsubfile; + $currsubfile{$path} = {}; if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { my ($sublistref,$listerror) = &Apache::lonnet::dirlist($url.$path,$udom,$uname,$getpropath); if (ref($sublistref) eq 'ARRAY') { foreach my $line (@{$sublistref}) { my ($file_name,$rest) = split(/\&/,$line,2); - $currsubfile{$file_name} = 1; + $currsubfile{$path}{$file_name} = 1; } } } elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) { if (opendir(my $dir,$url.'/'.$path)) { my @subdir_list = grep(!/^\./,readdir($dir)); - map {$currsubfile{$_} = 1;} @subdir_list; + map {$currsubfile{$path}{$_} = 1;} @subdir_list; + } + } elsif ($actionurl eq '/adm/dependencies') { + if ($env{'request.course.id'} ne '') { + my ($dir) = ($fileloc =~ m{^(.+/)[^/]+$}); + if ($dir ne '') { + my ($sublistref,$listerror) = + &Apache::lonnet::dirlist($dir.$path,$cdom,$cnum,$getpropath,undef,'/'); + if (ref($sublistref) eq 'ARRAY') { + foreach my $line (@{$sublistref}) { + my ($file_name,$dom,undef,$testdir,undef,undef,undef,undef,$size, + undef,$mtime)=split(/\&/,$line,12); + unless (($testdir&$dirptr) || + ($file_name =~ /^\.\.?$/)) { + $currsubfile{$path}{$file_name} = [$size,$mtime]; + } + } + } + } } } foreach my $file (keys(%{$subdependencies{$path}})) { - if ($currsubfile{$file}) { + if (exists($currsubfile{$path}{$file})) { my $item = $path.'/'.$file; unless ($mapping{$item} eq $item) { $pathchanges{$item} = 1; @@ -9267,6 +9310,17 @@ sub ask_for_embedded_content { $newfiles{$path.'/'.$file} = 1; } } + if ($actionurl eq '/adm/dependencies') { + foreach my $path (keys(%currsubfile)) { + if (ref($currsubfile{$path}) eq 'HASH') { + foreach my $file (keys(%{$currsubfile{$path}})) { + unless ($subdependencies{$path}{$file}) { + $unused{$path.'/'.$file} = 1; + } + } + } + } + } } my %currfile; if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { @@ -9283,9 +9337,27 @@ sub ask_for_embedded_content { my @dir_list = grep(!/^\./,readdir($dir)); map {$currfile{$_} = 1;} @dir_list; } + } elsif ($actionurl eq '/adm/dependencies') { + if ($env{'request.course.id'} ne '') { + my ($dir) = ($fileloc =~ m{^(.+/)[^/]+$}); + if ($dir ne '') { + my ($dirlistref,$listerror) = + &Apache::lonnet::dirlist($dir,$cdom,$cnum,$getpropath,undef,'/'); + if (ref($dirlistref) eq 'ARRAY') { + foreach my $line (@{$dirlistref}) { + my ($file_name,$dom,undef,$testdir,undef,undef,undef,undef, + $size,undef,$mtime)=split(/\&/,$line,12); + unless (($testdir&$dirptr) || + ($file_name =~ /^\.\.?$/)) { + $currfile{$file_name} = [$size,$mtime]; + } + } + } + } + } } foreach my $file (keys(%dependencies)) { - if ($currfile{$file}) { + if (exists($currfile{$file})) { unless ($mapping{$file} eq $file) { $pathchanges{$file} = 1; } @@ -9295,15 +9367,25 @@ sub ask_for_embedded_content { $newfiles{$file} = 1; } } + foreach my $file (keys(%currfile)) { + unless (($file eq $filename) || + ($file eq $filename.'.bak') || + ($dependencies{$file})) { + $unused{$file} = 1; + } + } foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%newfiles)) { + if ($actionurl eq '/adm/dependencies') { + next if ($embed_file =~ m{^\w+://}); + } $upload_output .= &start_data_table_row(). - ''.$embed_file.''; + ' '. + ''.$embed_file.''; unless ($mapping{$embed_file} eq $embed_file) { $upload_output .= '
'.&mt('changed from: [_1]',$mapping{$embed_file}).''; } $upload_output .= ''; - if ($args->{'ignore_remote_references'} - && $embed_file =~ m{^\w+://}) { + if ($args->{'ignore_remote_references'} && $embed_file =~ m{^\w+://}) { $upload_output.=''.&mt("URL points to other server.").''; $numremref++; } elsif ($args->{'error_on_invalid_names'} @@ -9312,24 +9394,84 @@ sub ask_for_embedded_content { $upload_output.=''.&mt('Invalid characters').''; $numinvalid++; } else { - $upload_output .= &embedded_file_element('upload_embedded',$num, + $upload_output .= &embedded_file_element('upload_embedded',$counter, $embed_file,\%mapping, - $allfiles,$codebase); - $num++; + $allfiles,$codebase,'upload'); + $counter ++; + $numnew ++; } $upload_output .= ''.&Apache::loncommon::end_data_table_row()."\n"; } foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%existing)) { - $upload_output .= &start_data_table_row(). - ''.$embed_file.''. - ''.&mt('Already exists').''. - &Apache::loncommon::end_data_table_row()."\n"; + if ($actionurl eq '/adm/dependencies') { + my ($size,$mtime) = &get_dependency_details(\%currfile,\%currsubfile,$embed_file); + $modify_output .= &start_data_table_row(). + ''. + ''. + ' '.$embed_file.''. + ''.$size.''. + ''.$mtime.''. + ''. + ''. + &end_data_table_row()."\n"; + $counter ++; + } else { + $upload_output .= &start_data_table_row(). + ''.$embed_file.''; + ''.&mt('Already exists').''. + &Apache::loncommon::end_data_table_row()."\n"; + } + } + my $delidx = $counter; + foreach my $oldfile (sort {lc($a) cmp lc($b)} keys(%unused)) { + my ($size,$mtime) = &get_dependency_details(\%currfile,\%currsubfile,$oldfile); + $delete_output .= &start_data_table_row(). + ''. + ' '.$oldfile.''. + ''.$size.''. + ''.$mtime.''. + ''. + &embedded_file_element('upload_embedded',$delidx, + $oldfile,\%mapping,$allfiles, + $codebase,'delete').''. + &end_data_table_row()."\n"; + $numunused ++; + $delidx ++; } if ($upload_output) { $upload_output = &start_data_table(). $upload_output. &end_data_table()."\n"; } + if ($modify_output) { + $modify_output = &start_data_table(). + &start_data_table_header_row(). + ''.&mt('File').''. + ''.&mt('Size (KB)').''. + ''.&mt('Modified').''. + ''.&mt('Upload replacement?').''. + &end_data_table_header_row(). + $modify_output. + &end_data_table()."\n"; + } + if ($delete_output) { + $delete_output = &start_data_table(). + &start_data_table_header_row(). + ''.&mt('File').''. + ''.&mt('Size (KB)').''. + ''.&mt('Modified').''. + ''.&mt('Delete?').''. + &end_data_table_header_row(). + $delete_output. + &end_data_table()."\n"; + } my $applies = 0; if ($numremref) { $applies ++; @@ -9340,15 +9482,37 @@ sub ask_for_embedded_content { if ($numexisting) { $applies ++; } - if ($num) { + if ($counter || $numunused) { $output = '
'."\n". - $state. - '

'.&mt('Upload embedded files'). - ':

'.$upload_output.'
'."\n". - ''."\n"; - if ($actionurl eq '') { + $state.'

'.$heading.'

'; + if ($actionurl eq '/adm/dependencies') { + if ($numnew) { + $output .= '

'.&mt('Missing dependencies').'

'. + '

'.&mt('The following files need to be uploaded.').'

'."\n". + $upload_output.'
'."\n"; + } + if ($numexisting) { + $output .= '

'.&mt('Uploaded dependencies (in use)').'

'. + '

'.&mt('Upload a new file to replace the one currently in use.').'

'."\n". + $modify_output.'
'."\n"; + $buttontext = &mt('Save changes'); + } + if ($numunused) { + $output .= '

'.&mt('Unused files').'

'. + '

'.&mt('The following uploaded files are no longer used.').'

'."\n". + $delete_output.'
'."\n"; + $buttontext = &mt('Save changes'); + } + } else { + $output .= $upload_output.'
'."\n"; + } + $output .= ''."\n"; + if ($actionurl eq '/adm/dependencies') { + $output .= ''."\n"; + } elsif ($actionurl eq '') { $output .= ''; } } elsif ($applies) { @@ -9376,13 +9540,13 @@ sub ask_for_embedded_content { $output .= $upload_output.'
'; } my ($pathchange_output,$chgcount); - $chgcount = $num; + $chgcount = $counter; if (keys(%pathchanges) > 0) { foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%pathchanges)) { - if ($num) { + if ($counter) { $output .= &embedded_file_element('pathchange',$chgcount, $embed_file,\%mapping, - $allfiles,$codebase); + $allfiles,$codebase,'change'); } else { $pathchange_output .= &start_data_table_row(). @@ -9391,14 +9555,14 @@ sub ask_for_embedded_content { ''.$mapping{$embed_file}.''. ''.$embed_file. &embedded_file_element('pathchange',$numpathchg,$embed_file, - \%mapping,$allfiles,$codebase). + \%mapping,$allfiles,$codebase,'change'). ''.&end_data_table_row(); } $numpathchg ++; $chgcount ++; } } - if ($num) { + if ($counter) { if ($numpathchg) { $output .= ''."\n"; @@ -9408,9 +9572,10 @@ sub ask_for_embedded_content { $output .= ''."\n"; } elsif ($actionurl eq '/adm/portfolio' || $actionurl eq '/adm/coursegrp_portfolio') { $output .= ''; + } elsif ($actionurl eq '/adm/dependencies') { + $output .= ''; } - $output .= ''."\n". - &mt('(only files for which a location has been provided will be uploaded)').'
'."\n"; + $output .= ''."\n".''."\n"; } elsif ($numpathchg) { my %pathchange = (); $output .= &modify_html_form('pathchange',$actionurl,$state,\%pathchange,$pathchange_output); @@ -9418,15 +9583,15 @@ sub ask_for_embedded_content { $output .= '

'.&mt('or').'

'; } } - return ($output,$num,$numpathchg); + return ($output,$counter,$numpathchg); } sub embedded_file_element { - my ($context,$num,$embed_file,$mapping,$allfiles,$codebase) = @_; + my ($context,$num,$embed_file,$mapping,$allfiles,$codebase,$type) = @_; return unless ((ref($mapping) eq 'HASH') && (ref($allfiles) eq 'HASH') && (ref($codebase) eq 'HASH')); my $output; - if ($context eq 'upload_embedded') { + if (($context eq 'upload_embedded') && ($type ne 'delete')) { $output = ''."\n"; } $output .= ' 0) { + $showmtime = &Apache::lonlocal::locallocaltime($mtime); + } + } + return ($showsize,$showmtime); +} + +sub ask_embedded_js { + return <<"END"; + + +END +} + sub upload_embedded { my ($context,$dirpath,$uname,$udom,$dir_root,$url_root,$group,$disk_quota, $current_disk_usage,$hiddenstate,$actionurl) = @_; @@ -9511,7 +9720,6 @@ sub upload_embedded { $output .= &mt('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2).'
'; next; } - $env{'form.embedded_item_'.$i.'.filename'}=$fname; if ($context eq 'portfolio') { my $result; @@ -9568,13 +9776,15 @@ sub upload_embedded { if (!open($fh,'>'.$dest)) { &Apache::lonnet::logthis('Failed to create '.$dest); $output .= ''. - &mt('An error occurred while trying to upload [_1] for embedded element [_2].',$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}). + &mt('An error occurred while trying to upload [_1] for embedded element [_2].', + $orig_uploaded_filename,$env{'form.embedded_orig_'.$i}). '
'; } else { if (!print $fh $env{'form.embedded_item_'.$i}) { &Apache::lonnet::logthis('Failed to write to '.$dest); $output .= ''. - &mt('An error occurred while writing the file [_1] for embedded element [_2].',$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}). + &mt('An error occurred while writing the file [_1] for embedded element [_2].', + $orig_uploaded_filename,$env{'form.embedded_orig_'.$i}). '
'; } else { $output .= &mt('Uploaded [_1]',''. @@ -9596,15 +9806,17 @@ sub upload_embedded { } $output .= &modify_html_form('upload_embedded',$actionurl,$hiddenstate,\%pathchange); $returnflag = 'ok'; - if (keys(%pathchange) > 0) { + my $numpathchgs = scalar(keys(%pathchange)); + if ($numpathchgs > 0) { if ($context eq 'portfolio') { $output .= '

'.&mt('or').'

'; } elsif ($context eq 'testbank') { - $output .= '

'.&mt('Or [_1]continue[_2] the testbank import without modifying the reference(s).','','').'

'; + $output .= '

'.&mt('Or [_1]continue[_2] the testbank import without modifying the reference(s).', + '','').'

'; $returnflag = 'modify_orightml'; } } - return ($output.$footer,$returnflag); + return ($output.$footer,$returnflag,$numpathchgs); } sub modify_html_form { @@ -9639,7 +9851,7 @@ sub modify_html_form { ''. &end_data_table_row(); - } + } } } else { $modifyform = $pathchgtable; @@ -9650,6 +9862,9 @@ sub modify_html_form { } } if ($modifyform) { + if ($actionurl eq '/adm/dependencies') { + $hiddenstate .= ''; + } return '

'.&mt('Changes in content of HTML file required').'

'."\n". '

'.&mt('Changes need to be made to the reference(s) used for one or more of the dependencies, if your HTML file is to work correctly:').'

    '."\n". '
  1. '.&mt('For consistency between the reference(s) and the location of the corresponding stored file within LON-CAPA.').'
  2. '."\n". @@ -9678,23 +9893,55 @@ sub modify_html_refs { $container = $env{'form.container'}; } elsif ($context eq 'coursedoc') { $container = $env{'form.primaryurl'}; + } elsif ($context eq 'manage_dependencies') { + (undef,undef,$container) = &Apache::lonnet::decode_symb($env{'form.symb'}); + $container = "/$container"; } else { $container = $Apache::lonnet::perlvar{'lonDocRoot'}.$env{'form.filename'}; } my (%allfiles,%codebase,$output,$content); my @changes = &get_env_multiple('form.namechange'); - return unless (@changes > 0); - if (($context eq 'portfolio') || ($context eq 'coursedoc')) { - return unless ($container =~ m{^/uploaded/\Q$udom\E/\Q$uname\E/}); + unless (@changes > 0) { + if (wantarray) { + return ('',0,0); + } else { + return; + } + } + if (($context eq 'portfolio') || ($context eq 'coursedoc') || + ($context eq 'manage_dependencies')) { + unless ($container =~ m{^/uploaded/\Q$udom\E/\Q$uname\E/}) { + if (wantarray) { + return ('',0,0); + } else { + return; + } + } $content = &Apache::lonnet::getfile($container); - return if ($content eq '-1'); + if ($content eq '-1') { + if (wantarray) { + return ('',0,0); + } else { + return; + } + } } else { - return unless ($container =~ /^\Q$dir_root\E/); + unless ($container =~ /^\Q$dir_root\E/) { + if (wantarray) { + return ('',0,0); + } else { + return; + } + } if (open(my $fh,"<$container")) { $content = join('', <$fh>); close($fh); } else { - return; + if (wantarray) { + return ('',0,0); + } else { + return; + } } } my ($count,$codebasecount) = (0,0); @@ -9728,13 +9975,14 @@ sub modify_html_refs { } if ($count || $codebasecount) { my $saveresult; - if ($context eq 'portfolio' || $context eq 'coursedoc') { + if (($context eq 'portfolio') || ($context eq 'coursedoc') || + ($context eq 'manage_dependencies')) { my $url = &Apache::lonnet::store_edited_file($container,$content,$udom,$uname,\$saveresult); if ($url eq $container) { my ($fname) = ($container =~ m{/([^/]+)$}); $output = '

    '.&mt('Updated [quant,_1,reference] in [_2].', $count,''. - $fname.'').'

    '; + $fname.'').'

    '; } else { $output = '

    '. &mt('Error: update failed for: [_1].', @@ -9761,7 +10009,11 @@ sub modify_html_refs { ' to modify references: '.$parse_result); } } - return $output; + if (wantarray) { + return ($output,$count,$codebasecount); + } else { + return $output; + } } sub check_for_existing { @@ -9931,20 +10183,26 @@ sub decompress_form { my ($mimetype,$archiveurl,$action,$noextract,$hiddenelements,$dirlist) = @_; my %lt = &Apache::lonlocal::texthash ( this => 'This file is an archive file.', + camt => 'This file is a Camtasia archive file.', itsc => 'Its contents are as follows:', youm => 'You may wish to extract its contents.', - camt => 'Extraction of contents is recommended for Camtasia zip files.', extr => 'Extract contents', + auto => 'LON-CAPA can process the files automatically, or you can decide how each should be handled.', + proa => 'Process automatically?', yes => 'Yes', no => 'No', + fold => 'Title for folder containing movie', + movi => 'Title for page containing embedded movie', ); - my $output = '

    '.$lt{'this'}; my $fileloc = &Apache::lonnet::filelocation(undef,$archiveurl); - my (%toplevel,@paths); + my ($is_camtasia,$topdir,%toplevel,@paths); my $info = &list_archive_contents($fileloc,\@paths); if (@paths) { foreach my $path (@paths) { $path =~ s{^/}{}; + if ($path =~ m{^([^/]+)/$}) { + $topdir = $1; + } if ($path =~ m{^([^/]+)/}) { $toplevel{$1} = $path; } else { @@ -9952,12 +10210,53 @@ sub decompress_form { } } } - if ($info eq '') { - $output .= ' '.$lt{'youm'}.'

    '."\n"; + if ($mimetype =~ m{^application/(x\-)?(compressed|zip)}) { + my @camtasia = ("$topdir/","$topdir/index.html", + "$topdir/media/", + "$topdir/media/$topdir.mp4", + "$topdir/media/FirstFrame.png", + "$topdir/media/player.swf", + "$topdir/media/swfobject.js", + "$topdir/media/expressInstall.swf"); + my @diffs = &compare_arrays(\@paths,\@camtasia); + if (@diffs == 0) { + $is_camtasia = 1; + } + } + my $output; + if ($is_camtasia) { + $output = <<"ENDCAM"; + +

    $lt{'camt'}

    +ENDCAM } else { - $output .= ' '.$lt{'itsc'}.'

    '."\n". - '
    '.$info.'
    '; + $output = '

    '.$lt{'this'}; + if ($info eq '') { + $output .= ' '.$lt{'youm'}.'

    '."\n"; + } else { + $output .= ' '.$lt{'itsc'}.'

    '."\n". + '
    '.$info.'
    '; + } } + $output .= '
    '."\n"; my $duplicates; my $num = 0; if (ref($dirlist) eq 'ARRAY') { @@ -9993,9 +10292,28 @@ sub decompress_form { } else { $itemcount = 1; } + if ($is_camtasia) { + $output .= $lt{'auto'}.'
    '. + ''.$lt{'proa'}.' 
    '. + '
    '. + &Apache::lonhtmlcommon::start_pick_box(). + &Apache::lonhtmlcommon::row_title($lt{'fold'}). + ''."\n". + &Apache::lonhtmlcommon::row_closure(). + &Apache::lonhtmlcommon::row_title($lt{'movi'}). + ''."\n". + &Apache::lonhtmlcommon::row_closure(1). + &Apache::lonhtmlcommon::end_pick_box(). + '
    '; + } $output .= ''. - ''."\n"; + ''. + "\n"; if ($duplicates ne '') { $output .= '

    '. &mt('Warning: decompression of the archive will overwrite the following items which already exist:').'
    '. @@ -10011,24 +10329,17 @@ sub decompress_form { &end_data_table(). '

    '; } - if ($mimetype =~ m{^application/(x\-)?(compressed|zip)}) { - $output .= '

    '.$lt{'camt'}.'

    '; - } - $output .= <<"START"; -
    - - -START + $output .= ''."\n"; if (ref($hiddenelements) eq 'HASH') { foreach my $hidden (sort(keys(%{$hiddenelements}))) { $output .= ''."\n"; } } $output .= <<"END"; +
    $noextract -
    END return $output; } @@ -10199,8 +10510,11 @@ sub process_decompression { } } if (@contents > 0) { + my $wantform; + unless ($env{'form.autoextract_camtasia'}) { + $wantform = 1; + } my (%children,%parent,%dirorder,%titles); - my $wantform = 1; my ($count,$datatable) = &get_extracted($docudom,$docuname, $currdir,\%is_dir, \%children,\%parent, @@ -10213,6 +10527,50 @@ sub process_decompression { $output .= &archive_javascript($startcount,$count, \%titles,\%children); } + if ($env{'form.autoextract_camtasia'}) { + my %displayed; + my $total = 1; + $env{'form.archive_directory'} = []; + foreach my $i (sort { $a <=> $b } keys(%dirorder)) { + my $path = join('/',map { $titles{$_}; } @{$dirorder{$i}}); + $path =~ s{/$}{}; + my $item; + if ($path ne '') { + $item = "$path/$titles{$i}"; + } else { + $item = $titles{$i}; + } + $env{'form.archive_content_'.$i} = "$dir_root/$destination/$item"; + if ($item eq $contents[0]) { + push(@{$env{'form.archive_directory'}},$i); + $env{'form.archive_'.$i} = 'display'; + $env{'form.archive_title_'.$i} = $env{'form.camtasia_foldername'}; + $displayed{'folder'} = $i; + } elsif ($item eq "$contents[0]/index.html") { + $env{'form.archive_'.$i} = 'display'; + $env{'form.archive_title_'.$i} = $env{'form.camtasia_moviename'}; + $displayed{'web'} = $i; + } else { + if ($item eq "$contents[0]/media") { + push(@{$env{'form.archive_directory'}},$i); + } + $env{'form.archive_'.$i} = 'dependency'; + } + $total ++; + } + for (my $i=1; $i<$total; $i++) { + next if ($i == $displayed{'web'}); + next if ($i == $displayed{'folder'}); + $env{'form.archive_dependent_on_'.$i} = $displayed{'web'}; + } + $env{'form.phase'} = 'decompress_cleanup'; + $env{'form.archivedelete'} = 1; + $env{'form.archive_count'} = $total-1; + $output .= + &process_extracted_files('coursedocs',$docudom, + $docuname,$destination, + $dir_root,$hiddenelem); + } } else { $warning = &mt('No new items extracted from archive file.'); } @@ -10611,12 +10969,12 @@ END } sub process_extracted_files { - my ($context,$docudom,$docuname,$url,$destination,$dir_root,$hiddenelem) = @_; + my ($context,$docudom,$docuname,$destination,$dir_root,$hiddenelem) = @_; my $numitems = $env{'form.archive_count'}; return unless ($numitems); my @ids=&Apache::lonnet::current_machine_ids(); my ($prefix,$pathtocheck,$dir,$ishome,$error,$warning,%toplevelitems,%is_dir, - %folders,%containers,%mapinner); + %folders,%containers,%mapinner,%prompttofetch); my $docuhome = &Apache::lonnet::homeserver($docuname,$docudom); if (grep(/^\Q$docuhome\E$/,@ids)) { $prefix = &LONCAPA::propath($docudom,$docuname); @@ -10652,7 +11010,7 @@ sub process_extracted_files { } } } - my ($output,%children,%parent,%titles,%dirorder); + my ($output,%children,%parent,%titles,%dirorder,$result); if (keys(%toplevelitems) > 0) { my @contents = sort(keys(%toplevelitems)); (my $count,undef) = &get_extracted($docudom,$docuname,$currdir,\%is_dir,\%children, @@ -10713,6 +11071,9 @@ sub process_extracted_files { $docuname.'/'.$folders{$outer}. '.'.$containers{$outer},1); $newseqid{$i} = $newidx; + unless ($errtext) { + $result .= '
  3. '.&mt('Folder: [_1] added to course',$docstitle).'
  4. '."\n"; + } } } else { if ($context eq 'coursedocs') { @@ -10729,6 +11090,11 @@ sub process_extracted_files { if (-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx") { system("mv $prefix$path $prefix$dir/$docstype/$mapinner{$outer}/$newidx/$title"); $newdest{$i} = "$prefix$dir/$docstype/$mapinner{$outer}/$newidx"; + unless ($ishome) { + my $fetch = "$newdest{$i}/$title"; + $fetch =~ s/^\Q$prefix$dir\E//; + $prompttofetch{$fetch} = 1; + } } $LONCAPA::map::resources[$newidx]= $docstitle.':'.$url.':false:normal:res'; @@ -10737,6 +11103,11 @@ sub process_extracted_files { &LONCAPA::map::storemap('/uploaded/'.$docudom.'/'. $docuname.'/'.$folders{$outer}. '.'.$containers{$outer},1); + unless ($errtext) { + if (-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx/$title") { + $result .= '
  5. '.&mt('File: [_1] added to course',$docstitle).'
  6. '."\n"; + } + } } } } elsif ($env{'form.archive_'.$i} eq 'dependency') { @@ -10744,7 +11115,7 @@ sub process_extracted_files { $referrer{$i} = $env{'form.archive_dependent_on_'.$i}; if ($env{'form.archive_'.$referrer{$i}} eq 'display') { if (ref($dirorder{$i}) eq 'ARRAY') { - my ($itemidx,$fullpath); + my ($itemidx,$fullpath,$relpath); for (my $j=0; $j<@{$dirorder{$i}}; $j++) { if (ref($dirorder{$referrer{$i}}) eq 'ARRAY') { my $container = $dirorder{$referrer{$i}}->[-1]; @@ -10763,6 +11134,7 @@ sub process_extracted_files { if (grep(/^\Q$dirorder{$i}->[$j]\E$/,@archdirs)) { unless (defined($newseqid{$dirorder{$i}->[$j]})) { $fullpath .= '/'.$titles{$dirorder{$i}->[$j]}; + $relpath .= '/'.$titles{$dirorder{$i}->[$j]}; if (!-e $fullpath) { mkdir($fullpath,0755); } @@ -10781,6 +11153,7 @@ sub process_extracted_files { } elsif (grep(/^\Q$dirorder{$i}->[$j]\E$/,@archdirs)) { unless (defined($newseqid{$dirorder{$i}->[$j]})) { $fullpath .= '/'.$titles{$dirorder{$i}->[$j]}; + $relpath .= '/'.$titles{$dirorder{$i}->[$j]}; if (!-e $fullpath) { mkdir($fullpath,0755); } @@ -10791,7 +11164,23 @@ sub process_extracted_files { } } if ($fullpath ne '') { - system("mv $prefix$path $fullpath/$title"); + if (-e "$prefix$path") { + system("mv $prefix$path $fullpath/$title"); + } + if (-e "$fullpath/$title") { + my $showpath; + if ($relpath ne '') { + $showpath = "$relpath/$title"; + } else { + $showpath = "/$title"; + } + $result .= '
  7. '.&mt('[_1] included as a dependency',$showpath).'
  8. '."\n"; + } + unless ($ishome) { + my $fetch = "$fullpath/$title"; + $fetch =~ s/^\Q$prefix$dir\E//; + $prompttofetch{$fetch} = 1; + } } } } @@ -10819,6 +11208,26 @@ sub process_extracted_files { &cleanup_empty_dirs($prefix."$pathtocheck/$dir"); } } + if ($result ne '') { + $output .= ''; + } + unless ($ishome) { + my $replicationfail; + foreach my $item (keys(%prompttofetch)) { + my $fetchresult= &Apache::lonnet::reply('fetchuserfile:'.$item,$docuhome); + unless ($fetchresult eq 'ok') { + $replicationfail .= '
  9. '.$item.'
  10. '."\n"; + } + } + if ($replicationfail) { + $output .= '

    '. + &mt('Course home server failed to retrieve:').'

    '; + } + } } else { $warning = &mt('No items found in archive.'); } @@ -10859,6 +11268,65 @@ sub cleanup_empty_dirs { =pod +=item &get_folder_hierarchy() + +Provides hierarchy of names of folders/sub-folders containing the current +item, + +Inputs: 3 + - $navmap - navmaps object + + - $map - url for map (either the trigger itself, or map containing + the resource, which is the trigger). + + - $showitem - 1 => show title for map itself; 0 => do not show. + +Outputs: 1 @pathitems - array of folder/subfolder names. + +=cut + +sub get_folder_hierarchy { + my ($navmap,$map,$showitem) = @_; + my @pathitems; + if (ref($navmap)) { + my $mapres = $navmap->getResourceByUrl($map); + if (ref($mapres)) { + my $pcslist = $mapres->map_hierarchy(); + if ($pcslist ne '') { + my @pcs = split(/,/,$pcslist); + foreach my $pc (@pcs) { + if ($pc == 1) { + push(@pathitems,&mt('Main Course Documents')); + } else { + my $res = $navmap->getByMapPc($pc); + if (ref($res)) { + my $title = $res->compTitle(); + $title =~ s/\W+/_/g; + if ($title ne '') { + push(@pathitems,$title); + } + } + } + } + } + if ($showitem) { + if ($mapres->{ID} eq '0.0') { + push(@pathitems,&mt('Main Course Documents')); + } else { + my $maptitle = $mapres->compTitle(); + $maptitle =~ s/\W+/_/g; + if ($maptitle ne '') { + push(@pathitems,$maptitle); + } + } + } + } + } + return @pathitems; +} + +=pod + =item * &get_turnedin_filepath() Determines path in a user's portfolio file for storage of files uploaded @@ -13163,7 +13631,9 @@ sub get_symb { my $symb=($env{'form.symb'} ne '' ? $env{'form.symb'} : (&Apache::lonnet::symbread($url))); if ($symb eq '') { if (!$silent) { - $request->print("Unable to handle ambiguous references:$url:."); + if (ref($request)) { + $request->print("Unable to handle ambiguous references:$url:."); + } return (); } }