Diff for /loncom/publisher/lonpublisher.pm between versions 1.152 and 1.212

version 1.152, 2003/12/26 19:12:51 version 1.212, 2006/09/13 21:43:26
Line 121  use HTML::LCParser; Line 121  use HTML::LCParser;
 use Apache::lonxml;  use Apache::lonxml;
 use Apache::loncacc;  use Apache::loncacc;
 use DBI;  use DBI;
 use Apache::lonnet();  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonmysql;  use Apache::lonmysql;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::loncfile;  use Apache::loncfile;
   use LONCAPA::lonmetadata;
   use Apache::lonmsg;
 use vars qw(%metadatafields %metadatakeys);  use vars qw(%metadatafields %metadatakeys);
   use lib '/home/httpd/lib/perl/';
   use LONCAPA;
    
   
 my %addid;  my %addid;
 my %nokey;  my %nokey;
Line 136  my $docroot; Line 141  my $docroot;
 my $cuname;  my $cuname;
 my $cudom;  my $cudom;
   
   my $registered_cleanup;
   my $modified_urls;
   
 =pod  =pod
   
 =item B<metaeval>  =item B<metaeval>
Line 197  sub metaeval { Line 205  sub metaeval {
  }   }
     }      }
     my $newentry=$parser->get_text('/'.$entry);      my $newentry=$parser->get_text('/'.$entry);
     if ($entry eq 'customdistributionfile') {      if (($entry eq 'customdistributionfile') ||
    ($entry eq 'sourcerights')) {
  $newentry=~s/^\s*//;   $newentry=~s/^\s*//;
  if ($newentry !~m|^/res|) { $newentry=$prefix.$newentry; }   if ($newentry !~m|^/res|) { $newentry=$prefix.$newentry; }
     }      }
 # actually store  # actually store
     $metadatafields{$unikey}=$newentry;      if ( $entry eq 'rule' && exists($metadatafields{$unikey})) {
    $metadatafields{$unikey}.=','.$newentry;
       } else {
    $metadatafields{$unikey}=$newentry;
       }
  }   }
     }      }
 }  }
Line 316  sub textfield { Line 329  sub textfield {
     $value=~s/\s+$//gs;      $value=~s/\s+$//gs;
     $value=~s/\s+/ /gs;      $value=~s/\s+/ /gs;
     $title=&mt($title);      $title=&mt($title);
     my $uctitle=uc($title);      $env{'form.'.$name}=$value;
     return "\n<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:".      return "\n<p><font color=\"#800000\" face=\"helvetica\"><b>$title:".
            "</b></font></p><br />".             "</b></font></p><br />".
            '<input type="text" name="'.$name.'" size=80 value="'.$value.'" />';             '<input type="text" name="'.$name.'" size=80 value="'.$value.'" />';
 }  }
   
   sub text_with_browse_field {
       my ($title,$name,$value,$restriction)=@_;
       $value=~s/^\s+//gs;
       $value=~s/\s+$//gs;
       $value=~s/\s+/ /gs;
       $title=&mt($title);
       $env{'form.'.$name}=$value;
       return "\n<p><font color=\"#800000\" face=\"helvetica\"><b>$title:".
              "</b></font></p><br />".
              '<input type="text" name="'.$name.'" size=80 value="'.$value.'" />'.
      '<a href="javascript:openbrowser(\'pubform\',\''.$name.'\',\''.$restriction.'\');">Select</a>&nbsp;'.
      '<a href="javascript:opensearcher(\'pubform\',\''.$name.'\');">Search</a>';
      
   }
   
 sub hiddenfield {  sub hiddenfield {
     my ($name,$value)=@_;      my ($name,$value)=@_;
       $env{'form.'.$name}=$value;
     return "\n".'<input type="hidden" name="'.$name.'" value="'.$value.'" />';      return "\n".'<input type="hidden" name="'.$name.'" value="'.$value.'" />';
 }  }
   
   sub checkbox {
       my ($name,$text)=@_;
       return "\n<br /><label><input type='checkbox' name='$name' /> ".
    &mt($text)."</label>";
   }
   
 sub selectbox {  sub selectbox {
     my ($title,$name,$value,$functionref,@idlist)=@_;      my ($title,$name,$value,$functionref,@idlist)=@_;
     $title=&mt($title);      $title=&mt($title);
     my $uctitle=uc($title);  
     $value=(split(/\s*,\s*/,$value))[-1];      $value=(split(/\s*,\s*/,$value))[-1];
     my $selout="\n<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:".      if (defined($value)) {
    $env{'form.'.$name}=$value;
       } else {
    $env{'form.'.$name}=$idlist[0];
       }
       my $selout="\n<p><font color=\"#800000\" face=\"helvetica\"><b>$title:".
  '</b></font></p><br /><select name="'.$name.'">';   '</b></font></p><br /><select name="'.$name.'">';
     foreach (@idlist) {      foreach (@idlist) {
         $selout.='<option value=\''.$_.'\'';          $selout.='<option value=\''.$_.'\'';
Line 344  sub selectbox { Line 383  sub selectbox {
     return $selout.'</select>';      return $selout.'</select>';
 }  }
   
   sub select_level_form {
       my ($value,$name)=@_;
       $env{'form.'.$name}=$value;
       if (!defined($value)) { $env{'form.'.$name}=0; }
       return  &Apache::loncommon::select_level_form($value,$name);
   }
 #########################################  #########################################
 #########################################  #########################################
   
Line 454  sub get_subscribed_hosts { Line 499  sub get_subscribed_hosts {
     while ($filename=readdir(DIR)) {      while ($filename=readdir(DIR)) {
  if ($filename=~/\Q$srcf\E\.(\w+)$/) {   if ($filename=~/\Q$srcf\E\.(\w+)$/) {
     my $subhost=$1;      my $subhost=$1;
     if (($subhost ne 'meta' && $subhost ne 'subscription') &&      if (($subhost ne 'meta' && $subhost ne 'subscription' &&
    $subhost ne 'tmp') &&
                 ($subhost ne $Apache::lonnet::perlvar{'lonHostID'})) {                  ($subhost ne $Apache::lonnet::perlvar{'lonHostID'})) {
  push(@subscribed,$subhost);   push(@subscribed,$subhost);
     }      }
Line 465  sub get_subscribed_hosts { Line 511  sub get_subscribed_hosts {
     if ( $sh=Apache::File->new("$target.subscription") ) {      if ( $sh=Apache::File->new("$target.subscription") ) {
  &Apache::lonnet::logthis("opened $target.subscription");   &Apache::lonnet::logthis("opened $target.subscription");
  while (my $subline=<$sh>) {   while (my $subline=<$sh>) {
     &Apache::lonnet::logthis("Trying $subline");  
     if ($subline =~ /(^\w+):/) {       if ($subline =~ /(^\w+):/) { 
                 if ($1 ne $Apache::lonnet::perlvar{'lonHostID'}) {                   if ($1 ne $Apache::lonnet::perlvar{'lonHostID'}) { 
                    push(@subscribed,$1);                     push(@subscribed,$1);
Line 505  sub get_max_ids_indices { Line 550  sub get_max_ids_indices {
     my %duplicatedids;      my %duplicatedids;
   
     my $parser=HTML::LCParser->new($content);      my $parser=HTML::LCParser->new($content);
       $parser->xml_mode(1);
     my $token;      my $token;
     while ($token=$parser->get_token) {      while ($token=$parser->get_token) {
  if ($token->[0] eq 'S') {   if ($token->[0] eq 'S') {
     my $counter;      my $counter;
     if ($counter=$addid{$token->[1]}) {      if ($counter=$addid{$token->[1]}) {
  if ($counter eq 'id') {   if ($counter eq 'id') {
     if (defined($token->[2]->{'id'})) {      if (defined($token->[2]->{'id'}) &&
    $token->[2]->{'id'} !~ /^\s*$/) {
  $maxid=($token->[2]->{'id'}>$maxid)?$token->[2]->{'id'}:$maxid;   $maxid=($token->[2]->{'id'}>$maxid)?$token->[2]->{'id'}:$maxid;
  if (exists($allids{$token->[2]->{'id'}})) {   if (exists($allids{$token->[2]->{'id'}})) {
     $duplicateids=1;      $duplicateids=1;
Line 523  sub get_max_ids_indices { Line 570  sub get_max_ids_indices {
  $needsfixup=1;   $needsfixup=1;
     }      }
  } else {   } else {
     if (defined($token->[2]->{'index'})) {      if (defined($token->[2]->{'index'}) &&
    $token->[2]->{'index'} !~ /^\s*$/) {
  $maxindex=($token->[2]->{'index'}>$maxindex)?$token->[2]->{'index'}:$maxindex;   $maxindex=($token->[2]->{'index'}>$maxindex)?$token->[2]->{'index'}:$maxindex;
     } else {      } else {
  $needsfixup=1;   $needsfixup=1;
Line 565  sub get_all_text_unbalanced { Line 613  sub get_all_text_unbalanced {
  } elsif ($token->[0] eq 'E')  {   } elsif ($token->[0] eq 'E')  {
     $result.=$token->[2];      $result.=$token->[2];
  }   }
  if ($result =~ /(.*)\Q$tag\E(.*)/s) {   if ($result =~ /\Q$tag\E/s) {
       ($result,my $redo)=$result =~ /(.*)\Q$tag\E(.*)/is;
     #&Apache::lonnet::logthis('Got a winner with leftovers ::'.$2);      #&Apache::lonnet::logthis('Got a winner with leftovers ::'.$2);
     #&Apache::lonnet::logthis('Result is :'.$1);      #&Apache::lonnet::logthis('Result is :'.$1);
     $result=$1;      $redo=$tag.$redo;
     my $redo=$tag.$2;  
     push (@$pars,HTML::LCParser->new(\$redo));      push (@$pars,HTML::LCParser->new(\$redo));
     $$pars[-1]->xml_mode('1');      $$pars[-1]->xml_mode('1');
     last;      last;
Line 632  sub fix_ids_and_indices { Line 680  sub fix_ids_and_indices {
     $allow{$token->[2]->{'src'}}=1;      $allow{$token->[2]->{'src'}}=1;
     next;      next;
  }   }
    if ($lctag eq 'base') { next; }
  my %parms=%{$token->[2]};   my %parms=%{$token->[2]};
  $counter=$addid{$tag};   $counter=$addid{$tag};
  if (!$counter) { $counter=$addid{$lctag}; }   if (!$counter) { $counter=$addid{$lctag}; }
  if ($counter) {   if ($counter) {
     if ($counter eq 'id') {      if ($counter eq 'id') {
  unless (defined($parms{'id'})) {   unless (defined($parms{'id'}) &&
    $parms{'id'}!~/^\s*$/) {
     $maxid++;      $maxid++;
     $parms{'id'}=$maxid;      $parms{'id'}=$maxid;
     print $logfile 'ID: '.$tag.':'.$maxid."\n";      print $logfile 'ID(new) : '.$tag.':'.$maxid."\n";
    } else {
       print $logfile 'ID(kept): '.$tag.':'.$parms{'id'}."\n";
  }   }
     } elsif ($counter eq 'index') {      } elsif ($counter eq 'index') {
  unless (defined($parms{'index'})) {   unless (defined($parms{'index'}) &&
    $parms{'index'}!~/^\s*$/) {
     $maxindex++;      $maxindex++;
     $parms{'index'}=$maxindex;      $parms{'index'}=$maxindex;
     print $logfile 'Index: '.$tag.':'.$maxindex."\n";      print $logfile 'Index: '.$tag.':'.$maxindex."\n";
  }   }
     }      }
  }   }
  foreach my $type ('src','href','background','bgimg') {                  unless ($parms{'type'} eq 'zombie') {
     foreach my $key (keys(%parms)) {      foreach my $type ('src','href','background','bgimg') {
  if ($key =~ /^$type$/i) {   foreach my $key (keys(%parms)) {
     $parms{$key}=&set_allow(\%allow,$logfile,      if ($key =~ /^$type$/i) {
     $target,$tag,   $parms{$key}=&set_allow(\%allow,$logfile,
     $parms{$key});   $target,$tag,
    $parms{$key});
       }
  }   }
     }      }
  }   }
Line 784  sub store_metadata { Line 839  sub store_metadata {
         &Apache::lonnet::logthis($error);          &Apache::lonnet::logthis($error);
         return ($error,undef);          return ($error,undef);
     }      }
       my $dbh = &Apache::lonmysql::get_dbh();
     if (($metadata{'obsolete'}) || ($metadata{'copyright'} eq 'priv') ||      if (($metadata{'obsolete'}) || ($metadata{'copyright'} eq 'priv') ||
  ($metadata{'copyright'} eq 'custom')) {   ($metadata{'copyright'} eq 'custom')) {
 # remove this entry          # remove this entry
  $status=&Apache::lonmysql::remove_from_table   $status=&LONCAPA::lonmetadata::delete_metadata($dbh,undef,
     ('metadata','url',$metadata{'url'});                                                         $metadata{'url'});
     } else {      } else {
 # store new data          $status = &LONCAPA::lonmetadata::update_metadata($dbh,undef,
  $metadata{'creationdate'}=                                                           \%metadata);
     &Apache::lonmysql::sqltime($metadata{'creationdate'});   
  $metadata{'lastrevisiondate'}=  
     &Apache::lonmysql::sqltime($metadata{'lastrevisiondate'});   
  $status = &Apache::lonmysql::store_row('metadata',\%metadata);  
     }      }
     if (! defined($status)) {      if (defined($status) && $status ne '') {
         $error='<font color="red">Error occured storing new values in '.          $error='<font color="red">Error occured storing new values in '.
             'metadata table in LON-CAPA database</font>';              'metadata table in LON-CAPA database</font>';
         &Apache::lonnet::logthis($error);          &Apache::lonnet::logthis($error);
           &Apache::lonnet::logthis($status);
         return ($error,undef);          return ($error,undef);
     }      }
     return (undef,$status);      return (undef,$status);
 }  }
   
   
   # ========================================== Parse file for errors and warnings
   
   sub checkonthis {
       my ($r,$source)=@_;
       my $uri=&Apache::lonnet::hreflocation($source);
       $uri=~s/\/$//;
       my $result=&Apache::lonnet::ssi_body($uri,
    ('grade_target'=>'web',
     'return_only_error_and_warning_counts' => 1));
       my ($errorcount,$warningcount)=split(':',$result);
       if (($errorcount) || ($warningcount)) {
           $r->print('<br /><tt>'.$uri.'</tt>: ');
    if ($errorcount) {
       $r->print('<img src="/adm/lonMisc/bomb.gif" /><font color="red"><b>'.
         $errorcount.' '.
         &mt('error(s)').'</b></font> ');
    }
    if ($warningcount) {
       $r->print('<font color="blue">'.
         $warningcount.' '.
         &mt('warning(s)').'</font>');
    }
       } else {
    #$r->print('<font color="green">'.&mt('ok').'</font>');
       }
       $r->rflush();
       return ($warningcount,$errorcount);
   }
   
 # ============================================== Parse file itself for metadata  # ============================================== Parse file itself for metadata
 #  #
 # parses a file with target meta, sets global %metadatafields %metadatakeys   # parses a file with target meta, sets global %metadatafields %metadatakeys 
Line 860  sub publish { Line 942  sub publish {
  return ('<font color="red">'.&mt('No write permission to user directory, FAIL').'</font>',1);   return ('<font color="red">'.&mt('No write permission to user directory, FAIL').'</font>',1);
     }      }
     print $logfile       print $logfile 
 "\n\n================= Publish ".localtime()." Phase One  ================\n".$ENV{'user.name'}.'@'.$ENV{'user.domain'}."\n";  "\n\n================= Publish ".localtime()." Phase One  ================\n".$env{'user.name'}.':'.$env{'user.domain'}."\n";
   
     if (($style eq 'ssi') || ($style eq 'rat') || ($style eq 'prv')) {      if (($style eq 'ssi') || ($style eq 'rat') || ($style eq 'prv')) {
 # ------------------------------------------------------- This needs processing  # ------------------------------------------------------- This needs processing
Line 890  sub publish { Line 972  sub publish {
               $allowstr.="\n".'<allow src="'.$thisdep.'" />';                $allowstr.="\n".'<allow src="'.$thisdep.'" />';
    }     }
            $scrout.='<br />';             $scrout.='<br />';
            unless ($thisdep=~/\*/) {             if ($thisdep!~/\*/ && $thisdep!~m|^/adm/|) {
        $scrout.='<a href="'.$thisdep.'">';         $scrout.='<a href="'.$thisdep.'">';
            }             }
            $scrout.='<tt>'.$thisdep.'</tt>';             $scrout.='<tt>'.$thisdep.'</tt>';
            unless ($thisdep=~/\*/) {             if ($thisdep!~/\*/ && $thisdep!~m|^/adm/|) {
        $scrout.='</a>';         $scrout.='</a>';
                if (                 if (
        &Apache::lonnet::getfile($Apache::lonnet::perlvar{'lonDocRoot'}.'/'.         &Apache::lonnet::getfile($Apache::lonnet::perlvar{'lonDocRoot'}.'/'.
Line 913  sub publish { Line 995  sub publish {
        }         }
            }             }
         }          }
         $outstring=~s/\n*(\<\/[^\>]+\>)\s*$/$allowstr\n$1\n/s;          $outstring=~s/\n*(\<\/[^\>]+\>[^<]*)$/$allowstr\n$1\n/s;
   
 ### FIXME: is this really what we want?  
 # I dont' think so, to will corrupt any UTF-8 resources at least,   
 # and any encoding other than ISO-8859-1 will probably break  
  #Encode any High ASCII characters  
  #$outstring=&HTML::Entities::encode($outstring,"\200-\377");  
 # ------------------------------------------------------------- Write modified.  # ------------------------------------------------------------- Write modified.
   
         {          {
Line 952  sub publish { Line 1029  sub publish {
     }      }
   
 # ------------------------------------------------ First, check out environment  # ------------------------------------------------ First, check out environment
      unless (-e $source.'.meta') {       if ((!(-e $source.'.meta')) || ($env{'form.forceoverride'})) {
         $metadatafields{'author'}=$ENV{'environment.firstname'}.' '.          $metadatafields{'author'}=$env{'environment.firstname'}.' '.
                           $ENV{'environment.middlename'}.' '.                            $env{'environment.middlename'}.' '.
                   $ENV{'environment.lastname'}.' '.                    $env{'environment.lastname'}.' '.
                   $ENV{'environment.generation'};                    $env{'environment.generation'};
         $metadatafields{'author'}=~s/\s+/ /g;          $metadatafields{'author'}=~s/\s+/ /g;
         $metadatafields{'author'}=~s/\s+$//;          $metadatafields{'author'}=~s/\s+$//;
         $metadatafields{'owner'}=$cuname.'@'.$cudom;          $metadatafields{'owner'}=$cuname.':'.$cudom;
  $metadatafields{'modifyinguser'}=$ENV{'user.name'}.'@'.  
                                  $ENV{'user.domain'};  
  $metadatafields{'authorspace'}=$cuname.'@'.$cudom;  
   
 # ------------------------------------------------ Check out directory hierachy  # ------------------------------------------------ Check out directory hierachy
   
Line 980  sub publish { Line 1054  sub publish {
             $scrout.=&metaread($logfile,$currentpath.'default.meta',$prefix);              $scrout.=&metaread($logfile,$currentpath.'default.meta',$prefix);
     $prefix=~s|^\.\./||;      $prefix=~s|^\.\./||;
         }          }
   
 # ----------------------------------------------------------- Parse file itself  # ----------------------------------------------------------- Parse file itself
 # read %metadatafields from file itself  # read %metadatafields from file itself
     
Line 1004  sub publish { Line 1079  sub publish {
  delete $metadatafields{$_};   delete $metadatafields{$_};
             }              }
         }          }
   # ------------------------------------------------------------- Save some stuff
           my %savemeta=();
           foreach ('title') {
               $savemeta{$_}=$metadatafields{$_};
    }
 # ------------------------------------------ See if anything new in file itself  # ------------------------------------------ See if anything new in file itself
     
  $allmeta=&parseformeta($source,$style);   $allmeta=&parseformeta($source,$style);
   # ----------------------------------------------------------- Restore the stuff
           foreach (keys %savemeta) {
       $metadatafields{$_}=$savemeta{$_};
    }
    }     }
   
                 
Line 1066  sub publish { Line 1150  sub publish {
     }      }
   
                           
     foreach (split(/\W+/,$metadatafields{'keywords'})) {      foreach my $addkey (split(/[\"\'\,\;]/,$metadatafields{'keywords'})) {
  $keywords{$_}=1;   $addkey=~s/\s+/ /g;
    $addkey=~s/^\s//;
    $addkey=~s/\s$//;
    if ($addkey=~/\w/) {
       $keywords{$addkey}=1;
    }
     }      }
 # --------------------------------------------------- Now we also have keywords  # --------------------------------------------------- Now we also have keywords
 # =============================================================================  # =============================================================================
 # INTERACTIVE MODE  # interactive mode html goes into $intr_scrout
 #  # batch mode throws away this HTML
     unless ($batch) {  # additionally all of the field functions have a by product of setting
         $scrout.=  #   $env{'from.'..} so that it can be used by the phase two handler in
     '<form name="pubform" action="/adm/publish" method="post">'.  #    batch mode
             '<p><input type="submit" value="'.&mt('Finalize Publication').'" /></p>'.  
             &hiddenfield('phase','two').      my $intr_scrout.=
             &hiddenfield('filename',$ENV{'form.filename'}).   '<form name="pubform" action="/adm/publish" method="post">'.
     &hiddenfield('allmeta',&Apache::lonnet::escape($allmeta)).   '<p>'.($env{'form.makeobsolete'}?'':'<input type="submit" value="'.&mt('Finalize Publication').'" />').'</p>'.
             &hiddenfield('dependencies',join(',',keys %allow)).   &hiddenfield('phase','two').
             &textfield('Title','title',$metadatafields{'title'}).   &hiddenfield('filename',$env{'form.filename'}).
             &textfield('Author(s)','author',$metadatafields{'author'}).   &hiddenfield('allmeta',&escape($allmeta)).
     &textfield('Subject','subject',$metadatafields{'subject'});   &hiddenfield('dependencies',join(',',keys %allow));
       unless ($env{'form.makeobsolete'}) {
 # --------------------------------------------------- Scan content for keywords         $intr_scrout.=
    &textfield('Title','title',$metadatafields{'title'}).
         my $keywords_help = Apache::loncommon::help_open_topic("Publishing_Keywords");   &textfield('Author(s)','author',$metadatafields{'author'}).
         my $KEYWORDS=&mt('KEYWORDS');   &textfield('Subject','subject',$metadatafields{'subject'});
  my $CheckAll=&mt('check all');   # --------------------------------------------------- Scan content for keywords
  my $UncheckAll=&mt('uncheck all');  
  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";
 <script>  <script>
 function checkAll(field) {  function checkAll(field) {
     for (i = 0; i < field.length; i++)      for (i = 0; i < field.length; i++)
Line 1110  function uncheckAll(field) { Line 1203  function uncheckAll(field) {
 </p>  </p>
 <br />  <br />
 END  END
  $keywordout.='<table border="2"><tr>';      $keywordout.='<table border="2"><tr>';
  my $colcount=0;      my $colcount=0;
   
  foreach (sort keys %keywords) {      foreach (sort keys %keywords) {
     $keywordout.='<td><input type="checkbox" name="keywords" value="'.$_.'"';   $keywordout.='<td><label><input type="checkbox" name="keywords" value="'.$_.'"';
     if ($metadatafields{'keywords'}) {   if ($metadatafields{'keywords'}) {
  if ($metadatafields{'keywords'}=~/\Q$_\E/) {      if ($metadatafields{'keywords'}=~/\Q$_\E/) {
     $keywordout.=' checked="on"';  
  }  
     } elsif (&Apache::loncommon::keyword($_)) {  
  $keywordout.=' checked="on"';   $keywordout.=' checked="on"';
    $env{'form.keywords'}.=$_.',';
     }      }
     $keywordout.=' />'.$_.'</td>';   } elsif (&Apache::loncommon::keyword($_)) {
     if ($colcount>10) {      $keywordout.=' checked="on"';
  $keywordout.="</tr><tr>\n";      $env{'form.keywords'}.=$_.',';
  $colcount=0;   }
     }   $keywordout.=' />'.$_.'</label></td>';
     $colcount++;   if ($colcount>10) {
       $keywordout.="</tr><tr>\n";
       $colcount=0;
  }   }
    $colcount++;
       }
       $env{'form.keywords'}=~s/\,$//;
   
  $keywordout.='</tr></table>';      $keywordout.='</tr></table>';
   
  $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.=      $intr_scrout.=
     "\n<p><font color=\"#800000\" face=\"helvetica\"><b>".&mt('ABSTRACT').":".   "\n<p><font color=\"#800000\" face=\"helvetica\"><b>".&mt('Abstract').":".
     "</b></font></p><br />".   "</b></font></p><br />".
     '<textarea cols="80" rows="5" name="abstract">'.   '<textarea cols="80" rows="5" name="abstract">'.
     $metadatafields{'abstract'}.'</textarea></p>';   $metadatafields{'abstract'}.'</textarea></p>';
   
  $source=~/\.(\w+)$/;      $source=~/\.(\w+)$/;
   
   
  $scrout.=      $intr_scrout.=
     "\n<p><font color=\"#800000\" face=\"helvetica\"><b>".   "\n<p><font color=\"#800000\" face=\"helvetica\"><b>".
     uc(&mt('Lowest Grade Level:')).   &mt('Lowest Grade Level').':'.
            "</b></font></p><br />".   "</b></font></p><br />".
    &Apache::loncommon::select_level_form($metadatafields{'lowestgradelevel'},'lowestgradelevel').   &select_level_form($metadatafields{'lowestgradelevel'},'lowestgradelevel').
     "\n<p><font color=\"#800000\" face=\"helvetica\"><b>".   "\n<p><font color=\"#800000\" face=\"helvetica\"><b>".
     uc(&mt('Highest Grade Level:')).   &mt('Highest Grade Level').':'.
            "</b></font></p><br />".   "</b></font></p><br />".
    &Apache::loncommon::select_level_form($metadatafields{'highestgradelevel'},'highestgradelevel').   &select_level_form($metadatafields{'highestgradelevel'},'highestgradelevel').
            &textfield('Standards','standards',$metadatafields{'standards'});   &textfield('Standards','standards',$metadatafields{'standards'});
   
   
   
   
  $scrout.=&hiddenfield('mime',$1);      $intr_scrout.=&hiddenfield('mime',$1);
   
  my $defaultlanguage=$metadatafields{'language'};      my $defaultlanguage=$metadatafields{'language'};
  $defaultlanguage =~ s/\s*notset\s*//g;      $defaultlanguage =~ s/\s*notset\s*//g;
  $defaultlanguage =~ s/^,\s*//g;      $defaultlanguage =~ s/^,\s*//g;
  $defaultlanguage =~ s/,\s*$//g;      $defaultlanguage =~ s/,\s*$//g;
   
  $scrout.=&selectbox('Language','language',      $intr_scrout.=&selectbox('Language','language',
     $defaultlanguage,       $defaultlanguage,
     \&Apache::loncommon::languagedescription,       \&Apache::loncommon::languagedescription,
     (&Apache::loncommon::languageids),       (&Apache::loncommon::languageids),
    );       );
   
  unless ($metadatafields{'creationdate'}) {      unless ($metadatafields{'creationdate'}) {
     $metadatafields{'creationdate'}=time;   $metadatafields{'creationdate'}=time;
  }      }
  $scrout.=&hiddenfield('creationdate',      $intr_scrout.=&hiddenfield('creationdate',
       &Apache::loncommon::unsqltime($metadatafields{'creationdate'}));         &Apache::lonmysql::unsqltime($metadatafields{'creationdate'}));
   
  $scrout.=&hiddenfield('lastrevisiondate',time);      $intr_scrout.=&hiddenfield('lastrevisiondate',time);
   
   
  $scrout.=&textfield('Publisher/Owner','owner',      $intr_scrout.=&textfield('Publisher/Owner','owner',
     $metadatafields{'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.  # -------------------------------------------------- Correct copyright for rat.
         my $defaultoption=$metadatafields{'copyright'};   if ($style eq 'rat') {
         unless ($defaultoption) { $defaultoption='default'; }  # -------------------------------------- Retrofix for non-applicable copyright
  unless ($style eq 'prv') {      if ($metadatafields{'copyright'} eq 'public') { 
     if ($style eq 'rat') {   delete $metadatafields{'copyright'};
  if ($metadatafields{'copyright'} eq 'public') {    $defaultoption='default';
     delete $metadatafields{'copyright'};      }
                     $defaultoption='default';      $intr_scrout.=&selectbox('Copyright/Distribution','copyright',
  }       $defaultoption,
  $scrout.=&selectbox('Copyright/Distribution','copyright',       \&Apache::loncommon::copyrightdescription,
     $defaultoption,  
     \&Apache::loncommon::copyrightdescription,  
     (grep !/^public$/,(&Apache::loncommon::copyrightids)));      (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<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:".  
  '</b></font> <input type="checkbox" name="obsolete" ';  
     if ($metadatafields{'obsolete'}) {  
  $scrout.=' checked="1" ';  
     }  
     $scrout.='/ ></p>'.  
  &textfield('Suggested Replacement for Obsolete File',  
     'obsoletereplacement',  
     $metadatafields{'obsoletereplacement'});  
  } else {   } else {
     $scrout.=&hiddenfield('copyright','private');      $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.=&text_with_browse_field('Custom Distribution File','customdistributionfile',$metadatafields{'customdistributionfile'},'rights').$copyright_help;
    $intr_scrout.=&selectbox('Source Distribution','sourceavail',
    $defaultsourceoption,
    \&Apache::loncommon::source_copyrightdescription,
    (&Apache::loncommon::source_copyrightids));
   # $intr_scrout.=&text_with_browse_field('Source Custom Distribution File','sourcerights',$metadatafields{'sourcerights'},'rights');
    my $uctitle=&mt('Obsolete');
    $intr_scrout.=
       "\n<p><label><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:".
       '</b></font> <input type="checkbox" name="obsolete" ';
    if ($metadatafields{'obsolete'}) {
       $intr_scrout.=' checked="1" ';
  }   }
  return ($scrout.'<p><input type="submit" value="'.   $intr_scrout.='/ ></label></p>'.
  &mt('Finalize Publication').'" /></p></form>',0);      &text_with_browse_field('Suggested Replacement for Obsolete File',
 # =============================================================================      'obsoletereplacement',
 # BATCH MODE      $metadatafields{'obsoletereplacement'});
 #  
     } else {      } else {
 # Transfer metadata directly to environment for stage 2   $intr_scrout.=&hiddenfield('copyright','private');
  foreach (keys %metadatafields) {      }
     $ENV{'form.'.$_}=$metadatafields{$_};     } else {
  }         $intr_scrout.=
  $ENV{'form.addkey'}='';   &hiddenfield('title',$metadatafields{'title'}).
  $ENV{'form.keywords'}='';   &hiddenfield('author',$metadatafields{'author'}).
  foreach (keys %keywords) {   &hiddenfield('subject',$metadatafields{'subject'}).
     if ($metadatafields{'keywords'}) {   &hiddenfield('keywords',$metadatafields{'keywords'}).
  if ($metadatafields{'keywords'}=~/\Q$_\E/) {    &hiddenfield('abstract',$metadatafields{'abstract'}).
     $ENV{'form.keywords'}.=$_.',';    &hiddenfield('notes',$metadatafields{'notes'}).
  }   &hiddenfield('mime',$metadatafields{'mime'}).
     } elsif (&Apache::loncommon::keyword($_)) {   &hiddenfield('creationdate',$metadatafields{'creationdate'}).
  $ENV{'form.keywords'}.=$_.',';   &hiddenfield('lastrevisiondate',time).
     }   &hiddenfield('owner',$metadatafields{'owner'}).
  }   &hiddenfield('lowestgradelevel',$metadatafields{'lowestgradelevel'}).
  $ENV{'form.keywords'}=~s/\,$//;   &hiddenfield('standards',$metadatafields{'standards'}).
  unless ($ENV{'form.creationdate'}) { $ENV{'form.creationdate'}=time; }   &hiddenfield('highestgradelevel',$metadatafields{'highestgradelevel'}).
  $ENV{'form.lastrevisiondate'}=time;   &hiddenfield('language',$metadatafields{'language'}).
  if ((($style eq 'rat') && ($ENV{'form.copyright'} eq 'public')) ||   &hiddenfield('copyright',$metadatafields{'copyright'}).
     (!$ENV{'form.copyright'})) {    &hiddenfield('sourceavail',$metadatafields{'sourceavail'}).
     $ENV{'form.copyright'}='default';   &hiddenfield('customdistributionfile',$metadatafields{'customdistributionfile'}).
  }   &hiddenfield('obsolete',1).
  $ENV{'form.allmeta'}=&Apache::lonnet::escape($allmeta);   &text_with_browse_field('Suggested Replacement for Obsolete File',
  return ($scrout,0);      'obsoletereplacement',
       $metadatafields{'obsoletereplacement'});
      }
       if (!$batch) {
    $scrout.=$intr_scrout.'<p><input type="submit" value="'.
       &mt($env{'form.makeobsolete'}?'Make Obsolete':'Finalize Publication').'" /></p></form>';
     }      }
       return($scrout,0);
 }  }
   
 #########################################  #########################################
Line 1287  Returns: Line 1392  Returns:
   
 =over 4  =over 4
   
 =item Scalar string  =item integer
   
 String contains status (errors and warnings) and information associated with  0: fail
 the server's attempts at publication.       1: success
   
 =cut  =cut
   
Line 1302  sub phasetwo { Line 1407  sub phasetwo {
     my ($r,$source,$target,$style,$distarget,$batch)=@_;      my ($r,$source,$target,$style,$distarget,$batch)=@_;
     $source=~s/\/+/\//g;      $source=~s/\/+/\//g;
     $target=~s/\/+/\//g;      $target=~s/\/+/\//g;
   #
     if ($target=~/\_\_\_/) {  # Unless trying to get rid of something, check name validity
  $r->print(  #
  '<font color="red">'.&mt('Unsupported character combination').      unless ($env{'form.obsolete'}) {
   ' "<tt>___</tt>" '.&mt('in filename, FAIL').'</font>');   if ($target=~/(\_\_\_|\&\&\&|\:\:\:)/) {
         return 0;      $r->print(
         '<font color="red">'.&mt('Unsupported character combination').
         ' "<tt>'.$1.'</tt>" '.&mt('in filename, FAIL').'</font>');
       return 0;
    }
    unless ($target=~/\.(\w+)$/) {
       $r->print('<font color="red">'.&mt('No valid extension found in filename, FAIL').'</font>');
       return 0;
    }
    if ($target=~/\.(\d+)\.(\w+)$/) {
       $r->print('<font color="red">'.&mt('Cannot publish versioned resource, FAIL').'</font>');
       return 0;
    }
     }      }
   
   #
   # End name check
   #
     $distarget=~s/\/+/\//g;      $distarget=~s/\/+/\//g;
     my $logfile;      my $logfile;
     unless ($logfile=Apache::File->new('>>'.$source.'.log')) {      unless ($logfile=Apache::File->new('>>'.$source.'.log')) {
Line 1318  sub phasetwo { Line 1439  sub phasetwo {
         return 0;          return 0;
     }      }
     print $logfile       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=();      %metadatafields=();
     %metadatakeys=();      %metadatakeys=();
   
       &metaeval(&unescape($env{'form.allmeta'}));
           
     &metaeval(&Apache::lonnet::unescape($ENV{'form.allmeta'}));      $metadatafields{'title'}=$env{'form.title'};
           $metadatafields{'author'}=$env{'form.author'};
     $metadatafields{'title'}=$ENV{'form.title'};      $metadatafields{'subject'}=$env{'form.subject'};
     $metadatafields{'author'}=$ENV{'form.author'};      $metadatafields{'notes'}=$env{'form.notes'};
     $metadatafields{'subject'}=$ENV{'form.subject'};      $metadatafields{'abstract'}=$env{'form.abstract'};
     $metadatafields{'notes'}=$ENV{'form.notes'};      $metadatafields{'mime'}=$env{'form.mime'};
     $metadatafields{'abstract'}=$ENV{'form.abstract'};      $metadatafields{'language'}=$env{'form.language'};
     $metadatafields{'mime'}=$ENV{'form.mime'};      $metadatafields{'creationdate'}=$env{'form.creationdate'};
     $metadatafields{'language'}=$ENV{'form.language'};      $metadatafields{'lastrevisiondate'}=$env{'form.lastrevisiondate'};
     $metadatafields{'creationdate'}=$ENV{'form.creationdate'};      $metadatafields{'owner'}=$env{'form.owner'};
     $metadatafields{'lastrevisiondate'}=$ENV{'form.lastrevisiondate'};      $metadatafields{'copyright'}=$env{'form.copyright'};
     $metadatafields{'owner'}=$ENV{'form.owner'};      $metadatafields{'standards'}=$env{'form.standards'};
     $metadatafields{'copyright'}=$ENV{'form.copyright'};      $metadatafields{'lowestgradelevel'}=$env{'form.lowestgradelevel'};
     $metadatafields{'standards'}=$ENV{'form.standards'};      $metadatafields{'highestgradelevel'}=$env{'form.highestgradelevel'};
     $metadatafields{'lowestgradelevel'}=$ENV{'form.lowestgradelevel'};  
     $metadatafields{'highestgradelevel'}=$ENV{'form.highestgradelevel'};  
     $metadatafields{'customdistributionfile'}=      $metadatafields{'customdistributionfile'}=
                                  $ENV{'form.customdistributionfile'};                                   $env{'form.customdistributionfile'};
     $metadatafields{'obsolete'}=$ENV{'form.obsolete'};      $metadatafields{'sourceavail'}=$env{'form.sourceavail'};
       $metadatafields{'obsolete'}=$env{'form.obsolete'};
     $metadatafields{'obsoletereplacement'}=      $metadatafields{'obsoletereplacement'}=
                         $ENV{'form.obsoletereplacement'};                          $env{'form.obsoletereplacement'};
     $metadatafields{'dependencies'}=$ENV{'form.dependencies'};      $metadatafields{'dependencies'}=$env{'form.dependencies'};
       $metadatafields{'modifyinguser'}=$env{'user.name'}.':'.
                                    $env{'user.domain'};
       $metadatafields{'authorspace'}=$cuname.':'.$cudom;
           
     my $allkeywords=$ENV{'form.addkey'};      my $allkeywords=$env{'form.addkey'};
     if (exists($ENV{'form.keywords'})) {      if (exists($env{'form.keywords'})) {
         if (ref($ENV{'form.keywords'})) {          if (ref($env{'form.keywords'})) {
             $allkeywords .= ','.join(',',@{$ENV{'form.keywords'}});              $allkeywords .= ','.join(',',@{$env{'form.keywords'}});
         } else {          } else {
             $allkeywords .= ','.$ENV{'form.keywords'};              $allkeywords .= ','.$env{'form.keywords'};
         }          }
     }      }
     $allkeywords=~s/\W+/\,/;      $allkeywords=~s/[\"\']//g;
     $allkeywords=~s/^\,//;      $allkeywords=~s/\s*[\;\,]\s*/\,/g;
       $allkeywords=~s/\s+/ /g;
       $allkeywords=~s/^[ \,]//;
       $allkeywords=~s/[ \,]$//;
     $metadatafields{'keywords'}=$allkeywords;      $metadatafields{'keywords'}=$allkeywords;
           
 # check if custom distribution file is specified  # check if custom distribution file is specified
     if ($metadatafields{'copyright'} eq 'custom') {      if ($metadatafields{'copyright'} eq 'custom') {
  my $file=$metadatafields{'customdistributionfile'};   my $file=$metadatafields{'customdistributionfile'};
  unless ($file=~/\.rights$/) {   unless ($file=~/\.rights$/) {
             return               $r->print(
                 '<font color="red">'.&mt('No valid custom distribution rights file specified, FAIL').                  '<font color="red">'.&mt('No valid custom distribution rights file specified, FAIL').
  '</font>';   '</font>');
       return 0;
         }          }
     }      }
     {      {
         print $logfile "\nWrite metadata file for ".$source;          print $logfile "\nWrite metadata file for ".$source;
         my $mfh;          my $mfh;
         unless ($mfh=Apache::File->new('>'.$source.'.meta')) {          unless ($mfh=Apache::File->new('>'.$source.'.meta')) {
             return               $r->print( 
                 '<font color="red">'.&mt('Could not write metadata, FAIL').                  '<font color="red">'.&mt('Could not write metadata, FAIL').
  '</font>';   '</font>');
       return 0;
         }          }
         foreach (sort keys %metadatafields) {          foreach (sort keys %metadatafields) {
             unless ($_=~/\./) {              unless ($_=~/\./) {
Line 1388  sub phasetwo { Line 1518  sub phasetwo {
                     print $mfh ' '.$_.'="'.$value.'"';                      print $mfh ' '.$_.'="'.$value.'"';
                 }                  }
                 print $mfh '>'.                  print $mfh '>'.
                     &HTML::Entities::encode($metadatafields{$unikey})                      &HTML::Entities::encode($metadatafields{$unikey},'<>&"')
                         .'</'.$tag.'>';                          .'</'.$tag.'>';
             }              }
         }          }
Line 1409  sub phasetwo { Line 1539  sub phasetwo {
  $r->print($error);   $r->print($error);
  print $logfile "\n".$error;   print $logfile "\n".$error;
     }      }
   # --------------------------------------------- Delete author resource messages
       my $delresult=&Apache::lonmsg::del_url_author_res_msg($target); 
       $r->print('<p>'.&mt('Removing error messages:').' '.$delresult.'</p>');
       print $logfile "\nRemoving error messages: $delresult";
 # ----------------------------------------------------------- Copy old versions  # ----------------------------------------------------------- Copy old versions
         
     if (-e $target) {      if (-e $target) {
Line 1421  sub phasetwo { Line 1554  sub phasetwo {
         my $srcd=$1;          my $srcd=$1;
         unless ($srcd=~/^\/home\/httpd\/html\/res/) {          unless ($srcd=~/^\/home\/httpd\/html\/res/) {
             print $logfile "\nPANIC: Target dir is ".$srcd;              print $logfile "\nPANIC: Target dir is ".$srcd;
             return "<font color=\"red\">Invalid target directory, FAIL</font>";              $r->print(
    "<font color=\"red\">Invalid target directory, FAIL</font>");
       return 0;
         }          }
         opendir(DIR,$srcd);          opendir(DIR,$srcd);
         while ($filename=readdir(DIR)) {          while ($filename=readdir(DIR)) {
Line 1446  sub phasetwo { Line 1581  sub phasetwo {
             $r->print('<p>'.&mt('Copied old target file').'</p>');              $r->print('<p>'.&mt('Copied old target file').'</p>');
         } else {          } else {
     print $logfile "Unable to write ".$copyfile.':'.$!."\n";      print $logfile "Unable to write ".$copyfile.':'.$!."\n";
             return "<font color=\"red\">".&mt('Failed to copy old target').              $r->print("<font color=\"red\">".&mt('Failed to copy old target').
  ", $!, ".&mt('FAIL')."</font>";   ", $!, ".&mt('FAIL')."</font>");
       return 0;
         }          }
                   
 # --------------------------------------------------------------- Copy Metadata  # --------------------------------------------------------------- Copy Metadata
Line 1460  sub phasetwo { Line 1596  sub phasetwo {
         } else {          } else {
     print $logfile "Unable to write metadata ".$copyfile.':'.$!."\n";      print $logfile "Unable to write metadata ".$copyfile.':'.$!."\n";
             if (-e $target.'.meta') {              if (-e $target.'.meta') {
                 return                   $r->print( 
                     "<font color=\"red\">".                      "<font color=\"red\">".
 &mt('Failed to write old metadata copy').", $!, ".&mt('FAIL')."</font>";  &mt('Failed to write old metadata copy').", $!, ".&mt('FAIL')."</font>");
    return 0;
     }      }
         }          }
                   
Line 1493  sub phasetwo { Line 1630  sub phasetwo {
         $r->print('<p>'.&mt('Copied source file').'</p>');          $r->print('<p>'.&mt('Copied source file').'</p>');
     } else {      } else {
         print $logfile "\nUnable to write ".$copyfile.':'.$!."\n";          print $logfile "\nUnable to write ".$copyfile.':'.$!."\n";
         return "<font color=\"red\">".          $r->print("<font color=\"red\">".
     &mt('Failed to copy source').", $!, ".&mt('FAIL')."</font>";      &mt('Failed to copy source').", $!, ".&mt('FAIL')."</font>");
    return 0;
     }      }
           
 # --------------------------------------------------------------- Copy Metadata  # --------------------------------------------------------------- Copy Metadata
Line 1506  sub phasetwo { Line 1644  sub phasetwo {
         $r->print('<p>'.&mt('Copied metadata').'</p>');          $r->print('<p>'.&mt('Copied metadata').'</p>');
     } else {      } else {
         print $logfile "\nUnable to write metadata ".$copyfile.':'.$!."\n";          print $logfile "\nUnable to write metadata ".$copyfile.':'.$!."\n";
         return           $r->print(
             "<font color=\"red\">".&mt('Failed to write metadata copy').", $!, ".&mt('FAIL')."</font>";              "<font color=\"red\">".&mt('Failed to write metadata copy').", $!, ".&mt('FAIL')."</font>");
    return 0;
     }      }
     $r->rflush;      $r->rflush;
 # --------------------------------------------------- Send update notifications  
   
     my @subscribed=&get_subscribed_hosts($target);  # ------------------------------------------------------------- Trigger updates
     foreach my $subhost (@subscribed) {      push(@{$modified_urls},[$target,$source]);
  $r->print('<p>'.&mt('Notifying host').' '.$subhost.':');$r->rflush;      unless ($registered_cleanup) {
  print $logfile "\nNotifying host ".$subhost.':';   $r->register_cleanup(\&notify);
  my $reply=&Apache::lonnet::critical('update:'.$target,$subhost);   $registered_cleanup=1;
  $r->print($reply.'</p><br />');$r->rflush;  
  print $logfile $reply;  
     }      }
       
 # ---------------------------------------- Send update notifications, meta only  
   
     my @subscribedmeta=&get_subscribed_hosts("$target.meta");  # ---------------------------------------------------------- Clear local caches
     foreach my $subhost (@subscribedmeta) {      my $thisdistarget=$target;
  $r->print('<p>'.      $thisdistarget=~s/^\Q$docroot\E//;
 &mt('Notifying host for metadata only').' '.$subhost.':');$r->rflush;      &Apache::lonnet::devalidate_cache_new('resversion',$target);
  print $logfile "\nNotifying host for metadata only ".$subhost.':';      &Apache::lonnet::devalidate_cache_new('meta',
  my $reply=&Apache::lonnet::critical('update:'.$target.'.meta',   &Apache::lonnet::declutter($thisdistarget));
     $subhost);  
  $r->print($reply.'</p><br />');$r->rflush;  
  print $logfile $reply;  
     }  
       
 # --------------------------------------------------- Notify subscribed courses  
     my %courses=&coursedependencies($target);  
     my $now=time;  
     foreach (keys %courses) {  
  $r->print('<p>'.&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.'</p><br />');$r->rflush;  
  print $logfile $reply;  
     }  
 # ------------------------------------------------ Provide link to new resource  # ------------------------------------------------ Provide link to new resource
     unless ($batch) {      unless ($batch) {
         my $thisdistarget=$target;  
         $thisdistarget=~s/^\Q$docroot\E//;  
                   
         my $thissrc=$source;          my $thissrc=$source;
         $thissrc=~s/^\/home\/(\w+)\/public_html/\/priv\/$1/;          $thissrc=~s/^\/home\/(\w+)\/public_html/\/priv\/$1/;
Line 1567  sub phasetwo { Line 1683  sub phasetwo {
                    '"><font size="+2">'.                     '"><font size="+2">'.
   &mt('Back to Source Directory').'</font></a></p>');    &mt('Back to Source Directory').'</font></a></p>');
     }      }
     return '<p><font color="green">'.&mt('Done').'</font></p>';      $logfile->close();
       $r->print('<p><font color="green">'.&mt('Done').'</font></p>');
       return 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;
    }
   # ---------------------------------------- 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;
    } 
   # --------------------------------------------------- Notify subscribed courses
    my %courses=&coursedependencies($target);
    my $now=time;
    foreach (keys %courses) {
       print $logfile "\nNotifying course ".$_.':';
       my ($cdom,$cname)=split(/\_/,$_);
       my $reply=&Apache::lonnet::cput
    ('versionupdate',{$target => $now},$cdom,$cname);
       print $logfile $reply;
    }
    print $logfile "\n============ Done ============\n";
    $logfile->close();
       }
       return OK;
 }  }
   
 #########################################  #########################################
   
 sub batchpublish {  sub batchpublish {
     my ($r,$srcfile,$targetfile)=@_;      my ($r,$srcfile,$targetfile)=@_;
     #publication pollutes %ENV with form.* values      #publication pollutes %env with form.* values
     my %oldENV=%ENV;      my %oldenv=%env;
     $srcfile=~s/\/+/\//g;      $srcfile=~s/\/+/\//g;
     $targetfile=~s/\/+/\//g;      $targetfile=~s/\/+/\//g;
     my $thisdisfn=$srcfile;      my $thisdisfn=$srcfile;
Line 1603  sub batchpublish { Line 1758  sub batchpublish {
     $r->print('<p>'.$outstring.'</p>');      $r->print('<p>'.$outstring.'</p>');
 # phase two takes  # phase two takes
 # my ($source,$target,$style,$distarget,batch)=@_;  # 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) {      if (!$error) {
  $r->print('<p>');   $r->print('<p>');
  &phasetwo($r,$srcfile,$targetfile,$thisembstyle,$thisdistarget,1);   &phasetwo($r,$srcfile,$targetfile,$thisembstyle,$thisdistarget,1);
  $r->print('</p>');   $r->print('</p>');
     }      }
     %ENV=%oldENV;      %env=%oldenv;
     return '';      return '';
 }  }
   
Line 1622  sub publishdirectory { Line 1777  sub publishdirectory {
     my $resdir=      my $resdir=
  $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'.$cudom.'/'.$cuname.'/'.   $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'.$cudom.'/'.$cuname.'/'.
  $thisdisfn;   $thisdisfn;
     $r->print('<h1>Directory <tt>'.$thisdisfn.'</tt></h1>'.      $r->print('<h1>'.&mt('Directory').' <tt>'.$thisdisfn.'</tt></h1>'.
       'Target: <tt>'.$resdir.'</tt><br />');        &mt('Target').': <tt>'.$resdir.'</tt><br />');
   
     my $dirptr=16384; # Mask indicating a directory in stat.cmode.      my $dirptr=16384; # Mask indicating a directory in stat.cmode.
       unless ($env{'form.phase'} eq 'two') {
     opendir(DIR,$fn);  # ask user what they want
     my @files=sort(readdir(DIR));          $r->print('<form name="pubdirpref" method="post">'.
     foreach my $filename (@files) {    &hiddenfield('phase','two').
  my ($cdev,$cino,$cmode,$cnlink,    &hiddenfield('filename',$env{'form.filename'}).
             $cuid,$cgid,$crdev,$csize,    &checkbox('pubrec','include subdirectories').
             $catime,$cmtime,$cctime,    &checkbox('forcerepub','force republication of previously published files').
             $cblksize,$cblocks)=stat($fn.'/'.$filename);                    &checkbox('obsolete','make file(s) obsolete').
     &checkbox('forceoverride','force directory level catalog information over existing').
  my $extension='';    '<br /><input type="submit" value="'.&mt('Publish Directory').'" /></form>');
  if ($filename=~/\.(\w+)$/) { $extension=$1; }      } else {
  if ($cmode&$dirptr) {  # actually publish things
     if (($filename!~/^\./) && ($ENV{'form.pubrec'})) {   opendir(DIR,$fn);
  &publishdirectory($r,$fn.'/'.$filename,$thisdisfn.'/'.$filename);   my @files=sort(readdir(DIR));
     }   foreach my $filename (@files) {
  } elsif ((&Apache::loncommon::fileembstyle($extension) ne 'hdn') &&      my ($cdev,$cino,$cmode,$cnlink,
  ($filename!~/^[\#\.]/) && ($filename!~/\~$/)) {   $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  # find out publication status and/or exiting metadata
     my $publishthis=0;   my $publishthis=0;
     if (-e $resdir.'/'.$filename) {   if (-e $resdir.'/'.$filename) {
         my ($rdev,$rino,$rmode,$rnlink,      my ($rdev,$rino,$rmode,$rnlink,
     $ruid,$rgid,$rrdev,$rsize,   $ruid,$rgid,$rrdev,$rsize,
     $ratime,$rmtime,$rctime,   $ratime,$rmtime,$rctime,
     $rblksize,$rblocks)=stat($resdir.'/'.$filename);   $rblksize,$rblocks)=stat($resdir.'/'.$filename);
         if (($rmtime<$cmtime) || ($ENV{'form.forcerepub'})) {      if (($rmtime<$cmtime) || ($env{'form.forcerepub'})) {
 # previously published, modified now  # previously published, modified now
     $publishthis=1;   $publishthis=1;
                 }      }
     } else {      my $meta_cmtime = (stat($fn.'/'.$filename.'.meta'))[9];
       my $meta_rmtime = (stat($resdir.'/'.$filename.'.meta'))[9];
       if ( $meta_rmtime<$meta_cmtime ) {
    &Apache::lonnet::logthis("meta change!");
    $publishthis=1;
       }
    } else {
 # never published  # never published
  $publishthis=1;      $publishthis=1;
     }   }
     if ($publishthis) {  
                 &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename);   if ($publishthis) {
     } else {      &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename);
  $r->print('<br />Skipping '.$filename.'<br />');   } else {
       $r->print('<br />'.&mt('Skipping').' '.$filename.'<br />');
    }
    $r->rflush();
     }      }
     $r->rflush();  
  }   }
    closedir(DIR);
     }      }
     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(&Apache::loncommon::start_page('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('<p>'.&mt('Created directory').' '.$parts[$count].'</p>');
               mkdir($path,0777);
           }
       }
       
       if (copy($fn,$copyfile)) {
           $r->print('<p>'.&mt('Copied source file').'</p>');
       } else {
           return "<font color=\"red\">".
       &mt('Failed to copy source').", $!, ".&mt('FAIL')."</font>";
       }
   
   # --------------------------------------------------- Send update notifications
   
       my @subscribed=&get_subscribed_hosts($target);
       foreach my $subhost (@subscribed) {
    $r->print('<p>'.&mt('Notifying host').' '.$subhost.':');$r->rflush;
    my $reply=&Apache::lonnet::critical('update:'.$target,$subhost);
    $r->print($reply.'</p><br />');$r->rflush;
       }
   # ------------------------------------------------------------------- Link back
       my $link=$fn;
       $link=~s/^\/home\/$cuname\/public_html\//\/priv\/$cuname\//;
       $r->print("<a href='$link'>".&mt('Back to Catalog Information').'</a>');
       $r->print(&Apache::loncommon::end_page());
       return OK;
 }  }
 #########################################  #########################################
   
Line 1722  sub handler { Line 1952  sub handler {
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                             ['filename']);                                              ['filename']);
   
   # -------------------------------------- Flag and buffer for registered cleanup
       $registered_cleanup=0;
       @{$modified_urls}=();
 # -------------------------------------------------------------- Check filename  # -------------------------------------------------------------- Check filename
   
     my $fn=&Apache::lonnet::unescape($ENV{'form.filename'});      my $fn=&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) {       unless ($fn) { 
  $r->log_reason($cuname.' at '.$cudom.   $r->log_reason($cuname.' at '.$cudom.
Line 1733  sub handler { Line 1974  sub handler {
  return HTTP_NOT_FOUND;   return HTTP_NOT_FOUND;
     }       } 
   
     ($cuname,$cudom)=  
  &Apache::loncacc::constructaccess($fn,$r->dir_config('lonDefDomain'));  
     unless (($cuname) && ($cudom)) {      unless (($cuname) && ($cudom)) {
  $r->log_reason($cuname.' at '.$cudom.   $r->log_reason($cuname.' at '.$cudom.
        ' trying to publish file '.$ENV{'form.filename'}.         ' trying to publish file '.$env{'form.filename'}.
        ' ('.$fn.') - not authorized',          ' ('.$fn.') - not authorized', 
        $r->filename);          $r->filename); 
  return HTTP_NOT_ACCEPTABLE;   return HTTP_NOT_ACCEPTABLE;
     }      }
   
     unless (&Apache::lonnet::homeserver($cuname,$cudom)       my $home=&Apache::lonnet::homeserver($cuname,$cudom);
     eq $r->dir_config('lonHostID')) {      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.   $r->log_reason($cuname.' at '.$cudom.
        ' trying to publish file '.$ENV{'form.filename'}.         ' trying to publish file '.$env{'form.filename'}.
        ' ('.$fn.') - not homeserver ('.         ' ('.$fn.') - not homeserver ('.$home.')', 
        &Apache::lonnet::homeserver($cuname,$cudom).')',   
        $r->filename);          $r->filename); 
  return HTTP_NOT_ACCEPTABLE;   return HTTP_NOT_ACCEPTABLE;
     }      }
Line 1761  sub handler { Line 2002  sub handler {
     if ($1 ne $cuname) {      if ($1 ne $cuname) {
  $r->log_reason($cuname.' at '.$cudom.   $r->log_reason($cuname.' at '.$cudom.
        ' trying to publish unowned file '.         ' trying to publish unowned file '.
        $ENV{'form.filename'}.' ('.$fn.')',          $env{'form.filename'}.' ('.$fn.')', 
        $r->filename);          $r->filename); 
  return HTTP_NOT_ACCEPTABLE;   return HTTP_NOT_ACCEPTABLE;
     } else {      } else {
Line 1772  sub handler { Line 2013  sub handler {
     unless (-e $fn) {       unless (-e $fn) { 
  $r->log_reason($cuname.' at '.$cudom.   $r->log_reason($cuname.' at '.$cudom.
        ' trying to publish non-existing file '.         ' trying to publish non-existing file '.
        $ENV{'form.filename'}.' ('.$fn.')',          $env{'form.filename'}.' ('.$fn.')', 
        $r->filename);          $r->filename); 
  return HTTP_NOT_FOUND;   return HTTP_NOT_FOUND;
     }       } 
   
     unless ($ENV{'form.phase'} eq 'two') {  
   
 # -------------------------------- File is there and owned, init lookup tables.  # -------------------------------- File is there and owned, init lookup tables.
   
  %addid=();      %addid=();
       
  {      {
     my $fh=Apache::File->new($r->dir_config('lonTabDir').'/addid.tab');   my $fh=Apache::File->new($r->dir_config('lonTabDir').'/addid.tab');
     while (<$fh>=~/(\w+)\s+(\w+)/) {   while (<$fh>=~/(\w+)\s+(\w+)/) {
  $addid{$1}=$2;      $addid{$1}=$2;
     }  
  }   }
       }
   
  %nokey=();      %nokey=();
   
  {      {
     my $fh=Apache::File->new($r->dir_config('lonIncludes').'/un_keyword.tab');   my $fh=Apache::File->new($r->dir_config('lonIncludes').'/un_keyword.tab');
     while (<$fh>) {   while (<$fh>) {
  my $word=$_;      my $word=$_;
  chomp($word);      chomp($word);
  $nokey{$word}=1;      $nokey{$word}=1;
     }  
  }   }
   
     }      }
   
 # ---------------------------------------------------------- Start page output.  # ---------------------------------------------------------- Start page output.
   
     &Apache::loncommon::content_type($r,'text/html');      &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;      $r->send_http_header;
       
     $r->print('<html><head><title>LON-CAPA Publishing</title></head>');      my $js='<script type="text/javascript">'.
     $r->print(&Apache::loncommon::bodytag('Resource Publication'));   &Apache::loncommon::browser_and_searcher_javascript().
    '</script>';
       $r->print(&Apache::loncommon::start_page('Resource Publication',$js));
   
   
     my $thisfn=$fn;      my $thisfn=$fn;
Line 1828  sub handler { Line 2067  sub handler {
     if ($fn=~/\/$/) {      if ($fn=~/\/$/) {
 # -------------------------------------------------------- This is a directory  # -------------------------------------------------------- This is a directory
  &publishdirectory($r,$fn,$thisdisfn);   &publishdirectory($r,$fn,$thisdisfn);
  $r->print('<hr><font size="+2">'.&mt('Done').'</font><br><a href="/priv/'   $r->print('<hr /><a href="/priv/'
   .$cuname.'/'.$thisdisfn    .$cuname.'/'.$thisdisfn
   .'">'.&mt('Return to Directory').'</a>');    .'">'.&mt('Return to Directory').'</a>');
   
Line 1838  sub handler { Line 2077  sub handler {
  $thisfn=~/\.(\w+)$/;   $thisfn=~/\.(\w+)$/;
  my $thistype=$1;   my $thistype=$1;
  my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);   my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);
           if ($thistype eq 'page') {  $thisembstyle = 'rat'; }
  $r->print('<h2>'.&mt('Publishing').' '.   $r->print('<h2>'.&mt('Publishing').' '.
   &Apache::loncommon::filedescription($thistype).' <tt>');    &Apache::loncommon::filedescription($thistype).' <tt>');
   
Line 1848  ENDCAPTION Line 2088  ENDCAPTION
         $r->print('</tt></h2><b>'.&mt('Target').':</b> <tt>'.          $r->print('</tt></h2><b>'.&mt('Target').':</b> <tt>'.
   $thisdistarget.'</tt><br />');    $thisdistarget.'</tt><br />');
         
  if (($cuname ne $ENV{'user.name'})||($cudom ne $ENV{'user.domain'})) {   if (($cuname ne $env{'user.name'})||($cudom ne $env{'user.domain'})) {
     $r->print('<h3><font color="red">'.&mt('Co-Author').': '.      $r->print('<h3><font color="red">'.&mt('Co-Author').': '.
       $cuname.&mt(' at ').$cudom.'</font></h3>');        $cuname.&mt(' at ').$cudom.'</font></h3>');
  }   }
Line 1863  ENDDIFF Line 2103  ENDDIFF
       
 # ------------------ Publishing from $thisfn to $thistarget with $thisembstyle.  # ------------------ Publishing from $thisfn to $thistarget with $thisembstyle.
   
  unless ($ENV{'form.phase'} eq 'two') {   unless ($env{'form.phase'} eq 'two') {
     my ($outstring,$error)=&publish($thisfn,$thistarget,$thisembstyle);  # ---------------------------------------------------------- Parse for problems
     $r->print('<hr />'.$outstring);      my ($warningcount,$errorcount);
       if ($thisembstyle eq 'ssi') {
    ($warningcount,$errorcount)=&checkonthis($r,$thisfn);
       }
       unless ($errorcount) {
    my ($outstring,$error)=
       &publish($thisfn,$thistarget,$thisembstyle);
    $r->print('<hr />'.$outstring);
       } else {
    $r->print('<h3>'.
     &mt('The document contains errors and cannot be published.').
     '</h3>');
       }
  } else {   } else {
     $r->print('<hr />'.      &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget); 
     &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget));       $r->print('<hr />');
  }   }
     }      }
     $r->print('</body></html>');      $r->print(&Apache::loncommon::end_page());
   
     return OK;      return OK;
 }  }

Removed from v.1.152  
changed lines
  Added in v.1.212


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.