--- loncom/publisher/lonpublisher.pm 2005/03/15 16:09:20 1.189 +++ loncom/publisher/lonpublisher.pm 2005/05/30 17:10:44 1.197 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Publication Handler # -# $Id: lonpublisher.pm,v 1.189 2005/03/15 16:09:20 albertel Exp $ +# $Id: lonpublisher.pm,v 1.197 2005/05/30 17:10:44 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -121,7 +121,7 @@ use HTML::LCParser; use Apache::lonxml; use Apache::loncacc; use DBI; -use Apache::lonnet(); +use Apache::lonnet; use Apache::loncommon(); use Apache::lonmysql; use Apache::lonlocal; @@ -326,7 +326,7 @@ sub textfield { $value=~s/\s+$//gs; $value=~s/\s+/ /gs; $title=&mt($title); - $ENV{'form.'.$name}=$value; + $env{'form.'.$name}=$value; return "\n

$title:". "


". ''; @@ -338,7 +338,7 @@ sub text_with_browse_field { $value=~s/\s+$//gs; $value=~s/\s+/ /gs; $title=&mt($title); - $ENV{'form.'.$name}=$value; + $env{'form.'.$name}=$value; return "\n

$title:". "


". ''. @@ -349,18 +349,23 @@ sub text_with_browse_field { sub hiddenfield { my ($name,$value)=@_; - $ENV{'form.'.$name}=$value; + $env{'form.'.$name}=$value; return "\n".''; } +sub checkbox { + my ($name,$text)=@_; + return "\n
".&mt($text); +} + sub selectbox { my ($title,$name,$value,$functionref,@idlist)=@_; $title=&mt($title); $value=(split(/\s*,\s*/,$value))[-1]; if (defined($value)) { - $ENV{'form.'.$name}=$value; + $env{'form.'.$name}=$value; } else { - $ENV{'form.'.$name}=$idlist[0]; + $env{'form.'.$name}=$idlist[0]; } my $selout="\n

$title:". '


'. + '

'.($env{'form.makeobsolete'}?'':'').'

'. &hiddenfield('phase','two'). - &hiddenfield('filename',$ENV{'form.filename'}). + &hiddenfield('filename',$env{'form.filename'}). &hiddenfield('allmeta',&Apache::lonnet::escape($allmeta)). - &hiddenfield('dependencies',join(',',keys %allow)). + &hiddenfield('dependencies',join(',',keys %allow)); + unless ($env{'form.makeobsolete'}) { + $intr_scrout.= &textfield('Title','title',$metadatafields{'title'}). &textfield('Author(s)','author',$metadatafields{'author'}). &textfield('Subject','subject',$metadatafields{'subject'}); - -# --------------------------------------------------- Scan content for keywords + # --------------------------------------------------- Scan content for keywords my $keywords_help = Apache::loncommon::help_open_topic("Publishing_Keywords"); my $KEYWORDS=&mt('Keywords'); @@ -1187,11 +1202,11 @@ END if ($metadatafields{'keywords'}) { if ($metadatafields{'keywords'}=~/\Q$_\E/) { $keywordout.=' checked="on"'; - $ENV{'form.keywords'}.=$_.','; + $env{'form.keywords'}.=$_.','; } } elsif (&Apache::loncommon::keyword($_)) { $keywordout.=' checked="on"'; - $ENV{'form.keywords'}.=$_.','; + $env{'form.keywords'}.=$_.','; } $keywordout.=' />'.$_.''; if ($colcount>10) { @@ -1200,7 +1215,7 @@ END } $colcount++; } - $ENV{'form.keywords'}=~s/\,$//; + $env{'form.keywords'}=~s/\,$//; $keywordout.=''; @@ -1309,9 +1324,33 @@ END } else { $intr_scrout.=&hiddenfield('copyright','private'); } + } else { + $intr_scrout.= + &hiddenfield('title',$metadatafields{'title'}). + &hiddenfield('author',$metadatafields{'author'}). + &hiddenfield('subject',$metadatafields{'subject'}). + &hiddenfield('keywords',$metadatafields{'keywords'}). + &hiddenfield('abstract',$metadatafields{'abstract'}). + &hiddenfield('notes',$metadatafields{'notes'}). + &hiddenfield('mime',$metadatafields{'mime'}). + &hiddenfield('creationdate',$metadatafields{'creationdate'}). + &hiddenfield('lastrevisiondate',time). + &hiddenfield('owner',$metadatafields{'owner'}). + &hiddenfield('lowestgradelevel',$metadatafields{'lowestgradelevel'}). + &hiddenfield('standards',$metadatafields{'standards'}). + &hiddenfield('highestgradelevel',$metadatafields{'highestgradelevel'}). + &hiddenfield('language',$metadatafields{'language'}). + &hiddenfield('copyright',$metadatafields{'copyright'}). + &hiddenfield('sourceavail',$metadatafields{'sourceavail'}). + &hiddenfield('customdistributionfile',$metadatafields{'customdistributionfile'}). + &hiddenfield('obsolete',1). + &text_with_browse_field('Suggested Replacement for Obsolete File', + 'obsoletereplacement', + $metadatafields{'obsoletereplacement'}); + } if (!$batch) { $scrout.=$intr_scrout.'

'; + &mt($env{'form.makeobsolete'}?'Make Obsolete':'Finalize Publication').'" />

'; } return($scrout,0); } @@ -1344,10 +1383,10 @@ Returns: =over 4 -=item Scalar string +=item integer -String contains status (errors and warnings) and information associated with -the server's attempts at publication. +0: fail +1: success =cut @@ -1359,13 +1398,29 @@ sub phasetwo { my ($r,$source,$target,$style,$distarget,$batch)=@_; $source=~s/\/+/\//g; $target=~s/\/+/\//g; - - if ($target=~/\_\_\_/) { - $r->print( - ''.&mt('Unsupported character combination'). - ' "___" '.&mt('in filename, FAIL').''); - return 0; +# +# Unless trying to get rid of something, check name validity +# + unless ($env{'form.obsolete'}) { + if ($target=~/(\_\_\_|\&\&\&|\:\:\:)/) { + $r->print( + ''.&mt('Unsupported character combination'). + ' "'.$1.'" '.&mt('in filename, FAIL').''); + return 0; + } + unless ($target=~/\.(\w+)$/) { + $r->print(''.&mt('No valid extension found in filename, FAIL').''); + return 0; + } + if ($target=~/\.(\d+)\.(\w+)$/) { + $r->print(''.&mt('Cannot publish versioned resource, FAIL').''); + return 0; + } } + +# +# End name check +# $distarget=~s/\/+/\//g; my $logfile; unless ($logfile=Apache::File->new('>>'.$source.'.log')) { @@ -1375,44 +1430,44 @@ sub phasetwo { return 0; } print $logfile - "\n================= Publish ".localtime()." Phase Two ================\n".$ENV{'user.name'}.'@'.$ENV{'user.domain'}."\n"; + "\n================= Publish ".localtime()." Phase Two ================\n".$env{'user.name'}.'@'.$env{'user.domain'}."\n"; %metadatafields=(); %metadatakeys=(); - &metaeval(&Apache::lonnet::unescape($ENV{'form.allmeta'})); + &metaeval(&Apache::lonnet::unescape($env{'form.allmeta'})); - $metadatafields{'title'}=$ENV{'form.title'}; - $metadatafields{'author'}=$ENV{'form.author'}; - $metadatafields{'subject'}=$ENV{'form.subject'}; - $metadatafields{'notes'}=$ENV{'form.notes'}; - $metadatafields{'abstract'}=$ENV{'form.abstract'}; - $metadatafields{'mime'}=$ENV{'form.mime'}; - $metadatafields{'language'}=$ENV{'form.language'}; - $metadatafields{'creationdate'}=$ENV{'form.creationdate'}; - $metadatafields{'lastrevisiondate'}=$ENV{'form.lastrevisiondate'}; - $metadatafields{'owner'}=$ENV{'form.owner'}; - $metadatafields{'copyright'}=$ENV{'form.copyright'}; - $metadatafields{'standards'}=$ENV{'form.standards'}; - $metadatafields{'lowestgradelevel'}=$ENV{'form.lowestgradelevel'}; - $metadatafields{'highestgradelevel'}=$ENV{'form.highestgradelevel'}; + $metadatafields{'title'}=$env{'form.title'}; + $metadatafields{'author'}=$env{'form.author'}; + $metadatafields{'subject'}=$env{'form.subject'}; + $metadatafields{'notes'}=$env{'form.notes'}; + $metadatafields{'abstract'}=$env{'form.abstract'}; + $metadatafields{'mime'}=$env{'form.mime'}; + $metadatafields{'language'}=$env{'form.language'}; + $metadatafields{'creationdate'}=$env{'form.creationdate'}; + $metadatafields{'lastrevisiondate'}=$env{'form.lastrevisiondate'}; + $metadatafields{'owner'}=$env{'form.owner'}; + $metadatafields{'copyright'}=$env{'form.copyright'}; + $metadatafields{'standards'}=$env{'form.standards'}; + $metadatafields{'lowestgradelevel'}=$env{'form.lowestgradelevel'}; + $metadatafields{'highestgradelevel'}=$env{'form.highestgradelevel'}; $metadatafields{'customdistributionfile'}= - $ENV{'form.customdistributionfile'}; - $metadatafields{'sourceavail'}=$ENV{'form.sourceavail'}; - $metadatafields{'obsolete'}=$ENV{'form.obsolete'}; + $env{'form.customdistributionfile'}; + $metadatafields{'sourceavail'}=$env{'form.sourceavail'}; + $metadatafields{'obsolete'}=$env{'form.obsolete'}; $metadatafields{'obsoletereplacement'}= - $ENV{'form.obsoletereplacement'}; - $metadatafields{'dependencies'}=$ENV{'form.dependencies'}; - $metadatafields{'modifyinguser'}=$ENV{'user.name'}.'@'. - $ENV{'user.domain'}; + $env{'form.obsoletereplacement'}; + $metadatafields{'dependencies'}=$env{'form.dependencies'}; + $metadatafields{'modifyinguser'}=$env{'user.name'}.'@'. + $env{'user.domain'}; $metadatafields{'authorspace'}=$cuname.'@'.$cudom; - my $allkeywords=$ENV{'form.addkey'}; - if (exists($ENV{'form.keywords'})) { - if (ref($ENV{'form.keywords'})) { - $allkeywords .= ','.join(',',@{$ENV{'form.keywords'}}); + my $allkeywords=$env{'form.addkey'}; + if (exists($env{'form.keywords'})) { + if (ref($env{'form.keywords'})) { + $allkeywords .= ','.join(',',@{$env{'form.keywords'}}); } else { - $allkeywords .= ','.$ENV{'form.keywords'}; + $allkeywords .= ','.$env{'form.keywords'}; } } $allkeywords=~s/[\"\']//g; @@ -1426,18 +1481,20 @@ sub phasetwo { if ($metadatafields{'copyright'} eq 'custom') { my $file=$metadatafields{'customdistributionfile'}; unless ($file=~/\.rights$/) { - return + $r->print( ''.&mt('No valid custom distribution rights file specified, FAIL'). - ''; + ''); + return 0; } } { print $logfile "\nWrite metadata file for ".$source; my $mfh; unless ($mfh=Apache::File->new('>'.$source.'.meta')) { - return + $r->print( ''.&mt('Could not write metadata, FAIL'). - ''; + ''); + return 0; } foreach (sort keys %metadatafields) { unless ($_=~/\./) { @@ -1488,7 +1545,9 @@ sub phasetwo { my $srcd=$1; unless ($srcd=~/^\/home\/httpd\/html\/res/) { print $logfile "\nPANIC: Target dir is ".$srcd; - return "Invalid target directory, FAIL"; + $r->print( + "Invalid target directory, FAIL"); + return 0; } opendir(DIR,$srcd); while ($filename=readdir(DIR)) { @@ -1513,8 +1572,9 @@ sub phasetwo { $r->print('

'.&mt('Copied old target file').'

'); } else { print $logfile "Unable to write ".$copyfile.':'.$!."\n"; - return "".&mt('Failed to copy old target'). - ", $!, ".&mt('FAIL').""; + $r->print("".&mt('Failed to copy old target'). + ", $!, ".&mt('FAIL').""); + return 0; } # --------------------------------------------------------------- Copy Metadata @@ -1527,9 +1587,10 @@ sub phasetwo { } else { print $logfile "Unable to write metadata ".$copyfile.':'.$!."\n"; if (-e $target.'.meta') { - return + $r->print( "". -&mt('Failed to write old metadata copy').", $!, ".&mt('FAIL').""; +&mt('Failed to write old metadata copy').", $!, ".&mt('FAIL').""); + return 0; } } @@ -1560,8 +1621,9 @@ sub phasetwo { $r->print('

'.&mt('Copied source file').'

'); } else { print $logfile "\nUnable to write ".$copyfile.':'.$!."\n"; - return "". - &mt('Failed to copy source').", $!, ".&mt('FAIL').""; + $r->print("". + &mt('Failed to copy source').", $!, ".&mt('FAIL').""); + return 0; } # --------------------------------------------------------------- Copy Metadata @@ -1573,8 +1635,9 @@ sub phasetwo { $r->print('

'.&mt('Copied metadata').'

'); } else { print $logfile "\nUnable to write metadata ".$copyfile.':'.$!."\n"; - return - "".&mt('Failed to write metadata copy').", $!, ".&mt('FAIL').""; + $r->print( + "".&mt('Failed to write metadata copy').", $!, ".&mt('FAIL').""); + return 0; } $r->rflush; @@ -1606,7 +1669,8 @@ sub phasetwo { &mt('Back to Source Directory').'

'); } $logfile->close(); - return '

'.&mt('Done').'

'; + $r->print('

'.&mt('Done').'

'); + return 1; } # =============================================================== Notifications @@ -1650,8 +1714,8 @@ sub notify { sub batchpublish { my ($r,$srcfile,$targetfile)=@_; - #publication pollutes %ENV with form.* values - my %oldENV=%ENV; + #publication pollutes %env with form.* values + my %oldenv=%env; $srcfile=~s/\/+/\//g; $targetfile=~s/\/+/\//g; my $thisdisfn=$srcfile; @@ -1679,13 +1743,13 @@ sub batchpublish { $r->print('

'.$outstring.'

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

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

'); } - %ENV=%oldENV; + %env=%oldenv; return ''; } @@ -1702,47 +1766,59 @@ sub publishdirectory { &mt('Target').': '.$resdir.'
'); my $dirptr=16384; # Mask indicating a directory in stat.cmode. - - opendir(DIR,$fn); - my @files=sort(readdir(DIR)); - foreach my $filename (@files) { - my ($cdev,$cino,$cmode,$cnlink, - $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); - } - } elsif ((&Apache::loncommon::fileembstyle($extension) ne 'hdn') && - ($filename!~/^[\#\.]/) && ($filename!~/\~$/)) { + unless ($env{'form.phase'} eq 'two') { +# ask user what they want + $r->print('
'. + &hiddenfield('phase','two'). + &hiddenfield('filename',$env{'form.filename'}). + &checkbox('pubrec','include subdirectories'). + &checkbox('forcerepub','force republication of previously published files'). + &checkbox('forceobsolete','make file(s) obsolete'). + &checkbox('forceoverride','force directory level catalog information over existing'). + '
'); + } else { +# actually publish things + opendir(DIR,$fn); + my @files=sort(readdir(DIR)); + foreach my $filename (@files) { + my ($cdev,$cino,$cmode,$cnlink, + $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); + } + } elsif ((&Apache::loncommon::fileembstyle($extension) ne 'hdn') && + ($filename!~/^[\#\.]/) && ($filename!~/\~$/)) { # find out publication status and/or exiting metadata - my $publishthis=0; - if (-e $resdir.'/'.$filename) { - my ($rdev,$rino,$rmode,$rnlink, - $ruid,$rgid,$rrdev,$rsize, - $ratime,$rmtime,$rctime, - $rblksize,$rblocks)=stat($resdir.'/'.$filename); - if (($rmtime<$cmtime) || ($ENV{'form.forcerepub'} eq 'ON')) { + my $publishthis=0; + if (-e $resdir.'/'.$filename) { + my ($rdev,$rino,$rmode,$rnlink, + $ruid,$rgid,$rrdev,$rsize, + $ratime,$rmtime,$rctime, + $rblksize,$rblocks)=stat($resdir.'/'.$filename); + if (($rmtime<$cmtime) || ($env{'form.forcerepub'})) { # previously published, modified now - $publishthis=1; - } - } else { + $publishthis=1; + } + } else { # never published - $publishthis=1; - } - if ($publishthis) { - &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename); - } else { - $r->print('
'.&mt('Skipping').' '.$filename.'
'); + $publishthis=1; + } + if ($publishthis) { + &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename); + } else { + $r->print('
'.&mt('Skipping').' '.$filename.'
'); + } + $r->rflush(); } - $r->rflush(); } + closedir(DIR); } - closedir(DIR); } ######################################### @@ -1860,7 +1936,7 @@ sub handler { @{$modified_urls}=(); # -------------------------------------------------------------- Check filename - my $fn=&Apache::lonnet::unescape($ENV{'form.filename'}); + my $fn=&Apache::lonnet::unescape($env{'form.filename'}); ($cuname,$cudom)= &Apache::loncacc::constructaccess($fn,$r->dir_config('lonDefDomain')); @@ -1879,7 +1955,7 @@ sub handler { unless (($cuname) && ($cudom)) { $r->log_reason($cuname.' at '.$cudom. - ' trying to publish file '.$ENV{'form.filename'}. + ' trying to publish file '.$env{'form.filename'}. ' ('.$fn.') - not authorized', $r->filename); return HTTP_NOT_ACCEPTABLE; @@ -1891,7 +1967,7 @@ sub handler { foreach my $id (@ids) { if ($id eq $home) { $allowed = 1; } } unless ($allowed) { $r->log_reason($cuname.' at '.$cudom. - ' trying to publish file '.$ENV{'form.filename'}. + ' trying to publish file '.$env{'form.filename'}. ' ('.$fn.') - not homeserver ('.$home.')', $r->filename); return HTTP_NOT_ACCEPTABLE; @@ -1905,7 +1981,7 @@ sub handler { if ($1 ne $cuname) { $r->log_reason($cuname.' at '.$cudom. ' trying to publish unowned file '. - $ENV{'form.filename'}.' ('.$fn.')', + $env{'form.filename'}.' ('.$fn.')', $r->filename); return HTTP_NOT_ACCEPTABLE; } else { @@ -1916,12 +1992,12 @@ sub handler { unless (-e $fn) { $r->log_reason($cuname.' at '.$cudom. ' trying to publish non-existing file '. - $ENV{'form.filename'}.' ('.$fn.')', + $env{'form.filename'}.' ('.$fn.')', $r->filename); return HTTP_NOT_FOUND; } - unless ($ENV{'form.phase'} eq 'two') { + unless ($env{'form.phase'} eq 'two') { # -------------------------------- File is there and owned, init lookup tables. @@ -1975,7 +2051,7 @@ sub handler { if ($fn=~/\/$/) { # -------------------------------------------------------- This is a directory &publishdirectory($r,$fn,$thisdisfn); - $r->print('
'.&mt('Done').'
'.&mt('Return to Directory').''); @@ -1995,7 +2071,7 @@ ENDCAPTION $r->print(''.&mt('Target').': '. $thisdistarget.'
'); - if (($cuname ne $ENV{'user.name'})||($cudom ne $ENV{'user.domain'})) { + if (($cuname ne $env{'user.name'})||($cudom ne $env{'user.domain'})) { $r->print('

'.&mt('Co-Author').': '. $cuname.&mt(' at ').$cudom.'

'); } @@ -2010,7 +2086,7 @@ ENDDIFF # ------------------ Publishing from $thisfn to $thistarget with $thisembstyle. - unless ($ENV{'form.phase'} eq 'two') { + unless ($env{'form.phase'} eq 'two') { # ---------------------------------------------------------- Parse for problems my ($warningcount,$errorcount); if ($thisembstyle eq 'ssi') { @@ -2026,8 +2102,8 @@ ENDDIFF ''); } } else { - $r->print('
'. - &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget)); + &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget); + $r->print('
'); } } $r->print('');