--- loncom/publisher/lonpublisher.pm 2024/06/01 22:41:28 1.295.2.1.2.2 +++ loncom/publisher/lonpublisher.pm 2022/09/09 19:20:55 1.300 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Publication Handler # -# $Id: lonpublisher.pm,v 1.295.2.1.2.2 2024/06/01 22:41:28 raeburn Exp $ +# $Id: lonpublisher.pm,v 1.300 2022/09/09 19:20:55 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -128,13 +128,9 @@ use Apache::lonlocal; use Apache::loncfile; use LONCAPA::lonmetadata; use Apache::lonmsg; -use vars qw(%metadatafields %metadatakeys); +use vars qw(%metadatafields %metadatakeys %addid $readit); use LONCAPA qw(:DEFAULT :match); - -my %addid; -my %nokey; - my $docroot; my $cuname; @@ -1106,7 +1102,7 @@ I ######################################### sub publish { - my ($source,$target,$style,$batch)=@_; + my ($source,$target,$style,$batch,$nokeyref)=@_; my $logfile; my $scrout=''; my $allmeta=''; @@ -1346,7 +1342,7 @@ sub publish { $textonly=~s/[^a-z^ü^ä^ö^ß\s]//g; #dont delete german "Umlaute" foreach ($textonly=~m/[^\s]+/g) { #match all but whitespaces - unless ($nokey{$_}) { + unless ($nokeyref->{$_}) { $keywords{$_}=1; } } @@ -1597,6 +1593,18 @@ END return($scrout,0); } +sub getnokey { + my ($includedir) = @_; + my $nokey={}; + my $fh=Apache::File->new($includedir.'/un_keyword.tab'); + while (<$fh>) { + my $word=$_; + chomp($word); + $nokey->{$word}=1; + } + return $nokey; +} + ######################################### ######################################### @@ -1619,13 +1627,21 @@ Parameters: =item I<$distarget> +=item I<$batch> + +=item I<$usebuffer> + =back Returns: =over 4 -=item integer +=item integer or array + +if $userbuffer arg is true, and if caller wants an array +then the array ($output,$rtncode) will be returned, otherwise +just the $rtncode will be returned. $rtncode is an integer: 0: fail 1: success @@ -1639,26 +1655,54 @@ Returns: ######################################### sub phasetwo { - my ($r,$source,$target,$style,$distarget,$batch)=@_; + my ($r,$source,$target,$style,$distarget,$batch,$usebuffer)=@_; $source=~s/\/+/\//g; $target=~s/\/+/\//g; # # Unless trying to get rid of something, check name validity # + my $output; unless ($env{'form.obsolete'}) { if ($target=~/(\_\_\_|\&\&\&|\:\:\:)/) { - $r->print(''. + $output = ''. &mt('Unsupported character combination [_1] in filename, FAIL.',"'.$1.'"). - ''); - return 0; + ''; + if ($usebuffer) { + if (wantarray) { + return ($output,0); + } else { + return 0; + } + } else { + $r->print($output); + return 0; + } } unless ($target=~/\.(\w+)$/) { - $r->print(''.&mt('No valid extension found in filename, FAIL').''); - return 0; + $output = ''.&mt('No valid extension found in filename, FAIL').''; + if ($usebuffer) { + if (wantarray) { + return ($output,0); + } else { + return 0; + } + } else { + $r->print($output); + return 0; + } } if ($target=~/\.(\d+)\.(\w+)$/) { - $r->print(''.&mt('Filename of resource contains internal version number. Cannot publish such resources, FAIL').''); - return 0; + $output = ''.&mt('Filename of resource contains internal version number. Cannot publish such resources, FAIL').''; + if ($usebuffer) { + if (wantarray) { + return ($output,0); + } else { + return 0; + } + } else { + $r->print($output); + return 0; + } } } @@ -1668,14 +1712,25 @@ sub phasetwo { $distarget=~s/\/+/\//g; my $logfile; unless ($logfile=Apache::File->new('>>'.$source.'.log')) { - $r->print( - ''. - &mt('No write permission to user directory, FAIL').''); - return 0; + $output = ''. + &mt('No write permission to user directory, FAIL').''; + if ($usebuffer) { + if (wantarray) { + return ($output,0); + } else { + return 0; + } + } else { + return 0; + } } if ($source =~ /\.rights$/) { - $r->print('

'.&mt('Warning: It can take up to 1 hour for rights changes to fully propagate.').'

'); + $output = '

'.&mt('Warning: It can take up to 1 hour for rights changes to fully propagate.').'

'; + unless ($usebuffer) { + $r->print($output); + $output = ''; + } } print $logfile @@ -1757,20 +1812,36 @@ sub phasetwo { if ($metadatafields{'copyright'} eq 'custom') { my $file=$metadatafields{'customdistributionfile'}; unless ($file=~/\.rights$/) { - $r->print( - ''.&mt('No valid custom distribution rights file specified, FAIL'). - ''); - return 0; + $output .= ''.&mt('No valid custom distribution rights file specified, FAIL'). + ''; + if ($usebuffer) { + if (wantarray) { + return ($output,0); + } else { + return 0; + } + } else { + $r->print($output); + return 0; + } } } { print $logfile "\nWrite metadata file for ".$source; my $mfh; unless ($mfh=Apache::File->new('>'.$source.'.meta')) { - $r->print( - ''.&mt('Could not write metadata, FAIL'). - ''); - return 0; + $output .= ''.&mt('Could not write metadata, FAIL'). + ''; + if ($usebuffer) { + if (wantarray) { + return ($output,0); + } else { + return 0; + } + } else { + $r->print($output); + return 0; + } } foreach my $field (sort(keys(%metadatafields))) { unless ($field=~/\./) { @@ -1789,7 +1860,12 @@ sub phasetwo { .''; } } - $r->print('

'.&mt('Wrote Metadata').'

'); + + $output .= '

'.&mt('Wrote Metadata').'

'; + unless ($usebuffer) { + $r->print($output); + $output = ''; + } print $logfile "\nWrote metadata"; } @@ -1798,17 +1874,35 @@ sub phasetwo { $metadatafields{'url'} = $distarget; $metadatafields{'version'} = 'current'; - my ($error,$success) = &store_metadata(%metadatafields); - if ($success) { - $r->print('

'.&mt('Synchronized SQL metadata database').'

'); - print $logfile "\nSynchronized SQL metadata database"; - } else { - $r->print($error); - print $logfile "\n".$error; + my $crsauthor; + if ($env{'request.course.id'}) { + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + if ($distarget =~ m{^/res/$cdom/$cnum}) { + $crsauthor = 1; + } + } + unless ($crsauthor) { + my ($error,$success) = &store_metadata(%metadatafields); + if ($success) { + $output .= '

'.&mt('Synchronized SQL metadata database').'

'; + print $logfile "\nSynchronized SQL metadata database"; + } else { + $output .= $error; + print $logfile "\n".$error; + } + unless ($usebuffer) { + $r->print($output); + $output = ''; + } } # --------------------------------------------- Delete author resource messages my $delresult=&Apache::lonmsg::del_url_author_res_msg($target); - $r->print('

'.&mt('Removing error messages:').' '.$delresult.'

'); + $output .= '

'.&mt('Removing error messages:').' '.$delresult.'

'; + unless ($usebuffer) { + $r->print($output); + $output = ''; + } print $logfile "\nRemoving error messages: $delresult"; # ----------------------------------------------------------- Copy old versions @@ -1822,9 +1916,18 @@ sub phasetwo { my $docroot = $Apache::lonnet::perlvar{'lonDocRoot'}; unless ($srcd=~/^\Q$docroot\E\/res/) { print $logfile "\nPANIC: Target dir is ".$srcd; - $r->print( - "".&mt('Invalid target directory, FAIL').""); - return 0; + $output .= + "".&mt('Invalid target directory, FAIL').""; + if ($usebuffer) { + if (wantarray) { + return ($output,0); + } else { + return 0; + } + } else { + $r->print($output); + return 0; + } } opendir(DIR,$srcd); while ($filename=readdir(DIR)) { @@ -1839,18 +1942,35 @@ sub phasetwo { } closedir(DIR); $maxversion++; - $r->print('

'.&mt('Creating old version [_1]',$maxversion).'

'); + $output .= '

'.&mt('Creating old version [_1]',$maxversion).'

'; + unless ($usebuffer) { + $r->print($output); + $output = ''; + } print $logfile "\nCreating old version ".$maxversion."\n"; my $copyfile=$srcd.'/'.$srcf.'.'.$maxversion.'.'.$srct; if (copy($target,$copyfile)) { print $logfile "Copied old target to ".$copyfile."\n"; - $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('Copied old target file'))); + $output .= &Apache::lonhtmlcommon::confirm_success(&mt('Copied old target file')); + unless ($usebuffer) { + $r->print($output); + $output = ''; + } } else { print $logfile "Unable to write ".$copyfile.':'.$!."\n"; - $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('Failed to copy old target').", $!",1)); - return 0; + $output .= &Apache::lonhtmlcommon::confirm_success(&mt('Failed to copy old target').", $!",1); + if ($usebuffer) { + if (wantarray) { + return ($output,0); + } else { + return 0; + } + } else { + $r->print($output); + return 0; + } } # --------------------------------------------------------------- Copy Metadata @@ -1859,19 +1979,34 @@ sub phasetwo { if (copy($target.'.meta',$copyfile)) { print $logfile "Copied old target metadata to ".$copyfile."\n"; - $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('Copied old metadata'))); + $output .= &Apache::lonhtmlcommon::confirm_success(&mt('Copied old metadata')); + unless ($usebuffer) { + $r->print($output); + $output = ''; + } } else { print $logfile "Unable to write metadata ".$copyfile.':'.$!."\n"; if (-e $target.'.meta') { - $r->print(&Apache::lonhtmlcommon::confirm_success( - &mt('Failed to write old metadata copy').", $!",1)); - return 0; + $output .= &Apache::lonhtmlcommon::confirm_success( + &mt('Failed to write old metadata copy').", $!",1); + if ($usebuffer) { + if (wantarray) { + return ($output,0); + } else { + return 0; + } + } else { + $r->print($output); + return 0; + } } } - - } else { - $r->print('

'.&mt('Initial version').'

'); + $output .= '

'.&mt('Initial version').'

'; + unless ($usebuffer) { + $r->print($output); + $output = ''; + } print $logfile "\nInitial version"; } @@ -1887,22 +2022,38 @@ sub phasetwo { if ((-e $path)!=1) { print $logfile "\nCreating directory ".$path; mkdir($path,0777); - $r->print('

' - .&mt('Created directory [_1]' - ,''.$parts[$count].'') - .'

' - ); + $output .= '

' + .&mt('Created directory [_1]' + ,''.$parts[$count].'') + .'

'; + unless ($usebuffer) { + $r->print($output); + $output = ''; + } } } if (copy($source,$copyfile)) { print $logfile "\nCopied original source to ".$copyfile."\n"; - $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('Copied source file'))); + $output .= &Apache::lonhtmlcommon::confirm_success(&mt('Copied source file')); + unless ($usebuffer) { + $r->print($output); + $output = ''; + } } else { print $logfile "\nUnable to write ".$copyfile.':'.$!."\n"; - $r->print(&Apache::lonhtmlcommon::confirm_success( - &mt('Failed to copy source').", $!",1)); - return 0; + $output .= &Apache::lonhtmlcommon::confirm_success( + &mt('Failed to copy source').", $!",1); + if ($usebuffer) { + if (wantarray) { + return ($output,0); + } else { + return 0; + } + } else { + $r->print($output); + return 0; + } } # ---------------------------------------------- Delete local tmp-preview files @@ -1913,18 +2064,37 @@ sub phasetwo { if (copy($source.'.meta',$copyfile)) { print $logfile "\nCopied original metadata to ".$copyfile."\n"; - $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('Copied metadata'))); + $output .= &Apache::lonhtmlcommon::confirm_success(&mt('Copied metadata')); + unless ($usebuffer) { + $r->print($output); + $output = ''; + } } else { print $logfile "\nUnable to write metadata ".$copyfile.':'.$!."\n"; - $r->print(&Apache::lonhtmlcommon::confirm_success( - &mt('Failed to write metadata copy').", $!",1)); - return 0; + $output .= &Apache::lonhtmlcommon::confirm_success( + &mt('Failed to write metadata copy').", $!",1); + if ($usebuffer) { + if (wantarray) { + return ($output,0); + } else { + return 0; + } + } else { + $r->print($output); + return 0; + } + } + unless ($usebuffer) { + $r->rflush; } - $r->rflush; # ------------------------------------------------------------- Trigger updates push(@{$modified_urls},[$target,$source]); - ¬ify_in_cleanup($r); + unless ($registered_cleanup) { + my $handlers = $r->get_handlers('PerlCleanupHandler'); + $r->set_handlers('PerlCleanupHandler' => [\¬ify,@{$handlers}]); + $registered_cleanup=1; + } # ---------------------------------------------------------- Clear local caches my $thisdistarget=$target; @@ -1935,7 +2105,11 @@ sub phasetwo { # ------------------------------------------------------------- Everything done $logfile->close(); - $r->print('

'.&mt('Done').'

'); + $output .= '

'.&mt('Done').'

'; + unless ($usebuffer) { + $r->print($output); + $output = ''; + } # ------------------------------------------------ Provide link to new resource unless ($batch) { @@ -1944,7 +2118,7 @@ sub phasetwo { my $thissrcdir=$thissrc; $thissrcdir=~s/\/[^\/]+$/\//; - $r->print( + $output .= &Apache::lonhtmlcommon::actionbox([ ''. &mt('View Published Version'). @@ -1954,18 +2128,25 @@ sub phasetwo { '', ''. &mt('Back to Source Directory'). - '']) - ); + '']); + unless ($usebuffer) { + $r->print($output); + $output = ''; + } } - return 1; -} -sub notify_in_cleanup { - my ($r) = @_; - unless ($registered_cleanup) { - my $handlers = $r->get_handlers('PerlCleanupHandler'); - $r->set_handlers('PerlCleanupHandler' => [\¬ify,@{$handlers}]); - $registered_cleanup=1; + if ($usebuffer) { + if (wantarray) { + return ($output,1); + } else { + return 1; + } + } else { + if (wantarray) { + return ('',1); + } else { + return 1; + } } } @@ -2010,12 +2191,11 @@ sub notify { ######################################### sub batchpublish { - my ($r,$srcfile,$targetfile)=@_; + my ($r,$srcfile,$targetfile,$nokeyref,$usebuffer)=@_; #publication pollutes %env with form.* values my %oldenv=%env; $srcfile=~s/\/+/\//g; $targetfile=~s/\/+/\//g; - $srcfile=~s/\/+/\//g; my $docroot=$r->dir_config('lonDocRoot'); my $thisdistarget=$targetfile; @@ -2030,31 +2210,46 @@ sub batchpublish { my $thisembstyle=&Apache::loncommon::fileembstyle($thistype); - $r->print('

' + my $output = '

' .&mt('Publishing [_1]',&Apache::loncfile::display($srcfile)) - .'

' - ); + .''; + unless ($usebuffer) { + $r->print($output); + $output = ''; + } # phase one takes # my ($source,$target,$style,$batch)=@_; - my ($outstring,$error)=&publish($srcfile,$targetfile,$thisembstyle,1); - $r->print('

'.$outstring.'

'); + my ($outstring,$error)=&publish($srcfile,$targetfile,$thisembstyle,1,$nokeyref); + + if ($usebuffer) { + $output .= '

'.$outstring.'

'; + } else { + $r->print('

'.$outstring.'

'); + } # phase two takes # my ($source,$target,$style,$distarget,batch)=@_; # $env{'form.allmeta'},$env{'form.title'},$env{'form.author'},... if (!$error) { - $r->print('

'); - &phasetwo($r,$srcfile,$targetfile,$thisembstyle,$thisdistarget,1); - $r->print('

'); + if ($usebuffer) { + my ($result,$error) = &phasetwo($r,$srcfile,$targetfile,$thisembstyle,$thisdistarget,1,$usebuffer); + $output .= '

'.$result.'

'; + } else { + &phasetwo($r,$srcfile,$targetfile,$thisembstyle,$thisdistarget,1); + } } %env=%oldenv; - return ''; + if ($usebuffer) { + return $output; + } else { + return ''; + } } ######################################### sub publishdirectory { - my ($r,$fn,$thisdisfn)=@_; + my ($r,$fn,$thisdisfn,$nokeyref)=@_; $fn=~s/\/+/\//g; $thisdisfn=~s/\/+/\//g; my $thisdisresdir=$thisdisfn; @@ -2069,7 +2264,7 @@ sub publishdirectory { .''.$thisdisresdir.'' ); my %reasons = &Apache::lonlocal::texthash( - mod => 'Authoring Space file postdates published file', + mod => 'Authoring Space file postdates published file', modmeta => 'Authoring Space metadata file postdates published file', unpub => 'Resource is unpublished', ); @@ -2114,9 +2309,6 @@ sub publishdirectory { my %commonaccess; map { $commonaccess{$_} = 1; } &Apache::loncommon::get_env_multiple('form.commonaccess'); unless ($lock) { $lock=&Apache::lonnet::set_lock(&mt('Publishing [_1]',$fn)); } - if ($lock) { - ¬ify_in_cleanup($r); - } # actually publish things opendir(DIR,$fn); my @files=sort(readdir(DIR)); @@ -2125,12 +2317,12 @@ sub publishdirectory { $cuid,$cgid,$crdev,$csize, $catime,$cmtime,$cctime, $cblksize,$cblocks)=stat($fn.'/'.$filename); - + my $extension=''; if ($filename=~/\.(\w+)$/) { $extension=$1; } if ($cmode&$dirptr) { if (($filename!~/^\./) && ($env{'form.pubrec'})) { - &publishdirectory($r,$fn.'/'.$filename,$thisdisfn.'/'.$filename); + &publishdirectory($r,$fn.'/'.$filename,$thisdisfn.'/'.$filename,$nokeyref); } } elsif ((&Apache::loncommon::fileembstyle($extension) ne 'hdn') && ($filename!~/^[\#\.]/) && ($filename!~/\~$/)) { @@ -2156,7 +2348,7 @@ sub publishdirectory { if ( $meta_rmtime<$meta_cmtime ) { if ($env{'form.excludemodmeta'}) { $skipthis='modmeta'; - $publishthis=0; + $publishthis=0; } else { $publishthis=1; } @@ -2197,7 +2389,7 @@ sub publishdirectory { } if ($publishthis) { - &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename); + &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename,$nokeyref); } else { my $reason; if ($skipthis) { @@ -2369,29 +2561,7 @@ sub handler { return HTTP_NOT_FOUND; } -# -------------------------------- File is there and owned, init lookup tables. - - %addid=(); - - { - my $fh=Apache::File->new($r->dir_config('lonTabDir').'/addid.tab'); - while (<$fh>=~/(\w+)\s+(\w+)/) { - $addid{$1}=$2; - } - } - - %nokey=(); - - { - my $fh=Apache::File->new($r->dir_config('lonIncludes').'/un_keyword.tab'); - while (<$fh>) { - my $word=$_; - chomp($word); - $nokey{$word}=1; - } - } - -# ---------------------------------------------------------- Start page output. +# --------------------------------- File is there and owned, start page output &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; @@ -2466,10 +2636,11 @@ END my $thistarget=$fn; $thistarget=~s/^\/priv\//\/res\//; my $thisdistarget=&HTML::Entities::encode($thistarget,'<>&"'); + my $nokeyref = &getnokey($r->dir_config('lonIncludes')); if ($fn=~/\/$/) { # -------------------------------------------------------- This is a directory - &publishdirectory($r,$docroot.$fn,$thisdisfn); + &publishdirectory($r,$docroot.$fn,$thisdisfn,$nokeyref); $r->print( '

'. &Apache::lonhtmlcommon::actionbox([ @@ -2542,7 +2713,7 @@ ENDDIFF } unless ($errorcount) { my ($outstring,$error)= - &publish($docroot.$fn,$docroot.$thistarget,$thisembstyle); + &publish($docroot.$fn,$docroot.$thistarget,$thisembstyle,undef,$nokeyref); $r->print($outstring); } else { $r->print('

'. @@ -2550,7 +2721,9 @@ ENDDIFF '

'); } } else { - &phasetwo($r,$docroot.$fn,$docroot.$thistarget,$thisembstyle,$thisdistarget); + my ($output,$error) = &phasetwo($r,$docroot.$fn,$docroot.$thistarget, + $thisembstyle,$thisdistarget); + $r->print($output); } } $r->print(&Apache::loncommon::end_page()); @@ -2558,6 +2731,24 @@ ENDDIFF return OK; } +BEGIN { + +# ----------------------------------- Read addid.tab + unless ($readit) { + %addid=(); + + { + my $tabdir = $Apache::lonnet::perlvar{'lonTabDir'}; + my $fh=Apache::File->new($tabdir.'/addid.tab'); + while (<$fh>=~/(\w+)\s+(\w+)/) { + $addid{$1}=$2; + } + } + } + $readit=1; +} + + 1; __END__