--- loncom/publisher/lonpublisher.pm 2003/03/17 16:58:09 1.119 +++ loncom/publisher/lonpublisher.pm 2003/09/25 20:01:15 1.136 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Publication Handler # -# $Id: lonpublisher.pm,v 1.119 2003/03/17 16:58:09 www Exp $ +# $Id: lonpublisher.pm,v 1.136 2003/09/25 20:01:15 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -82,6 +82,26 @@ invocation by F: ErrorDocument 500 /adm/errorhandler +=head1 OVERVIEW + +Authors can only write-access the C space. They can +copy resources into the resource area through the publication step, +and move them back through a recover step. Authors do not have direct +write-access to their resource space. + +During the publication step, several events will be +triggered. Metadata is gathered, where a wizard manages default +entries on a hierarchical per-directory base: The wizard imports the +metadata (including access privileges and royalty information) from +the most recent published resource in the current directory, and if +that is not available, from the next directory above, etc. The Network +keeps all previous versions of a resource and makes them available by +an explicit version number, which is inserted between the file name +and extension, for example C, while the most recent +version does not carry a version number (C). Servers +subscribing to a changed resource are notified that a new version is +available. + =head1 DESCRIPTION B takes the proper steps to add resources to the LON-CAPA @@ -122,6 +142,7 @@ use DBI; use Apache::lonnet(); use Apache::loncommon(); use Apache::lonmysql; +use Apache::lonlocal; use vars qw(%metadatafields %metadatakeys); my %addid; @@ -190,7 +211,7 @@ sub metaeval { } if ($metadatafields{$unikey}) { my $newentry=$parser->get_text('/'.$entry); - unless (($metadatafields{$unikey}=~/$newentry/) || + unless (($metadatafields{$unikey}=~/\Q$newentry\E/) || ($newentry eq '')) { $metadatafields{$unikey}.=', '.$newentry; } @@ -242,7 +263,7 @@ sub metaread { my ($logfile,$fn)=@_; unless (-e $fn) { print($logfile 'No file '.$fn."\n"); - return '
No file: '.$fn.''; + return '
No file: '.$fn.''; } print($logfile 'Processing '.$fn."\n"); my $metastring; @@ -251,7 +272,7 @@ sub metaread { $metastring=join('',<$metafh>); } &metaeval($metastring); - return '
Processed file: '.$fn.''; + return '
Processed file: '.$fn.''; } ######################################### @@ -304,7 +325,10 @@ string which presents the form field (fo ######################################### sub textfield { my ($title,$name,$value)=@_; - return "\n

$title:
". + $title=&mt($title); + my $uctitle=uc($title); + return "\n

$uctitle:". + "


". ''; } @@ -315,9 +339,11 @@ sub hiddenfield { sub selectbox { my ($title,$name,$value,$functionref,@idlist)=@_; + $title=&mt($title); my $uctitle=uc($title); + $value=(split(/\s*,\s*/,$value))[-1]; my $selout="\n

$uctitle:". - "
".''; foreach (@idlist) { $selout.='

Metadata Information ' . + $scrout.='

'.&mt('Metadata Information').' ' . Apache::loncommon::help_open_topic("Metadata_Description") . '

'; } @@ -907,11 +939,14 @@ sub publish { $metadatafields{'author'}=~s/\s+/ /g; $metadatafields{'author'}=~s/\s+$//; $metadatafields{'owner'}=$cuname.'@'.$cudom; + $metadatafields{'modifyinguser'}=$ENV{'user.name'}.'@'. + $ENV{'user.domain'}; + $metadatafields{'authorspace'}=$cuname.'@'.$cudom; # ------------------------------------------------ Check out directory hierachy my $thisdisfn=$source; - $thisdisfn=~s/^\/home\/$cuname\///; + $thisdisfn=~s/^\/home\/\Q$cuname\E\///; my @urlparts=split(/\//,$thisdisfn); $#urlparts--; @@ -947,11 +982,12 @@ sub publish { # -------------------------------------------------- Parse content for metadata if (($style eq 'ssi') || ($style eq 'prv')) { - my $oldenv=$ENV{'request.uri'}; - - $ENV{'request.uri'}=$target; - $allmeta=Apache::lonxml::xmlparse(undef,'meta',$content); - $ENV{'request.uri'}=$oldenv; + my $dir=$source; + $dir=~s-/[^/]*$--; + my $file=$source; + $file=(split('/',$file))[-1]; + $source=&Apache::lonnet::hreflocation($dir,$file); + $allmeta=&Apache::lonnet::ssi_body($source,('grade_target' => 'meta')); &metaeval($allmeta); } @@ -969,7 +1005,8 @@ sub publish { } } if ($chparms) { - $scrout.='

New parameters or stored values: '.$chparms; + $scrout.='

'.&mt('New parameters or stored values'). + ': '.$chparms.'

'; } $chparms=''; @@ -983,8 +1020,8 @@ sub publish { } } if ($chparms) { - $scrout.='

Obsolete parameters or stored values: '. - $chparms; + $scrout.='

'.&mt('Obsolete parameters or stored values').': '. + $chparms.'

'; } # ------------------------------------------------------- Now have all metadata @@ -1042,24 +1079,26 @@ function uncheckAll(field) { field[i].checked = false ; } -

Keywords: $keywords_help - - +

KEYWORDS: + $keywords_help + + +


END - $keywordout.=''; + $keywordout.='
'; my $colcount=0; foreach (sort keys %keywords) { - $keywordout.=''; if ($colcount>10) { $keywordout.="\n"; $colcount=0; @@ -1076,15 +1115,22 @@ END $scrout.=&textfield('Notes','notes',$metadatafields{'notes'}); $scrout.= - '

Abstract:
'; + "\n

ABSTRACT:". + "


". + '

'; $source=~/\.(\w+)$/; $scrout.=&hiddenfield('mime',$1); + my $defaultlanguage=$metadatafields{'language'}; + $defaultlanguage =~ s/\s*notset\s*//g; + $defaultlanguage =~ s/^,\s*//g; + $defaultlanguage =~ s/,\s*$//g; + $scrout.=&selectbox('Language','language', - $metadatafields{'language'}, + $defaultlanguage, \&Apache::loncommon::languagedescription, (&Apache::loncommon::languageids), ); @@ -1102,18 +1148,21 @@ END $metadatafields{'owner'}); # -------------------------------------------------- Correct copyright for rat. + my $defaultoption=$metadatafields{'copyright'}; + unless ($defaultoption) { $defaultoption='default'; } unless ($style eq 'prv') { if ($style eq 'rat') { if ($metadatafields{'copyright'} eq 'public') { delete $metadatafields{'copyright'}; + $defaultoption='default'; } $scrout.=&selectbox('Copyright/Distribution','copyright', - $metadatafields{'copyright'}, + $defaultoption, \&Apache::loncommon::copyrightdescription, (grep !/^public$/,(&Apache::loncommon::copyrightids))); } else { $scrout.=&selectbox('Copyright/Distribution','copyright', - $metadatafields{'copyright'}, + $defaultoption, \&Apache::loncommon::copyrightdescription, (&Apache::loncommon::copyrightids)); } @@ -1124,10 +1173,22 @@ END $scrout.=&textfield('Custom Distribution File','customdistributionfile', $metadatafields{'customdistributionfile'}). $copyright_help; + my $uctitle=uc(&mt('Obsolete')); + $scrout.= + "\n

$uctitle:". + '

',0); + return ($scrout.'

',0); # ============================================================================= # BATCH MODE # @@ -1140,7 +1201,7 @@ END $ENV{'form.keywords'}=''; foreach (keys %keywords) { if ($metadatafields{'keywords'}) { - if ($metadatafields{'keywords'}=~/$_/) { + if ($metadatafields{'keywords'}=~/\Q$_\E/) { $ENV{'form.keywords'}.=$_.','; } } elsif (&Apache::loncommon::keyword($_)) { @@ -1205,18 +1266,20 @@ sub phasetwo { if ($target=~/\_\_\_/) { $r->print( - 'Unsupported character combination "___" in filename, FAIL'); + ''.&mt('Unsupported character combination'). + ' "___" '.&mt('in filename, FAIL').''); return 0; } $distarget=~s/\/+/\//g; my $logfile; unless ($logfile=Apache::File->new('>>'.$source.'.log')) { $r->print( - 'No write permission to user directory, FAIL'); + ''. + &mt('No write permission to user directory, FAIL').''); return 0; } print $logfile - "\n================= Publish ".localtime()." Phase Two ================\n"; + "\n================= Publish ".localtime()." Phase Two ================\n".$ENV{'user.name'}.'@'.$ENV{'user.domain'}."\n"; %metadatafields=(); %metadatakeys=(); @@ -1255,7 +1318,8 @@ sub phasetwo { my $mfh; unless ($mfh=Apache::File->new('>'.$source.'.meta')) { return - 'Could not write metadata, FAIL'; + ''.&mt('Could not write metadata, FAIL'). + ''; } foreach (sort keys %metadatafields) { unless ($_=~/\./) { @@ -1274,7 +1338,7 @@ sub phasetwo { .''; } } - $r->print('

Wrote Metadata'); + $r->print('

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

'); print $logfile "\nWrote metadata"; } @@ -1285,14 +1349,15 @@ sub phasetwo { unless ($metadatafields{'copyright'} eq 'priv') { my ($error,$success) = &store_metadata(\%metadatafields); if ($success) { - $r->print('

Synchronized SQL metadata database'); + $r->print('

Synchronized SQL metadata database

'); print $logfile "\nSynchronized SQL metadata database"; } else { $r->print($error); print $logfile "\n".$error; } } else { - $r->print('

Private Publication - did not synchronize database'); + $r->print('

'. + &mt('Private Publication - did not synchronize database').'

'); print $logfile "\nPrivate: Did not synchronize data into ". "SQL metadata database"; } @@ -1322,17 +1387,18 @@ sub phasetwo { } closedir(DIR); $maxversion++; - $r->print('

Creating old version '.$maxversion); - print $logfile "\nCreating old version ".$maxversion; + $r->print('

Creating old version '.$maxversion.'

'); + 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('

Copied old target file'); + $r->print('

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

'); } else { print $logfile "Unable to write ".$copyfile.':'.$!."\n"; - return "Failed to copy old target, $!, FAIL"; + return "".&mt('Failed to copy old target'). + ", $!, ".&mt('FAIL').""; } # --------------------------------------------------------------- Copy Metadata @@ -1341,18 +1407,19 @@ sub phasetwo { if (copy($target.'.meta',$copyfile)) { print $logfile "Copied old target metadata to ".$copyfile."\n"; - $r->print('

Copied old metadata') + $r->print('

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

') } else { print $logfile "Unable to write metadata ".$copyfile.':'.$!."\n"; if (-e $target.'.meta') { return - "Failed to write old metadata copy, $!, FAIL"; + "". +&mt('Failed to write old metadata copy').", $!, ".&mt('FAIL').""; } } } else { - $r->print('

Initial version'); + $r->print('

Initial version

'); print $logfile "\nInitial version"; } @@ -1367,17 +1434,18 @@ sub phasetwo { $path.="/$parts[$count]"; if ((-e $path)!=1) { print $logfile "\nCreating directory ".$path; - $r->print('

Created directory '.$parts[$count]); + $r->print('

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

'); mkdir($path,0777); } } if (copy($source,$copyfile)) { print $logfile "\nCopied original source to ".$copyfile."\n"; - $r->print('

Copied source file'); + $r->print('

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

'); } else { print $logfile "\nUnable to write ".$copyfile.':'.$!."\n"; - return "Failed to copy source, $!, FAIL"; + return "". + &mt('Failed to copy source').", $!, ".&mt('FAIL').""; } # --------------------------------------------------------------- Copy Metadata @@ -1386,21 +1454,21 @@ sub phasetwo { if (copy($source.'.meta',$copyfile)) { print $logfile "\nCopied original metadata to ".$copyfile."\n"; - $r->print('

Copied metadata'); + $r->print('

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

'); } else { print $logfile "\nUnable to write metadata ".$copyfile.':'.$!."\n"; return - "Failed to write metadata copy, $!, FAIL"; + "".&mt('Failed to write metadata copy').", $!, ".&mt('FAIL').""; } $r->rflush; # --------------------------------------------------- Send update notifications my @subscribed=&get_subscribed_hosts($target); foreach my $subhost (@subscribed) { - $r->print('

Notifying host '.$subhost.':');$r->rflush; + $r->print('

'.&mt('Notifying host').' '.$subhost.':');$r->rflush; print $logfile "\nNotifying host ".$subhost.':'; my $reply=&Apache::lonnet::critical('update:'.$target,$subhost); - $r->print($reply.'
');$r->rflush; + $r->print($reply.'


');$r->rflush; print $logfile $reply; } @@ -1408,11 +1476,12 @@ sub phasetwo { my @subscribedmeta=&get_subscribed_hosts("$target.meta"); foreach my $subhost (@subscribedmeta) { - $r->print('

Notifying host for metadata only '.$subhost.':');$r->rflush; + $r->print('

'. +&mt('Notifying host for metadata only').' '.$subhost.':');$r->rflush; print $logfile "\nNotifying host for metadata only ".$subhost.':'; my $reply=&Apache::lonnet::critical('update:'.$target.'.meta', $subhost); - $r->print($reply.'
');$r->rflush; + $r->print($reply.'


');$r->rflush; print $logfile $reply; } @@ -1420,18 +1489,18 @@ sub phasetwo { my %courses=&coursedependencies($target); my $now=time; foreach (keys %courses) { - $r->print('

Notifying course '.$_.':');$r->rflush; + $r->print('

'.&mt('Notifying course').' '.$_.':');$r->rflush; print $logfile "\nNotifying host ".$_.':'; my ($cdom,$cname)=split(/\_/,$_); my $reply=&Apache::lonnet::cput ('versionupdate',{$target => $now},$cdom,$cname); - $r->print($reply.'
');$r->rflush; + $r->print($reply.'


');$r->rflush; print $logfile $reply; } # ------------------------------------------------ Provide link to new resource unless ($batch) { my $thisdistarget=$target; - $thisdistarget=~s/^$docroot//; + $thisdistarget=~s/^\Q$docroot\E//; my $thissrc=$source; $thissrc=~s/^\/home\/(\w+)\/public_html/\/priv\/$1/; @@ -1441,11 +1510,11 @@ sub phasetwo { $r->print( - '
'. + '
'. 'View Published Version'. - '

Back to Source'. + '

Back to Source

'. '

Back to Source Directory'); + '">Back to Source Directory

'); } } @@ -1453,6 +1522,8 @@ sub phasetwo { sub batchpublish { my ($r,$srcfile,$targetfile)=@_; + #publication pollutes %ENV with form.* values + my %oldENV=%ENV; $srcfile=~s/\/+/\//g; $targetfile=~s/\/+/\//g; my $thisdisfn=$srcfile; @@ -1461,7 +1532,7 @@ sub batchpublish { my $docroot=$r->dir_config('lonDocRoot'); my $thisdistarget=$targetfile; - $thisdistarget=~s/^$docroot//; + $thisdistarget=~s/^\Q$docroot\E//; undef %metadatafields; @@ -1488,6 +1559,7 @@ sub batchpublish { &phasetwo($r,$srcfile,$targetfile,$thisembstyle,$thisdistarget,1); $r->print('

'); } + %ENV=%oldENV; return ''; } @@ -1528,7 +1600,7 @@ sub publishdirectory { $ruid,$rgid,$rrdev,$rsize, $ratime,$rmtime,$rctime, $rblksize,$rblocks)=stat($resdir.'/'.$filename); - if ($rmtime<$cmtime) { + if (($rmtime<$cmtime) || ($ENV{'form.forcerepub'})) { # previously published, modified now $publishthis=1; } @@ -1590,7 +1662,7 @@ sub handler { my $r=shift; if ($r->header_only) { - $r->content_type('text/html'); + &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK; } @@ -1683,7 +1755,7 @@ unless ($ENV{'form.phase'} eq 'two') { # ---------------------------------------------------------- Start page output. - $r->content_type('text/html'); + &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; $r->print('LON-CAPA Publishing'); @@ -1698,35 +1770,45 @@ unless ($ENV{'form.phase'} eq 'two') { $thistarget=~s/\/public\_html//; my $thisdistarget=$thistarget; - $thisdistarget=~s/^$docroot//; + $thisdistarget=~s/^\Q$docroot\E//; my $thisdisfn=$thisfn; - $thisdisfn=~s/^\/home\/$cuname\/public_html\///; + $thisdisfn=~s/^\/home\/\Q$cuname\E\/public_html\///; if ($fn=~/\/$/) { # -------------------------------------------------------- This is a directory &publishdirectory($r,$fn,$thisdisfn); + $r->print('
'.&mt('Done').'
'.&mt('Return to Directory').''); + } else { # ---------------------- Evaluate individual file, and then output information. $thisfn=~/\.(\w+)$/; my $thistype=$1; my $thisembstyle=&Apache::loncommon::fileembstyle($thistype); + $r->print('

'.&mt('Publishing').' '. + &Apache::loncommon::filedescription($thistype).' '); - $r->print('

Publishing '. - &Apache::loncommon::filedescription($thistype).' '. - ''.$thisdisfn. - '

Target: '.$thisdistarget.'

'); + $r->print(< +$thisdisfn +ENDCAPTION + $r->print( + '

'.&mt('Target').': '.$thisdistarget.'
'); if (($cuname ne $ENV{'user.name'}) || ($cudom ne $ENV{'user.domain'})) { - $r->print('

Co-Author: '.$cuname.' at '.$cudom. + $r->print('

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

'); } if (&Apache::loncommon::fileembstyle($thistype) eq 'ssi') { - $r->print('
Diffs with Current Version

'); + $r->print(< + +ENDDIFF + $r->print(&mt('Diffs with Current Version').'
'); } # ------------------ Publishing from $thisfn to $thistarget with $thisembstyle. @@ -1751,5 +1833,7 @@ __END__ =back +=back + =cut

'; + $keywordout.=' />'.$_.'