--- loncom/publisher/lonpublisher.pm 2003/11/04 16:15:56 1.143 +++ loncom/publisher/lonpublisher.pm 2004/06/18 16:52:19 1.174 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Publication Handler # -# $Id: lonpublisher.pm,v 1.143 2003/11/04 16:15:56 www Exp $ +# $Id: lonpublisher.pm,v 1.174 2004/06/18 16:52:19 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -25,24 +25,6 @@ # # http://www.lon-capa.org/ # -# -# (TeX Content Handler -# -# 05/29/00,05/30,10/11 Gerd Kortemeyer) -# -# 11/28,11/29,11/30,12/01,12/02,12/04,12/23 Gerd Kortemeyer -# 03/23 Guy Albertelli -# 03/24,03/29,04/03 Gerd Kortemeyer -# 05/03,05/05,05/07 Gerd Kortemeyer -# 06/23,08/07,08/11,8/13,8/17,8/18,8/24,9/26,10/16 Gerd Kortemeyer -# 12/04,12/05 Guy Albertelli -# 12/05 Gerd Kortemeyer -# 12/05 Guy Albertelli -# 12/06,12/07 Gerd Kortemeyer -# 12/25 Gerd Kortemeyer -# YEAR=2002 -# 1/17 Gerd Kortemeyer -# ### ############################################################################### @@ -143,6 +125,9 @@ use Apache::lonnet(); use Apache::loncommon(); use Apache::lonmysql; use Apache::lonlocal; +use Apache::loncfile; +use LONCAPA::lonmetadata; +use Apache::lonmsg; use vars qw(%metadatafields %metadatakeys); my %addid; @@ -180,6 +165,10 @@ nothing ######################################### ######################################### +# +# Modifies global %metadatafields %metadatakeys +# + sub metaeval { my ($metastring,$prefix)=@_; @@ -210,11 +199,15 @@ sub metaeval { } } my $newentry=$parser->get_text('/'.$entry); - if ($entry eq 'customdistributionfile') { + if (($entry eq 'customdistributionfile') || + ($entry eq 'sourcerights')) { $newentry=~s/^\s*//; if ($newentry !~m|^/res|) { $newentry=$prefix.$newentry; } } - unless ($metadatafields{$unikey}=~/\w/) { +# actually store + if ( $entry eq 'rule' && exists($metadatafields{$unikey})) { + $metadatafields{$unikey}.=','.$newentry; + } else { $metadatafields{$unikey}=$newentry; } } @@ -262,7 +255,8 @@ sub metaread { my ($logfile,$fn,$prefix)=@_; unless (-e $fn) { print($logfile 'No file '.$fn."\n"); - return '
No file: '.$fn.''; + return '
'.&mt('No file').': '. + &Apache::loncfile::display($fn).''; } print($logfile 'Processing '.$fn."\n"); my $metastring; @@ -271,7 +265,8 @@ sub metaread { $metastring=join('',<$metafh>); } &metaeval($metastring,$prefix); - return '
Processed file: '.$fn.''; + return '
'.&mt('Processed file').': '. + &Apache::loncfile::display($fn).''; } ######################################### @@ -328,23 +323,28 @@ sub textfield { $value=~s/\s+$//gs; $value=~s/\s+/ /gs; $title=&mt($title); - my $uctitle=uc($title); - return "\n

$uctitle:". + $ENV{'form.'.$name}=$value; + return "\n

$title:". "


". ''; } sub hiddenfield { my ($name,$value)=@_; + $ENV{'form.'.$name}=$value; return "\n".''; } 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:". + if (defined($value)) { + $ENV{'form.'.$name}=$value; + } else { + $ENV{'form.'.$name}=$idlist[0]; + } + my $selout="\n

$title:". '


'. - &hiddenfield('phase','two'). - &hiddenfield('filename',$ENV{'form.filename'}). - &hiddenfield('allmeta',&Apache::lonnet::escape($allmeta)). - &hiddenfield('dependencies',join(',',keys %allow)). - &textfield('Title','title',$metadatafields{'title'}). - &textfield('Author(s)','author',$metadatafields{'author'}). - &textfield('Subject','subject',$metadatafields{'subject'}); +# interactive mode html goes into $intr_scrout +# batch mode throws away this HTML +# additionally all of the field functions have a by product of setting +# $ENV{'from.'..} so that it can be used by the phase two handler in +# batch mode + + my $intr_scrout.= + '
'. + '

'. + &hiddenfield('phase','two'). + &hiddenfield('filename',$ENV{'form.filename'}). + &hiddenfield('allmeta',&Apache::lonnet::escape($allmeta)). + &hiddenfield('dependencies',join(',',keys %allow)). + &textfield('Title','title',$metadatafields{'title'}). + &textfield('Author(s)','author',$metadatafields{'author'}). + &textfield('Subject','subject',$metadatafields{'subject'}); # --------------------------------------------------- Scan content for keywords - my $keywords_help = Apache::loncommon::help_open_topic("Publishing_Keywords"); - my $keywordout=<<"END"; + my $keywords_help = Apache::loncommon::help_open_topic("Publishing_Keywords"); + my $KEYWORDS=&mt('Keywords'); + my $CheckAll=&mt('check all'); + my $UncheckAll=&mt('uncheck all'); + my $keywordout=<<"END"; -

KEYWORDS: +

$KEYWORDS: $keywords_help - - + +


END - $keywordout.=''; - my $colcount=0; + $keywordout.='
'; + my $colcount=0; - foreach (sort keys %keywords) { - $keywordout.='\n"; - $colcount=0; - } - $colcount++; + } elsif (&Apache::loncommon::keyword($_)) { + $keywordout.=' checked="on"'; + $ENV{'form.keywords'}.=$_.','; } + $keywordout.=' />'.$_.''; + if ($colcount>10) { + $keywordout.="\n"; + $colcount=0; + } + $colcount++; + } + $ENV{'form.keywords'}=~s/\,$//; - $keywordout.='
'; - if ($colcount>10) { - $keywordout.="
'; + $keywordout.=''; - $scrout.=$keywordout; + $intr_scrout.=$keywordout; - $scrout.=&textfield('Additional Keywords','addkey',''); + $intr_scrout.=&textfield('Additional Keywords','addkey',''); - $scrout.=&textfield('Notes','notes',$metadatafields{'notes'}); + $intr_scrout.=&textfield('Notes','notes',$metadatafields{'notes'}); - $scrout.= - "\n

ABSTRACT:". - "


". - '

'; + $intr_scrout.= + "\n

".&mt('Abstract').":". + "


". + '

'; - $source=~/\.(\w+)$/; + $source=~/\.(\w+)$/; - $scrout.=&hiddenfield('mime',$1); - my $defaultlanguage=$metadatafields{'language'}; - $defaultlanguage =~ s/\s*notset\s*//g; - $defaultlanguage =~ s/^,\s*//g; - $defaultlanguage =~ s/,\s*$//g; + $intr_scrout.= + "\n

". + &mt('Lowest Grade Level').':'. + "


". + &select_level_form($metadatafields{'lowestgradelevel'},'lowestgradelevel'). + "\n

". + &mt('Highest Grade Level').':'. + "


". + &select_level_form($metadatafields{'highestgradelevel'},'highestgradelevel'). + &textfield('Standards','standards',$metadatafields{'standards'}); - $scrout.=&selectbox('Language','language', - $defaultlanguage, - \&Apache::loncommon::languagedescription, - (&Apache::loncommon::languageids), - ); - unless ($metadatafields{'creationdate'}) { - $metadatafields{'creationdate'}=time; - } - $scrout.=&hiddenfield('creationdate', - &Apache::loncommon::unsqltime($metadatafields{'creationdate'})); - $scrout.=&hiddenfield('lastrevisiondate',time); + + $intr_scrout.=&hiddenfield('mime',$1); + + my $defaultlanguage=$metadatafields{'language'}; + $defaultlanguage =~ s/\s*notset\s*//g; + $defaultlanguage =~ s/^,\s*//g; + $defaultlanguage =~ s/,\s*$//g; + + $intr_scrout.=&selectbox('Language','language', + $defaultlanguage, + \&Apache::loncommon::languagedescription, + (&Apache::loncommon::languageids), + ); + + unless ($metadatafields{'creationdate'}) { + $metadatafields{'creationdate'}=time; + } + $intr_scrout.=&hiddenfield('creationdate', + &Apache::lonmysql::unsqltime($metadatafields{'creationdate'})); + + $intr_scrout.=&hiddenfield('lastrevisiondate',time); - $scrout.=&textfield('Publisher/Owner','owner', - $metadatafields{'owner'}); + $intr_scrout.=&textfield('Publisher/Owner','owner', + $metadatafields{'owner'}); +# ---------------------------------------------- Retrofix for unused copyright + if ($metadatafields{'copyright'} eq 'free') { + $metadatafields{'copyright'}='default'; + $metadatafields{'sourceavail'}='open'; + } +# ------------------------------------------------ Dial in reasonable defaults + my $defaultoption=$metadatafields{'copyright'}; + unless ($defaultoption) { $defaultoption='default'; } + my $defaultsourceoption=$metadatafields{'sourceavail'}; + unless ($defaultsourceoption) { $defaultsourceoption='closed'; } + unless ($style eq 'prv') { # -------------------------------------------------- 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', - $defaultoption, - \&Apache::loncommon::copyrightdescription, + if ($style eq 'rat') { +# -------------------------------------- Retrofix for non-applicable copyright + if ($metadatafields{'copyright'} eq 'public') { + delete $metadatafields{'copyright'}; + $defaultoption='default'; + } + $intr_scrout.=&selectbox('Copyright/Distribution','copyright', + $defaultoption, + \&Apache::loncommon::copyrightdescription, (grep !/^public$/,(&Apache::loncommon::copyrightids))); - } else { - $scrout.=&selectbox('Copyright/Distribution','copyright', - $defaultoption, - \&Apache::loncommon::copyrightdescription, - (&Apache::loncommon::copyrightids)); - } - - my $copyright_help = - Apache::loncommon::help_open_topic('Publishing_Copyright'); - $scrout =~ s/DISTRIBUTION:/'DISTRIBUTION: ' . $copyright_help/ge; - $scrout.=&textfield('Custom Distribution File','customdistributionfile', - $metadatafields{'customdistributionfile'}). - $copyright_help; - my $uctitle=uc(&mt('Obsolete')); - $scrout.= - "\n

$uctitle:". - '

',0); -# ============================================================================= -# BATCH MODE -# + $intr_scrout.=&selectbox('Copyright/Distribution','copyright', + $defaultoption, + \&Apache::loncommon::copyrightdescription, + (&Apache::loncommon::copyrightids)); + } + my $copyright_help = + Apache::loncommon::help_open_topic('Publishing_Copyright'); + $intr_scrout =~ s/DISTRIBUTION:/'DISTRIBUTION: ' . $copyright_help/ge; + $intr_scrout.=&textfield('Custom Distribution File','customdistributionfile', + $metadatafields{'customdistributionfile'}). + $copyright_help; + $intr_scrout.=&selectbox('Source Distribution','sourceavail', + $defaultsourceoption, + \&Apache::loncommon::source_copyrightdescription, + (&Apache::loncommon::source_copyrightids)); + $intr_scrout.=&textfield('Source Custom Distribution File','sourcerights', + $metadatafields{'sourcerights'}); + my $uctitle=&mt('Obsolete'); + $intr_scrout.= + "\n

$uctitle:". + '

'; } + return($scrout,0); } ######################################### @@ -1303,7 +1330,7 @@ sub phasetwo { %metadatafields=(); %metadatakeys=(); - + &metaeval(&Apache::lonnet::unescape($ENV{'form.allmeta'})); $metadatafields{'title'}=$ENV{'form.title'}; @@ -1317,12 +1344,19 @@ sub phasetwo { $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'}; $metadatafields{'obsoletereplacement'}= $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'})) { @@ -1332,10 +1366,22 @@ sub phasetwo { $allkeywords .= ','.$ENV{'form.keywords'}; } } - $allkeywords=~s/\W+/\,/; - $allkeywords=~s/^\,//; + $allkeywords=~s/[\"\']//g; + $allkeywords=~s/\s*[\;\,]\s*/\,/g; + $allkeywords=~s/\s+/ /g; + $allkeywords=~s/^[ \,]//; + $allkeywords=~s/[ \,]$//; $metadatafields{'keywords'}=$allkeywords; +# check if custom distribution file is specified + if ($metadatafields{'copyright'} eq 'custom') { + my $file=$metadatafields{'customdistributionfile'}; + unless ($file=~/\.rights$/) { + return + ''.&mt('No valid custom distribution rights file specified, FAIL'). + ''; + } + } { print $logfile "\nWrite metadata file for ".$source; my $mfh; @@ -1357,7 +1403,7 @@ sub phasetwo { print $mfh ' '.$_.'="'.$value.'"'; } print $mfh '>'. - &HTML::Entities::encode($metadatafields{$unikey}) + &HTML::Entities::encode($metadatafields{$unikey},'<>&"') .''; } } @@ -1369,21 +1415,19 @@ sub phasetwo { $metadatafields{'url'} = $distarget; $metadatafields{'version'} = 'current'; - unless ($metadatafields{'copyright'} eq 'priv') { - 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 ($error,$success) = &store_metadata(%metadatafields); + if ($success) { + $r->print('

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

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

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

'); - print $logfile "\nPrivate: Did not synchronize data into ". - "SQL metadata database"; + $r->print($error); + print $logfile "\n".$error; } +# --------------------------------------------- Delete author resource messages + my $delresult=&Apache::lonmsg::del_url_author_res_msg($target); + $r->print('

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

'); + print $logfile "\nRemoving error messages: $delresult"; # ----------------------------------------------------------- Copy old versions if (-e $target) { @@ -1541,6 +1585,7 @@ sub phasetwo { '">'. &mt('Back to Source Directory').'

'); } + return '

'.&mt('Done').'

'; } ######################################### @@ -1595,8 +1640,8 @@ sub publishdirectory { my $resdir= $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'.$cudom.'/'.$cuname.'/'. $thisdisfn; - $r->print('

Directory '.$thisdisfn.'

'. - 'Target: '.$resdir.'
'); + $r->print('

'.&mt('Directory').' '.$thisdisfn.'

'. + &mt('Target').': '.$resdir.'
'); my $dirptr=16384; # Mask indicating a directory in stat.cmode. @@ -1634,13 +1679,70 @@ sub publishdirectory { if ($publishthis) { &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename); } else { - $r->print('
Skipping '.$filename.'
'); + $r->print('
'.&mt('Skipping').' '.$filename.'
'); } $r->rflush(); } } closedir(DIR); } + +######################################### +# publish a default.meta file + +sub defaultmetapublish { + my ($r,$fn,$cuname,$cudom)=@_; + $fn=~s/^\/\~$cuname\//\/home\/$cuname\/public_html\//; + unless (-e $fn) { + return HTTP_NOT_FOUND; + } + my $target=$fn; + $target=~s/^\/home\/$cuname\/public_html\//$Apache::lonnet::perlvar{'lonDocRoot'}\/res\/$cudom\/$cuname\//; + + + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; + + $r->print('LON-CAPA Publishing'); + $r->print(&Apache::loncommon::bodytag('Catalog Information Publication')); + +# ---------------------------------------------------------------- Write Source + my $copyfile=$target; + + my @parts=split(/\//,$copyfile); + my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]"; + + my $count; + for ($count=5;$count<$#parts;$count++) { + $path.="/$parts[$count]"; + if ((-e $path)!=1) { + $r->print('

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

'); + mkdir($path,0777); + } + } + + if (copy($fn,$copyfile)) { + $r->print('

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

'); + } else { + return "". + &mt('Failed to copy source').", $!, ".&mt('FAIL').""; + } + +# --------------------------------------------------- Send update notifications + + my @subscribed=&get_subscribed_hosts($target); + foreach my $subhost (@subscribed) { + $r->print('

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


');$r->rflush; + } +# ------------------------------------------------------------------- Link back + my $link=$fn; + $link=~s/^\/home\/$cuname\/public_html\//\/priv\/$cuname\//; + $r->print("".&mt('Back to Catalog Information').''); + $r->print(''); + return OK; +} ######################################### =pod @@ -1699,6 +1801,14 @@ sub handler { my $fn=&Apache::lonnet::unescape($ENV{'form.filename'}); + ($cuname,$cudom)= + &Apache::loncacc::constructaccess($fn,$r->dir_config('lonDefDomain')); + +# special publication: default.meta file + if ($fn=~/\/default.meta$/) { + return &defaultmetapublish($r,$fn,$cuname,$cudom); + } + $fn=~s/\.meta$//; unless ($fn) { $r->log_reason($cuname.' at '.$cudom. @@ -1706,8 +1816,6 @@ sub handler { return HTTP_NOT_FOUND; } - ($cuname,$cudom)= - &Apache::loncacc::constructaccess($fn,$r->dir_config('lonDefDomain')); unless (($cuname) && ($cudom)) { $r->log_reason($cuname.' at '.$cudom. ' trying to publish file '.$ENV{'form.filename'}. @@ -1716,12 +1824,14 @@ sub handler { return HTTP_NOT_ACCEPTABLE; } - unless (&Apache::lonnet::homeserver($cuname,$cudom) - eq $r->dir_config('lonHostID')) { + my $home=&Apache::lonnet::homeserver($cuname,$cudom); + my $allowed=0; + my @ids=&Apache::lonnet::current_machine_ids(); + 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'}. - ' ('.$fn.') - not homeserver ('. - &Apache::lonnet::homeserver($cuname,$cudom).')', + ' ('.$fn.') - not homeserver ('.$home.')', $r->filename); return HTTP_NOT_ACCEPTABLE; } @@ -1840,8 +1950,8 @@ ENDDIFF my ($outstring,$error)=&publish($thisfn,$thistarget,$thisembstyle); $r->print('
'.$outstring); } else { - $r->print('
'); - &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget); + $r->print('
'. + &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget)); } } $r->print('');