--- loncom/publisher/lonpublisher.pm 2022/09/09 19:20:55 1.300
+++ loncom/publisher/lonpublisher.pm 2025/01/04 21:23:33 1.307
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Publication Handler
#
-# $Id: lonpublisher.pm,v 1.300 2022/09/09 19:20:55 raeburn Exp $
+# $Id: lonpublisher.pm,v 1.307 2025/01/04 21:23:33 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -329,7 +329,7 @@ string which presents the form field (fo
#########################################
#########################################
sub textfield {
- my ($title,$name,$value,$noline)=@_;
+ my ($title,$name,$value,$noline,$readonly)=@_;
$value=~s/^\s+//gs;
$value=~s/\s+$//gs;
$value=~s/\s+/ /gs;
@@ -341,22 +341,31 @@ sub textfield {
}
sub text_with_browse_field {
- my ($title,$name,$value,$restriction,$noline)=@_;
+ my ($title,$name,$value,$restriction,$noline,$readonly)=@_;
$value=~s/^\s+//gs;
$value=~s/\s+$//gs;
$value=~s/\s+/ /gs;
$title=&mt($title);
$env{'form.'.$name}=$value;
- return "\n".&Apache::lonhtmlcommon::row_title($title)
- .''
- .'
'
+ my $disabled;
+ if ($readonly) {
+ $disabled = ' disabled="disabled"';
+ }
+ my $output =
+ "\n".&Apache::lonhtmlcommon::row_title($title)
+ .'';
+ unless ($readonly) {
+ $output .=
+ '
'
.''
.&mt('Select')
.' '
.''
.&mt('Search')
- .''
- .&Apache::lonhtmlcommon::row_closure($noline);
+ .'';
+ }
+ $output .= &Apache::lonhtmlcommon::row_closure($noline);
+ return $output;
}
sub hiddenfield {
@@ -372,7 +381,7 @@ sub checkbox {
}
sub selectbox {
- my ($title,$name,$value,$functionref,@idlist)=@_;
+ my ($title,$name,$value,$readonly,$functionref,@idlist)=@_;
$title=&mt($title);
$value=(split(/\s*,\s*/,$value))[-1];
if (defined($value)) {
@@ -387,6 +396,9 @@ sub selectbox {
if ($id eq $value) {
$selout.=' selected="selected"';
}
+ if ($readonly) {
+ $selout .= ' disabled="disabled"';
+ }
$selout.='>'.&{$functionref}($id).'';
}
$selout.=''.&Apache::lonhtmlcommon::row_closure();
@@ -416,7 +428,7 @@ sub common_access {
}
my %lt = &Apache::lonlocal::texthash(
'default' => 'System wide - can be used for any courses system wide',
- 'domain' => 'Domain only - use limited to courses in the domai',
+ 'domain' => 'Domain only - use limited to courses in the domain',
'custom' => 'Customized right of use ...',
'public' => 'Public - no authentication or authorization required for use',
'closed' => 'Closed - XML source is closed to everyone',
@@ -1199,6 +1211,20 @@ sub publish {
$content=$outstring;
}
+
+# ----------------------------------------------------- Course Authoring Space.
+ my ($courseauthor,$crsaurights,$readonly);
+ if ($env{'request.course.id'}) {
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my $docroot = $Apache::lonnet::perlvar{'lonDocRoot'};
+ if ($source =~ m{^\Q$docroot/priv/$cdom/$cnum/\E}) {
+ $courseauthor = $cnum.':'.$cdom;
+ $crsaurights = "/res/$cdom/$cnum/default.rights";
+ $readonly = 1;
+ }
+ }
+
# -------------------------------------------- Initial step done, now metadata.
# --------------------------------------- Storage for metadata keys and fields.
@@ -1485,7 +1511,7 @@ END
$defaultlanguage =~ s/,\s*$//g;
$intr_scrout.=&selectbox('Language','language',
- $defaultlanguage,
+ $defaultlanguage,'',
\&Apache::loncommon::languagedescription,
(&Apache::loncommon::languageids),
);
@@ -1502,8 +1528,11 @@ END
if ($style eq 'prv') {
$pubowner_last = 1;
}
+ if ($courseauthor) {
+ $metadatafields{'owner'} = $courseauthor;
+ }
$intr_scrout.=&textfield('Publisher/Owner','owner',
- $metadatafields{'owner'},$pubowner_last);
+ $metadatafields{'owner'},$pubowner_last,$readonly);
# ---------------------------------------------- Retrofix for unused copyright
if ($metadatafields{'copyright'} eq 'free') {
@@ -1516,6 +1545,10 @@ END
# ------------------------------------------------ Dial in reasonable defaults
my $defaultoption=$metadatafields{'copyright'};
unless ($defaultoption) { $defaultoption='default'; }
+ if ($courseauthor) {
+ $defaultoption='custom';
+ $metadatafields{'customdistributionfile'}=$crsaurights;
+ }
my $defaultsourceoption=$metadatafields{'sourceavail'};
unless ($defaultsourceoption) { $defaultsourceoption='closed'; }
unless ($style eq 'prv') {
@@ -1527,12 +1560,12 @@ END
$defaultoption='default';
}
$intr_scrout.=&selectbox('Copyright/Distribution','copyright',
- $defaultoption,
+ $defaultoption,$readonly,
\&Apache::loncommon::copyrightdescription,
(grep !/^(public|priv)$/,(&Apache::loncommon::copyrightids)));
} else {
$intr_scrout.=&selectbox('Copyright/Distribution','copyright',
- $defaultoption,
+ $defaultoption,$readonly,
\&Apache::loncommon::copyrightdescription,
(grep !/^priv$/,(&Apache::loncommon::copyrightids)));
}
@@ -1541,9 +1574,9 @@ END
my $replace=&mt('Copyright/Distribution:');
$intr_scrout =~ s/$replace/$replace.' '.$copyright_help/ge;
- $intr_scrout.=&text_with_browse_field('Custom Distribution File','customdistributionfile',$metadatafields{'customdistributionfile'},'rights');
+ $intr_scrout.=&text_with_browse_field('Custom Distribution File','customdistributionfile',$metadatafields{'customdistributionfile'},'rights','',$readonly);
$intr_scrout.=&selectbox('Source Distribution','sourceavail',
- $defaultsourceoption,
+ $defaultsourceoption,'',
\&Apache::loncommon::source_copyrightdescription,
(&Apache::loncommon::source_copyrightids));
# $intr_scrout.=&text_with_browse_field('Source Custom Distribution File','sourcerights',$metadatafields{'sourcerights'},'rights');
@@ -1792,7 +1825,21 @@ sub phasetwo {
$env{'user.domain'};
$metadatafields{'authorspace'}=$cuname.':'.$cudom;
$metadatafields{'domain'}=$cudom;
-
+
+ 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;
+ my $default_rights = "/res/$cdom/$cnum/default.rights";
+ unless ($distarget eq $default_rights) {
+ $metadatafields{'copyright'} = 'custom';
+ $metadatafields{'customdistributionfile'} = $default_rights;
+ }
+ }
+ }
+
my $allkeywords=$env{'form.addkey'};
if (exists($env{'form.keywords'})) {
if (ref($env{'form.keywords'})) {
@@ -1874,14 +1921,6 @@ sub phasetwo {
$metadatafields{'url'} = $distarget;
$metadatafields{'version'} = 'current';
- 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) {
@@ -2090,11 +2129,7 @@ sub phasetwo {
# ------------------------------------------------------------- Trigger updates
push(@{$modified_urls},[$target,$source]);
- unless ($registered_cleanup) {
- my $handlers = $r->get_handlers('PerlCleanupHandler');
- $r->set_handlers('PerlCleanupHandler' => [\¬ify,@{$handlers}]);
- $registered_cleanup=1;
- }
+ ¬ify_in_cleanup($r);
# ---------------------------------------------------------- Clear local caches
my $thisdistarget=$target;
@@ -2150,39 +2185,51 @@ sub phasetwo {
}
}
+sub notify_in_cleanup {
+ my ($r) = @_;
+ unless ($registered_cleanup) {
+ my $handlers = $r->get_handlers('PerlCleanupHandler');
+ $r->set_handlers('PerlCleanupHandler' => [\¬ify,@{$handlers}]);
+ $registered_cleanup=1;
+ }
+}
+
# =============================================================== Notifications
sub notify {
# --------------------------------------------------- Send update notifications
- foreach my $targetsource (@{$modified_urls}){
- my ($target,$source)=@{$targetsource};
- my $logfile=Apache::File->new('>>'.$source.'.log');
- print $logfile "\nCleanup phase: Notifications\n";
- my @subscribed=&get_subscribed_hosts($target);
- foreach my $subhost (@subscribed) {
- print $logfile "\nNotifying host ".$subhost.':';
- my $reply=&Apache::lonnet::critical('update:'.$target,$subhost);
- print $logfile $reply;
- }
+ if (ref($modified_urls) eq 'ARRAY') {
+ foreach my $targetsource (@{$modified_urls}){
+ my ($target,$source)=@{$targetsource};
+ my $logfile=Apache::File->new('>>'.$source.'.log');
+ print $logfile "\nCleanup phase: Notifications\n";
+ my @subscribed=&get_subscribed_hosts($target);
+ foreach my $subhost (@subscribed) {
+ print $logfile "\nNotifying host ".$subhost.':';
+ my $reply=&Apache::lonnet::critical('update:'.$target,$subhost);
+ print $logfile $reply;
+ }
# ---------------------------------------- Send update notifications, meta only
- my @subscribedmeta=&get_subscribed_hosts("$target.meta");
- foreach my $subhost (@subscribedmeta) {
- print $logfile "\nNotifying host for metadata only ".$subhost.':';
- my $reply=&Apache::lonnet::critical('update:'.$target.'.meta',
- $subhost);
- print $logfile $reply;
- }
+ my @subscribedmeta=&get_subscribed_hosts("$target.meta");
+ foreach my $subhost (@subscribedmeta) {
+ print $logfile "\nNotifying host for metadata only ".$subhost.':';
+ my $reply=&Apache::lonnet::critical('update:'.$target.'.meta',
+ $subhost);
+ print $logfile $reply;
+ }
# --------------------------------------------------- Notify subscribed courses
- my %courses=&coursedependencies($target);
- my $now=time;
- foreach my $course (keys(%courses)) {
- print $logfile "\nNotifying course ".$course.':';
- my ($cdom,$cname)=split(/\_/,$course);
- my $reply=&Apache::lonnet::cput
- ('versionupdate',{$target => $now},$cdom,$cname);
- print $logfile $reply;
- }
- print $logfile "\n============ Done ============\n";
- $logfile->close();
+ my %courses=&coursedependencies($target);
+ my $now=time;
+ foreach my $course (keys(%courses)) {
+ print $logfile "\nNotifying course ".$course.':';
+ my ($cdom,$cname)=split(/\_/,$course);
+ my $reply=&Apache::lonnet::cput
+ ('versionupdate',{$target => $now},$cdom,$cname);
+ print $logfile $reply;
+ }
+ print $logfile "\n============ Done ============\n";
+ $logfile->close();
+ }
+ $modified_urls = [];
}
if ($lock) { &Apache::lonnet::remove_lock($lock); }
return OK;
@@ -2207,6 +2254,18 @@ sub batchpublish {
$srcfile=~/\.(\w+)$/;
my $thistype=$1;
+#
+# If lonpublisher::batchpublish() is called directly from another package
+# instead of via a call to lonpublisher::handler(), need to set the package
+# scalars: $cuname and $cudom, and will unset when done.
+#
+ my $clearvars;
+ if (($cuname eq '') && ($cudom eq '')) {
+ ($cuname,$cudom) = &Apache::lonnet::constructaccess($srcfile);
+ unless (($cuname eq '') && ($cudom eq '')) {
+ $clearvars = 1;
+ }
+ }
my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);
@@ -2221,7 +2280,7 @@ sub batchpublish {
# phase one takes
# my ($source,$target,$style,$batch)=@_;
my ($outstring,$error)=&publish($srcfile,$targetfile,$thisembstyle,1,$nokeyref);
-
+
if ($usebuffer) {
$output .= '
'.$outstring.'
'; } else { @@ -2239,6 +2298,10 @@ sub batchpublish { } } %env=%oldenv; + if ($clearvars) { + undef($cuname); + undef($cudom); + } if ($usebuffer) { return $output; } else { @@ -2249,7 +2312,7 @@ sub batchpublish { ######################################### sub publishdirectory { - my ($r,$fn,$thisdisfn,$nokeyref)=@_; + my ($r,$fn,$thisdisfn,$nokeyref,$crsauthor)=@_; $fn=~s/\/+/\//g; $thisdisfn=~s/\/+/\//g; my $thisdisresdir=$thisdisfn; @@ -2290,10 +2353,12 @@ sub publishdirectory { &checkbox('excludemodmeta','exclude files with modified metadata'). ''. '' ); @@ -2309,6 +2374,9 @@ 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)); @@ -2317,12 +2385,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,$nokeyref); + &publishdirectory($r,$fn.'/'.$filename,$thisdisfn.'/'.$filename,$nokeyref,$crsauthor); } } elsif ((&Apache::loncommon::fileembstyle($extension) ne 'hdn') && ($filename!~/^[\#\.]/) && ($filename!~/\~$/)) { @@ -2565,12 +2633,23 @@ sub handler { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; - + # Breadcrumbs &Apache::lonhtmlcommon::clear_breadcrumbs(); + my $crumbtext = 'Authoring Space'; + my $crumbhref = &Apache::loncommon::authorspace($fn); + my $crsauthor; + if ($env{'request.course.id'}) { + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + if ($crumbhref eq "/priv/$cdom/$cnum/") { + $crumbtext = 'Course Authoring Space'; + $crsauthor = 1; + } + } &Apache::lonhtmlcommon::add_breadcrumb({ - 'text' => 'Authoring Space', - 'href' => &Apache::loncommon::authorspace($fn), + 'text' => $crumbtext, + 'href' => $crumbhref, }); &Apache::lonhtmlcommon::add_breadcrumb({ 'text' => 'Resource Publication', @@ -2640,7 +2719,7 @@ END if ($fn=~/\/$/) { # -------------------------------------------------------- This is a directory - &publishdirectory($r,$docroot.$fn,$thisdisfn,$nokeyref); + &publishdirectory($r,$docroot.$fn,$thisdisfn,$nokeyref,$crsauthor); $r->print( '