Diff for /loncom/publisher/lonpublisher.pm between versions 1.126 and 1.145.2.1.2.1

version 1.126, 2003/07/23 19:17:27 version 1.145.2.1.2.1, 2004/01/27 23:11:23
Line 82  invocation by F<loncapa_apache.conf>: Line 82  invocation by F<loncapa_apache.conf>:
   ErrorDocument     500 /adm/errorhandler    ErrorDocument     500 /adm/errorhandler
   </Location>    </Location>
   
   =head1 OVERVIEW
   
   Authors can only write-access the C</~authorname/> space. They can
   copy resources into the resource area through the publication step,
   and move them back through a recover step. Authors do not have direct
   write-access to their resource space.
   
   During the publication step, several events will be
   triggered. Metadata is gathered, where a wizard manages default
   entries on a hierarchical per-directory base: The wizard imports the
   metadata (including access privileges and royalty information) from
   the most recent published resource in the current directory, and if
   that is not available, from the next directory above, etc. The Network
   keeps all previous versions of a resource and makes them available by
   an explicit version number, which is inserted between the file name
   and extension, for example C<foo.2.html>, while the most recent
   version does not carry a version number (C<foo.html>). Servers
   subscribing to a changed resource are notified that a new version is
   available.
   
 =head1 DESCRIPTION  =head1 DESCRIPTION
   
 B<lonpublisher> takes the proper steps to add resources to the LON-CAPA  B<lonpublisher> takes the proper steps to add resources to the LON-CAPA
Line 122  use DBI; Line 142  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::loncfile;
 use vars qw(%metadatafields %metadatakeys);  use vars qw(%metadatafields %metadatakeys);
   
 my %addid;  my %addid;
Line 159  nothing Line 181  nothing
   
 #########################################  #########################################
 #########################################  #########################################
   #
   # Modifies global %metadatafields %metadatakeys 
   #
   
 sub metaeval {  sub metaeval {
     my $metastring=shift;      my ($metastring,$prefix)=@_;
         
         my $parser=HTML::LCParser->new(\$metastring);      my $parser=HTML::LCParser->new(\$metastring);
         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 $entry=$token->[1];      my $entry=$token->[1];
               my $unikey=$entry;      my $unikey=$entry;
               if (defined($token->[2]->{'package'})) {       if (defined($token->[2]->{'package'})) { 
                   $unikey.='_package_'.$token->[2]->{'package'};   $unikey.='_package_'.$token->[2]->{'package'};
               }       } 
               if (defined($token->[2]->{'part'})) {       if (defined($token->[2]->{'part'})) { 
                  $unikey.='_'.$token->[2]->{'part'};    $unikey.='_'.$token->[2]->{'part'}; 
       }      }
               if (defined($token->[2]->{'id'})) {       if (defined($token->[2]->{'id'})) { 
                   $unikey.='_'.$token->[2]->{'id'};   $unikey.='_'.$token->[2]->{'id'};
               }       } 
               if (defined($token->[2]->{'name'})) {       if (defined($token->[2]->{'name'})) { 
                  $unikey.='_'.$token->[2]->{'name'};    $unikey.='_'.$token->[2]->{'name'}; 
       }      }
               foreach (@{$token->[3]}) {      foreach (@{$token->[3]}) {
   $metadatafields{$unikey.'.'.$_}=$token->[2]->{$_};   $metadatafields{$unikey.'.'.$_}=$token->[2]->{$_};
                   if ($metadatakeys{$unikey}) {   if ($metadatakeys{$unikey}) {
       $metadatakeys{$unikey}.=','.$_;      $metadatakeys{$unikey}.=','.$_;
                   } else {   } else {
                       $metadatakeys{$unikey}=$_;      $metadatakeys{$unikey}=$_;
                   }   }
               }      }
               if ($metadatafields{$unikey}) {      my $newentry=$parser->get_text('/'.$entry);
   my $newentry=$parser->get_text('/'.$entry);      if ($entry eq 'customdistributionfile') {
                   unless (($metadatafields{$unikey}=~/\Q$newentry\E/) ||   $newentry=~s/^\s*//;
                           ($newentry eq '')) {   if ($newentry !~m|^/res|) { $newentry=$prefix.$newentry; }
                      $metadatafields{$unikey}.=', '.$newentry;      }
   }  # actually store
       } else {      if ( $entry eq 'rule' && exists($metadatafields{$unikey})) {
                  $metadatafields{$unikey}=$parser->get_text('/'.$entry);   $metadatafields{$unikey}.=','.$newentry;
               }      } else {
           }   $metadatafields{$unikey}=$newentry;
        }      }
    }
       }
 }  }
   
 #########################################  #########################################
Line 239  XHTML text that indicates successful rea Line 267  XHTML text that indicates successful rea
 #########################################  #########################################
 #########################################  #########################################
 sub metaread {  sub metaread {
     my ($logfile,$fn)=@_;      my ($logfile,$fn,$prefix)=@_;
     unless (-e $fn) {      unless (-e $fn) {
  print($logfile 'No file '.$fn."\n");   print($logfile 'No file '.$fn."\n");
         return '<br /><b>No file:</b> <tt>'.$fn.'</tt>';          return '<br /><b>No file:</b> <tt>'.
       &Apache::loncfile::display($fn).'</tt>';
     }      }
     print($logfile 'Processing '.$fn."\n");      print($logfile 'Processing '.$fn."\n");
     my $metastring;      my $metastring;
     {      {
      my $metafh=Apache::File->new($fn);   my $metafh=Apache::File->new($fn);
      $metastring=join('',<$metafh>);   $metastring=join('',<$metafh>);
     }      }
     &metaeval($metastring);      &metaeval($metastring,$prefix);
     return '<br /><b>Processed file:</b> <tt>'.$fn.'</tt>';      return '<br /><b>Processed file:</b> <tt>'.
    &Apache::loncfile::display($fn).'</tt>';
 }  }
   
 #########################################  #########################################
Line 304  string which presents the form field (fo Line 334  string which presents the form field (fo
 #########################################  #########################################
 sub textfield {  sub textfield {
     my ($title,$name,$value)=@_;      my ($title,$name,$value)=@_;
       $value=~s/^\s+//gs;
       $value=~s/\s+$//gs;
       $value=~s/\s+/ /gs;
       $title=&mt($title);
     my $uctitle=uc($title);      my $uctitle=uc($title);
     return "\n<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:".      return "\n<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:".
            "</b></font></p><br />".             "</b></font></p><br />".
Line 317  sub hiddenfield { Line 351  sub hiddenfield {
   
 sub selectbox {  sub selectbox {
     my ($title,$name,$value,$functionref,@idlist)=@_;      my ($title,$name,$value,$functionref,@idlist)=@_;
       $title=&mt($title);
     my $uctitle=uc($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:".      my $selout="\n<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:".
Line 647  sub fix_ids_and_indices { Line 682  sub fix_ids_and_indices {
     }      }
  }   }
  # probably a <randomlabel> image type <label>   # probably a <randomlabel> image type <label>
  if ($lctag eq 'label' && defined($parms{'description'})) {   # or a <image> tag inside <imageresponse>
    if (($lctag eq 'label' && defined($parms{'description'}))
       ||
       ($lctag eq 'image')) {
     my $next_token=$parser[-1]->get_token();      my $next_token=$parser[-1]->get_token();
     if ($next_token->[0] eq 'T') {      if ($next_token->[0] eq 'T') {
  $next_token->[1]=&set_allow(\%allow,$logfile,   $next_token->[1]=&set_allow(\%allow,$logfile,
Line 698  sub fix_ids_and_indices { Line 736  sub fix_ids_and_indices {
  }   }
  if (!$endtag) { if ($token->[4]=~m:/>$:) { $endtag=' /'; }; }   if (!$endtag) { if ($token->[4]=~m:/>$:) { $endtag=' /'; }; }
  $outstring.='<'.$tag.$newparmstring.$endtag.'>';   $outstring.='<'.$tag.$newparmstring.$endtag.'>';
  if ($lctag eq 'm') {   if ($lctag eq 'm' || $lctag eq 'script' 
     $outstring.=&get_all_text_unbalanced('/m',\@parser);                      || $lctag eq 'display' || $lctag eq 'tex') {
       $outstring.=&get_all_text_unbalanced('/'.$lctag,\@parser);
  }   }
     } elsif ($token->[0] eq 'E') {      } elsif ($token->[0] eq 'E') {
  if ($token->[2]) {   if ($token->[2]) {
Line 781  sub store_metadata { Line 820  sub store_metadata {
     return (undef,$status);      return (undef,$status);
 }  }
   
   
   # ============================================== Parse file itself for metadata
   #
   # parses a file with target meta, sets global %metadatafields %metadatakeys 
   
   sub parseformeta {
       my ($source,$style)=@_;
       my $allmeta='';
       if (($style eq 'ssi') || ($style eq 'prv')) {
    my $dir=$source;
    $dir=~s-/[^/]*$--;
    my $file=$source;
    $file=(split('/',$file))[-1];
           $source=&Apache::lonnet::hreflocation($dir,$file);
    $allmeta=&Apache::lonnet::ssi_body($source,('grade_target' => 'meta'));
           &metaeval($allmeta);
       }
       return $allmeta;
   }
   
 #########################################  #########################################
 #########################################  #########################################
   
Line 870  sub publish { Line 929  sub publish {
         }          }
         $outstring=~s/\n*(\<\/[^\>]+\>)\s*$/$allowstr\n$1\n/s;          $outstring=~s/\n*(\<\/[^\>]+\>)\s*$/$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   #Encode any High ASCII characters
  $outstring=&HTML::Entities::encode($outstring,"\200-\377");   #$outstring=&HTML::Entities::encode($outstring,"\200-\377");
 # ------------------------------------------------------------- Write modified.  # ------------------------------------------------------------- Write modified.
   
         {          {
           my $org;            my $org;
           unless ($org=Apache::File->new('>'.$source)) {            unless ($org=Apache::File->new('>'.$source)) {
              print $logfile "No write permit to $source\n";               print $logfile "No write permit to $source\n";
              return ('<font color="red">No write permission to '.$source.               return ('<font color="red">'.&mt('No write permission to').
      ', FAIL</font>',1);       ' '.$source.
        ', '.&mt('FAIL').'</font>',1);
   }    }
           print($org $outstring);            print($org $outstring);
         }          }
Line 889  sub publish { Line 952  sub publish {
 # -------------------------------------------- Initial step done, now metadata.  # -------------------------------------------- Initial step done, now metadata.
   
 # --------------------------------------- Storage for metadata keys and fields.  # --------------------------------------- Storage for metadata keys and fields.
   # these are globals
   #
      %metadatafields=();       %metadatafields=();
      %metadatakeys=();       %metadatakeys=();
             
      my %oldparmstores=();       my %oldparmstores=();
             
     unless ($batch) {      unless ($batch) {
      $scrout.='<h3>Metadata Information ' .       $scrout.='<h3>'.&mt('Metadata Information').' ' .
        Apache::loncommon::help_open_topic("Metadata_Description")         Apache::loncommon::help_open_topic("Metadata_Description")
        . '</h3>';         . '</h3>';
     }      }
Line 914  sub publish { Line 978  sub publish {
                                  $ENV{'user.domain'};                                   $ENV{'user.domain'};
  $metadatafields{'authorspace'}=$cuname.'@'.$cudom;   $metadatafields{'authorspace'}=$cuname.'@'.$cudom;
   
   # ----------------------------------------------------------- Parse file itself
   # read %metadatafields from file itself
    
    $allmeta=&parseformeta($source,$style);
 # ------------------------------------------------ Check out directory hierachy  # ------------------------------------------------ Check out directory hierachy
   
         my $thisdisfn=$source;          my $thisdisfn=$source;
Line 924  sub publish { Line 992  sub publish {
   
         my $currentpath='/home/'.$cuname.'/';          my $currentpath='/home/'.$cuname.'/';
   
    my $prefix='../'x($#urlparts);
         foreach (@urlparts) {          foreach (@urlparts) {
     $currentpath.=$_.'/';      $currentpath.=$_.'/';
             $scrout.=&metaread($logfile,$currentpath.'default.meta');              $scrout.=&metaread($logfile,$currentpath.'default.meta',$prefix);
       $prefix=~s|^\.\./||;
         }          }
   
 # ------------------- Clear out parameters and stores (there should not be any)  # ------------------- Clear out parameters and stores (there should not be any)
Line 948  sub publish { Line 1018  sub publish {
  delete $metadatafields{$_};   delete $metadatafields{$_};
             }              }
         }          }
           # ------------------------------------------ See if anything new in file itself
     }   
    $allmeta=&parseformeta($source,$style);
      }
   
 # -------------------------------------------------- Parse content for metadata         
     if (($style eq 'ssi') || ($style eq 'prv')) {  
         my $oldenv=$ENV{'request.uri'};  
   
         $ENV{'request.uri'}=$target;  
         $allmeta=Apache::lonxml::xmlparse(undef,'meta',$content);  
         $ENV{'request.uri'}=$oldenv;  
   
         &metaeval($allmeta);  
     }  
 # ---------------- Find and document discrepancies in the parameters and stores  # ---------------- Find and document discrepancies in the parameters and stores
   
     my $chparms='';      my $chparms='';
Line 975  sub publish { Line 1038  sub publish {
  }   }
     }      }
     if ($chparms) {      if ($chparms) {
  $scrout.='<p><b>New parameters or stored values:</b> '.$chparms.'</p>';   $scrout.='<p><b>'.&mt('New parameters or stored values').
       ':</b> '.$chparms.'</p>';
     }      }
   
     $chparms='';      $chparms='';
Line 989  sub publish { Line 1053  sub publish {
  }   }
     }      }
     if ($chparms) {      if ($chparms) {
  $scrout.='<p><b>Obsolete parameters or stored values:</b> '.   $scrout.='<p><b>'.&mt('Obsolete parameters or stored values').':</b> '.
     $chparms.'</p>';      $chparms.'</p><h1><font color="red">'.&mt('Warning!').
       '</font></h1><p><font color="red" size="+1">'.
       &mt('If this resource is in active use, student performance data from the previous version may become inaccessible.').'</font></p><hr />';
     }      }
   
 # ------------------------------------------------------- Now have all metadata  # ------------------------------------------------------- Now have all metadata
Line 1142  END Line 1208  END
     $scrout.=&textfield('Custom Distribution File','customdistributionfile',      $scrout.=&textfield('Custom Distribution File','customdistributionfile',
  $metadatafields{'customdistributionfile'}).   $metadatafields{'customdistributionfile'}).
     $copyright_help;      $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');      $scrout.=&hiddenfield('copyright','private');
  }   }
  return ($scrout.'<p><input type="submit" value="Finalize Publication" /></p></form>',0);   return ($scrout.'<p><input type="submit" value="'.
    &mt('Finalize Publication').'" /></p></form>',0);
 # =============================================================================  # =============================================================================
 # BATCH MODE  # BATCH MODE
 #  #
Line 1223  sub phasetwo { Line 1301  sub phasetwo {
   
     if ($target=~/\_\_\_/) {      if ($target=~/\_\_\_/) {
  $r->print(   $r->print(
  '<font color="red">Unsupported character combination "<tt>___</tt>" in filename, FAIL</font>');   '<font color="red">'.&mt('Unsupported character combination').
     ' "<tt>___</tt>" '.&mt('in filename, FAIL').'</font>');
         return 0;          return 0;
     }      }
     $distarget=~s/\/+/\//g;      $distarget=~s/\/+/\//g;
     my $logfile;      my $logfile;
     unless ($logfile=Apache::File->new('>>'.$source.'.log')) {      unless ($logfile=Apache::File->new('>>'.$source.'.log')) {
  $r->print(   $r->print(
         '<font color="red">No write permission to user directory, FAIL</font>');          '<font color="red">'.
    &mt('No write permission to user directory, FAIL').'</font>');
         return 0;          return 0;
     }      }
     print $logfile       print $logfile 
Line 1254  sub phasetwo { Line 1334  sub phasetwo {
     $metadatafields{'copyright'}=$ENV{'form.copyright'};      $metadatafields{'copyright'}=$ENV{'form.copyright'};
     $metadatafields{'customdistributionfile'}=      $metadatafields{'customdistributionfile'}=
                                  $ENV{'form.customdistributionfile'};                                   $ENV{'form.customdistributionfile'};
       $metadatafields{'obsolete'}=$ENV{'form.obsolete'};
       $metadatafields{'obsoletereplacement'}=
                           $ENV{'form.obsoletereplacement'};
     $metadatafields{'dependencies'}=$ENV{'form.dependencies'};      $metadatafields{'dependencies'}=$ENV{'form.dependencies'};
           
     my $allkeywords=$ENV{'form.addkey'};      my $allkeywords=$ENV{'form.addkey'};
Line 1273  sub phasetwo { Line 1356  sub phasetwo {
         my $mfh;          my $mfh;
         unless ($mfh=Apache::File->new('>'.$source.'.meta')) {          unless ($mfh=Apache::File->new('>'.$source.'.meta')) {
             return               return 
                 '<font color="red">Could not write metadata, FAIL</font>';                  '<font color="red">'.&mt('Could not write metadata, FAIL').
    '</font>';
         }          }
         foreach (sort keys %metadatafields) {          foreach (sort keys %metadatafields) {
             unless ($_=~/\./) {              unless ($_=~/\./) {
Line 1292  sub phasetwo { Line 1376  sub phasetwo {
                         .'</'.$tag.'>';                          .'</'.$tag.'>';
             }              }
         }          }
         $r->print('<p>Wrote Metadata</p>');          $r->print('<p>'.&mt('Wrote Metadata').'</p>');
         print $logfile "\nWrote metadata";          print $logfile "\nWrote metadata";
     }      }
           
Line 1303  sub phasetwo { Line 1387  sub phasetwo {
     unless ($metadatafields{'copyright'} eq 'priv') {      unless ($metadatafields{'copyright'} eq 'priv') {
         my ($error,$success) = &store_metadata(\%metadatafields);          my ($error,$success) = &store_metadata(\%metadatafields);
         if ($success) {          if ($success) {
             $r->print('<p>Synchronized SQL metadata database</p>');              $r->print('<p>'.&mt('Synchronized SQL metadata database').'</p>');
             print $logfile "\nSynchronized SQL metadata database";              print $logfile "\nSynchronized SQL metadata database";
         } else {          } else {
             $r->print($error);              $r->print($error);
             print $logfile "\n".$error;              print $logfile "\n".$error;
         }          }
     } else {      } else {
         $r->print('<p>Private Publication - did not synchronize database</p>');          $r->print('<p>'.
        &mt('Private Publication - did not synchronize database').'</p>');
         print $logfile "\nPrivate: Did not synchronize data into ".          print $logfile "\nPrivate: Did not synchronize data into ".
             "SQL metadata database";              "SQL metadata database";
     }      }
Line 1347  sub phasetwo { Line 1432  sub phasetwo {
                   
         if (copy($target,$copyfile)) {          if (copy($target,$copyfile)) {
     print $logfile "Copied old target to ".$copyfile."\n";      print $logfile "Copied old target to ".$copyfile."\n";
             $r->print('<p>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\">Failed to copy old target, $!, FAIL</font>";              return "<font color=\"red\">".&mt('Failed to copy old target').
    ", $!, ".&mt('FAIL')."</font>";
         }          }
                   
 # --------------------------------------------------------------- Copy Metadata  # --------------------------------------------------------------- Copy Metadata
Line 1359  sub phasetwo { Line 1445  sub phasetwo {
                   
         if (copy($target.'.meta',$copyfile)) {          if (copy($target.'.meta',$copyfile)) {
     print $logfile "Copied old target metadata to ".$copyfile."\n";      print $logfile "Copied old target metadata to ".$copyfile."\n";
             $r->print('<p>Copied old metadata</p>')              $r->print('<p>'.&mt('Copied old metadata').'</p>')
         } 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                   return 
                     "<font color=\"red\">Failed to write old metadata copy, $!, FAIL</font>";                      "<font color=\"red\">".
   &mt('Failed to write old metadata copy').", $!, ".&mt('FAIL')."</font>";
     }      }
         }          }
                   
                   
     } else {      } else {
         $r->print('<p>Initial version</p>');          $r->print('<p>'.&mt('Initial version').'</p>');
         print $logfile "\nInitial version";          print $logfile "\nInitial version";
     }      }
   
Line 1385  sub phasetwo { Line 1472  sub phasetwo {
         $path.="/$parts[$count]";          $path.="/$parts[$count]";
         if ((-e $path)!=1) {          if ((-e $path)!=1) {
             print $logfile "\nCreating directory ".$path;              print $logfile "\nCreating directory ".$path;
             $r->print('<p>Created directory '.$parts[$count].'</p>');              $r->print('<p>'.&mt('Created directory').' '.$parts[$count].'</p>');
             mkdir($path,0777);              mkdir($path,0777);
         }          }
     }      }
           
     if (copy($source,$copyfile)) {      if (copy($source,$copyfile)) {
         print $logfile "\nCopied original source to ".$copyfile."\n";          print $logfile "\nCopied original source to ".$copyfile."\n";
         $r->print('<p>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\">Failed to copy source, $!, FAIL</font>";          return "<font color=\"red\">".
       &mt('Failed to copy source').", $!, ".&mt('FAIL')."</font>";
     }      }
           
 # --------------------------------------------------------------- Copy Metadata  # --------------------------------------------------------------- Copy Metadata
Line 1404  sub phasetwo { Line 1492  sub phasetwo {
           
     if (copy($source.'.meta',$copyfile)) {      if (copy($source.'.meta',$copyfile)) {
         print $logfile "\nCopied original metadata to ".$copyfile."\n";          print $logfile "\nCopied original metadata to ".$copyfile."\n";
         $r->print('<p>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           return 
             "<font color=\"red\">Failed to write metadata copy, $!, FAIL</font>";              "<font color=\"red\">".&mt('Failed to write metadata copy').", $!, ".&mt('FAIL')."</font>";
     }      }
     $r->rflush;      $r->rflush;
 # --------------------------------------------------- Send update notifications  # --------------------------------------------------- Send update notifications
   
     my @subscribed=&get_subscribed_hosts($target);      my @subscribed=&get_subscribed_hosts($target);
     foreach my $subhost (@subscribed) {      foreach my $subhost (@subscribed) {
  $r->print('<p>Notifying host '.$subhost.':');$r->rflush;   $r->print('<p>'.&mt('Notifying host').' '.$subhost.':');$r->rflush;
  print $logfile "\nNotifying host ".$subhost.':';   print $logfile "\nNotifying host ".$subhost.':';
  my $reply=&Apache::lonnet::critical('update:'.$target,$subhost);   my $reply=&Apache::lonnet::critical('update:'.$target,$subhost);
  $r->print($reply.'</p><br />');$r->rflush;   $r->print($reply.'</p><br />');$r->rflush;
Line 1426  sub phasetwo { Line 1514  sub phasetwo {
   
     my @subscribedmeta=&get_subscribed_hosts("$target.meta");      my @subscribedmeta=&get_subscribed_hosts("$target.meta");
     foreach my $subhost (@subscribedmeta) {      foreach my $subhost (@subscribedmeta) {
  $r->print('<p>Notifying host for metadata only '.$subhost.':');$r->rflush;   $r->print('<p>'.
   &mt('Notifying host for metadata only').' '.$subhost.':');$r->rflush;
  print $logfile "\nNotifying host for metadata only ".$subhost.':';   print $logfile "\nNotifying host for metadata only ".$subhost.':';
  my $reply=&Apache::lonnet::critical('update:'.$target.'.meta',   my $reply=&Apache::lonnet::critical('update:'.$target.'.meta',
     $subhost);      $subhost);
Line 1438  sub phasetwo { Line 1527  sub phasetwo {
     my %courses=&coursedependencies($target);      my %courses=&coursedependencies($target);
     my $now=time;      my $now=time;
     foreach (keys %courses) {      foreach (keys %courses) {
  $r->print('<p>Notifying course '.$_.':');$r->rflush;   $r->print('<p>'.&mt('Notifying course').' '.$_.':');$r->rflush;
  print $logfile "\nNotifying host ".$_.':';   print $logfile "\nNotifying host ".$_.':';
         my ($cdom,$cname)=split(/\_/,$_);          my ($cdom,$cname)=split(/\_/,$_);
  my $reply=&Apache::lonnet::cput   my $reply=&Apache::lonnet::cput
Line 1460  sub phasetwo { Line 1549  sub phasetwo {
                   
         $r->print(          $r->print(
            '<hr /><a href="'.$thisdistarget.'"><font size="+2">'.             '<hr /><a href="'.$thisdistarget.'"><font size="+2">'.
            'View Published Version</font></a>'.             &mt('View Published Version').'</font></a>'.
            '<p><a href="'.$thissrc.'"><font size=+2>Back to Source</font></a></p>'.             '<p><a href="'.$thissrc.'"><font size=+2>'.
     &mt('Back to Source').'</font></a></p>'.
            '<p><a href="'.$thissrcdir.             '<p><a href="'.$thissrcdir.
                    '"><font size="+2">Back to Source Directory</font></a></p>');                     '"><font size="+2">'.
     &mt('Back to Source Directory').'</font></a></p>');
     }      }
 }  }
   
Line 1471  sub phasetwo { Line 1562  sub phasetwo {
   
 sub batchpublish {  sub batchpublish {
     my ($r,$srcfile,$targetfile)=@_;      my ($r,$srcfile,$targetfile)=@_;
       #publication pollutes %ENV with form.* values
       my %oldENV=%ENV;
     $srcfile=~s/\/+/\//g;      $srcfile=~s/\/+/\//g;
     $targetfile=~s/\/+/\//g;      $targetfile=~s/\/+/\//g;
     my $thisdisfn=$srcfile;      my $thisdisfn=$srcfile;
Line 1482  sub batchpublish { Line 1575  sub batchpublish {
     $thisdistarget=~s/^\Q$docroot\E//;      $thisdistarget=~s/^\Q$docroot\E//;
   
   
     undef %metadatafields;      %metadatafields=();
     undef %metadatakeys;      %metadatakeys=();
      %metadatafields=();      $srcfile=~/\.(\w+)$/;
      %metadatakeys=();      my $thistype=$1;
       $srcfile=~/\.(\w+)$/;  
       my $thistype=$1;  
   
   
       my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);      my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);
             
     $r->print('<h2>Publishing <tt>'.$thisdisfn.'</tt></h2>');      $r->print('<h2>'.&mt('Publishing').' <tt>'.$thisdisfn.'</tt></h2>');
   
 # phase one takes  # phase one takes
 #  my ($source,$target,$style,$batch)=@_;  #  my ($source,$target,$style,$batch)=@_;
Line 1506  sub batchpublish { Line 1597  sub batchpublish {
  &phasetwo($r,$srcfile,$targetfile,$thisembstyle,$thisdistarget,1);   &phasetwo($r,$srcfile,$targetfile,$thisembstyle,$thisdistarget,1);
  $r->print('</p>');   $r->print('</p>');
     }      }
       %ENV=%oldENV;
     return '';      return '';
 }  }
   
Line 1516  sub publishdirectory { Line 1608  sub publishdirectory {
     $fn=~s/\/+/\//g;      $fn=~s/\/+/\//g;
     $thisdisfn=~s/\/+/\//g;      $thisdisfn=~s/\/+/\//g;
     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>Directory <tt>'.$thisdisfn.'</tt></h1>'.
                 'Target: <tt>'.$resdir.'</tt><br />');        '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.
   
       opendir(DIR,$fn);      opendir(DIR,$fn);
       my @files=sort(readdir(DIR));      my @files=sort(readdir(DIR));
       foreach my $filename (@files) {      foreach my $filename (@files) {
          my ($cdev,$cino,$cmode,$cnlink,   my ($cdev,$cino,$cmode,$cnlink,
             $cuid,$cgid,$crdev,$csize,              $cuid,$cgid,$crdev,$csize,
             $catime,$cmtime,$cctime,              $catime,$cmtime,$cctime,
             $cblksize,$cblocks)=stat($fn.'/'.$filename);              $cblksize,$cblocks)=stat($fn.'/'.$filename);
   
          my $extension='';   my $extension='';
          if ($filename=~/\.(\w+)$/) { $extension=$1; }   if ($filename=~/\.(\w+)$/) { $extension=$1; }
          if ($cmode&$dirptr) {   if ($cmode&$dirptr) {
    if (($filename!~/^\./) && ($ENV{'form.pubrec'})) {      if (($filename!~/^\./) && ($ENV{'form.pubrec'})) {
       &publishdirectory($r,$fn.'/'.$filename,$thisdisfn.'/'.$filename);   &publishdirectory($r,$fn.'/'.$filename,$thisdisfn.'/'.$filename);
    }      }
          } elsif ((&Apache::loncommon::fileembstyle($extension) ne 'hdn') &&   } elsif ((&Apache::loncommon::fileembstyle($extension) ne 'hdn') &&
                   ($filename!~/^[\#\.]/) && ($filename!~/\~$/)) {   ($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 {      } else {
 # never published  # never published
  $publishthis=1;   $publishthis=1;
      }      }
              if ($publishthis) {      if ($publishthis) {
                 &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename);                  &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename);
      } else {      } else {
                  $r->print('<br />Skipping '.$filename.'<br />');   $r->print('<br />Skipping '.$filename.'<br />');
              }      }
              $r->rflush();      $r->rflush();
          }   }
       }      }
       closedir(DIR);      closedir(DIR);
 }  }
 #########################################  #########################################
   
Line 1605  Publishing from $thisfn to $thistarget w Line 1697  Publishing from $thisfn to $thistarget w
 #########################################  #########################################
 #########################################  #########################################
 sub handler {  sub handler {
   my $r=shift;      my $r=shift;
   
   if ($r->header_only) {      if ($r->header_only) {
      $r->content_type('text/html');   &Apache::loncommon::content_type($r,'text/html');
      $r->send_http_header;   $r->send_http_header;
      return OK;   return OK;
   }      }
   
 # Get query string for limited number of parameters  # Get query string for limited number of parameters
   
Line 1620  sub handler { Line 1712  sub handler {
   
 # -------------------------------------------------------------- Check filename  # -------------------------------------------------------------- Check filename
   
   my $fn=&Apache::lonnet::unescape($ENV{'form.filename'});      my $fn=&Apache::lonnet::unescape($ENV{'form.filename'});
   
       
   unless ($fn) {       unless ($fn) { 
      $r->log_reason($cuname.' at '.$cudom.   $r->log_reason($cuname.' at '.$cudom.
          ' trying to publish empty filename', $r->filename);          ' trying to publish empty filename', $r->filename); 
      return HTTP_NOT_FOUND;   return HTTP_NOT_FOUND;
   }       } 
   
   ($cuname,$cudom)=      ($cuname,$cudom)=
     &Apache::loncacc::constructaccess($fn,$r->dir_config('lonDefDomain'));   &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;
      $r->log_reason($cuname.' at '.$cudom.      my @ids=&Apache::lonnet::current_machine_ids();
          ' trying to publish file '.$ENV{'form.filename'}.      foreach my $id (@ids) { if ($id eq $home) { $allowed = 1; }  }
          ' ('.$fn.') - not homeserver ('.      unless ($allowed) {
          &Apache::lonnet::homeserver($cuname,$cudom).')',    $r->log_reason($cuname.' at '.$cudom.
          $r->filename);          ' trying to publish file '.$ENV{'form.filename'}.
      return HTTP_NOT_ACCEPTABLE;         ' ('.$fn.') - not homeserver ('.$home.')', 
   }         $r->filename); 
    return HTTP_NOT_ACCEPTABLE;
   $fn=~s/^http\:\/\/[^\/]+//;      }
   $fn=~s/^\/\~(\w+)/\/home\/$1\/public_html/;  
       $fn=~s/^http\:\/\/[^\/]+//;
   my $targetdir='';      $fn=~s/^\/\~(\w+)/\/home\/$1\/public_html/;
   $docroot=$r->dir_config('lonDocRoot');   
   if ($1 ne $cuname) {      my $targetdir='';
      $r->log_reason($cuname.' at '.$cudom.      $docroot=$r->dir_config('lonDocRoot'); 
          ' trying to publish unowned file '.$ENV{'form.filename'}.      if ($1 ne $cuname) {
          ' ('.$fn.')',    $r->log_reason($cuname.' at '.$cudom.
          $r->filename);          ' trying to publish unowned file '.
      return HTTP_NOT_ACCEPTABLE;         $ENV{'form.filename'}.' ('.$fn.')', 
   } else {         $r->filename); 
       $targetdir=$docroot.'/res/'.$cudom;   return HTTP_NOT_ACCEPTABLE;
   }      } else {
    $targetdir=$docroot.'/res/'.$cudom;
       }
                                                                     
       
   unless (-e $fn) {       unless (-e $fn) { 
      $r->log_reason($cuname.' at '.$cudom.   $r->log_reason($cuname.' at '.$cudom.
          ' trying to publish non-existing file '.$ENV{'form.filename'}.         ' trying to publish non-existing file '.
          ' ('.$fn.')',          $ENV{'form.filename'}.' ('.$fn.')', 
          $r->filename);          $r->filename); 
      return HTTP_NOT_FOUND;   return HTTP_NOT_FOUND;
   }       } 
   
 unless ($ENV{'form.phase'} eq 'two') {      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=();  
   
   {  
      my $fh=Apache::File->new($r->dir_config('lonIncludes').'/un_keyword.tab');  
       while (<$fh>) {  
           my $word=$_;  
           chomp($word);  
           $nokey{$word}=1;  
       }  
   }  
   
 }   %nokey=();
   
    {
       my $fh=Apache::File->new($r->dir_config('lonIncludes').'/un_keyword.tab');
       while (<$fh>) {
    my $word=$_;
    chomp($word);
    $nokey{$word}=1;
       }
    }
   
       }
   
 # ---------------------------------------------------------- Start page output.  # ---------------------------------------------------------- Start page output.
   
   $r->content_type('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>');      $r->print('<html><head><title>LON-CAPA Publishing</title></head>');
   $r->print(&Apache::loncommon::bodytag('Resource Publication'));      $r->print(&Apache::loncommon::bodytag('Resource Publication'));
   
   
   my $thisfn=$fn;      my $thisfn=$fn;
   
   my $thistarget=$thisfn;      my $thistarget=$thisfn;
               
   $thistarget=~s/^\/home/$targetdir/;      $thistarget=~s/^\/home/$targetdir/;
   $thistarget=~s/\/public\_html//;      $thistarget=~s/\/public\_html//;
   
   my $thisdistarget=$thistarget;      my $thisdistarget=$thistarget;
   $thisdistarget=~s/^\Q$docroot\E//;      $thisdistarget=~s/^\Q$docroot\E//;
   
   my $thisdisfn=$thisfn;      my $thisdisfn=$thisfn;
   $thisdisfn=~s/^\/home\/\Q$cuname\E\/public_html\///;      $thisdisfn=~s/^\/home\/\Q$cuname\E\/public_html\///;
   
   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/'
     .$cuname.'/'.$thisdisfn
     .'">'.&mt('Return to Directory').'</a>');
   
   } else {  
       } else {
 # ---------------------- Evaluate individual file, and then output information.  # ---------------------- Evaluate individual file, and then output information.
       $thisfn=~/\.(\w+)$/;   $thisfn=~/\.(\w+)$/;
       my $thistype=$1;   my $thistype=$1;
       my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);   my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);
    $r->print('<h2>'.&mt('Publishing').' '.
       $r->print('<h2>Publishing '.    &Apache::loncommon::filedescription($thistype).' <tt>');
         &Apache::loncommon::filedescription($thistype).' <tt>'.  
         '<a href="/~'.$cuname.'/'.$thisdisfn.'" target="cat">'.$thisdisfn.   $r->print(<<ENDCAPTION);
         '</a></tt></h2><b>Target:</b> <tt>'.$thisdistarget.'</tt><br />');  <a href='javascript:void(window.open("/~$cuname/$thisdisfn","cat","height=300,width=500,scrollbars=1,resizable=1,menubar=0,location=1"))'>
   $thisdisfn</a>
   ENDCAPTION
           $r->print('</tt></h2><b>'.&mt('Target').':</b> <tt>'.
     $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">Co-Author: '.$cuname.' at '.$cudom.      $r->print('<h3><font color="red">'.&mt('Co-Author').': '.
     '</font></h3>');        $cuname.&mt(' at ').$cudom.'</font></h3>');
       }   }
   
       if (&Apache::loncommon::fileembstyle($thistype) eq 'ssi') {   if (&Apache::loncommon::fileembstyle($thistype) eq 'ssi') {
           $r->print('<br /><a href="/adm/diff?filename=/~'.$cuname.'/'.      $r->print(<<ENDDIFF);
                     $thisdisfn.  <br />
    '&versiontwo=priv" target="cat">Diffs with Current Version</a><br />');  <a href='javascript:void(window.open("/adm/diff?filename=/~$cuname/$thisdisfn&versiontwo=priv","cat","height=300,width=500,scrollbars=1,resizable=1,menubar=0,location=1"))'>
       }  ENDDIFF
               $r->print(&mt('Diffs with Current Version').'</a><br />');
    }
       
 # ------------------ 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);      my ($outstring,$error)=&publish($thisfn,$thistarget,$thisembstyle);
    $r->print('<hr />'.$outstring);      $r->print('<hr />'.$outstring);
        } else {   } else {
            $r->print('<hr />');      $r->print('<hr />');
            &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget);       &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget); 
        }   }
   }      }
   $r->print('</body></html>');      $r->print('</body></html>');
   
   return OK;      return OK;
 }  }
   
 1;  1;

Removed from v.1.126  
changed lines
  Added in v.1.145.2.1.2.1


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>