Diff for /loncom/publisher/lonpublisher.pm between versions 1.89 and 1.99

version 1.89, 2002/08/09 17:57:48 version 1.99, 2002/10/07 13:50:36
Line 61 Line 61
 ##                                                                           ##  ##                                                                           ##
 ###############################################################################  ###############################################################################
   
   
   ######################################################################
   ######################################################################
   
   =pod 
   
   =head1 NAME
   
   lonpublisher - LON-CAPA publishing handler
   
   =head1 SYNOPSIS
   
   B<lonpublisher> is used by B<mod_perl> inside B<Apache>.  This is the
   invocation by F<loncapa_apache.conf>:
   
     <Location /adm/publish>
     PerlAccessHandler       Apache::lonacc
     SetHandler perl-script
     PerlHandler Apache::lonpublisher
     ErrorDocument     403 /adm/login
     ErrorDocument     404 /adm/notfound.html
     ErrorDocument     406 /adm/unauthorized.html
     ErrorDocument     500 /adm/errorhandler
     </Location>
   
   =head1 DESCRIPTION
   
   B<lonpublisher> takes the proper steps to add resources to the LON-CAPA
   digital library.  This includes updating the metadata table in the
   LON-CAPA database.
   
   B<lonpublisher> is many things to many people.  
   
   This module publishes a file.  This involves gathering metadata,
   versioning the file, copying file from construction space to
   publication space, and copying metadata from construction space
   to publication space.
   
   =head2 SUBROUTINES
   
   Many of the undocumented subroutines implement various magical
   parsing shortcuts.
   
   =over 4
   
   =cut
   
   ######################################################################
   ######################################################################
   
   
 package Apache::lonpublisher;  package Apache::lonpublisher;
   
 # ------------------------------------------------- modules used by this module  # ------------------------------------------------- modules used by this module
Line 88  my $docroot; Line 139  my $docroot;
 my $cuname;  my $cuname;
 my $cudom;  my $cudom;
   
 # ----------------------------------------------- Evaluate string with metadata  #########################################
   #########################################
   
   =pod
   
   =item B<metaeval>
   
   Evaluates a string that contains metadata.  This subroutine
   stores values inside I<%metadatafields> and I<%metadatakeys>.
   The hash key is a I<$unikey> corresponding to a unique id
   that is descriptive of the parser location inside the XML tree.
   
   Parameters:
   
   =over 4
   
   =item I<$metastring>
   
   A string that contains metadata.
   
   =back
   
   Returns:
   
   nothing
   
   =cut
   
   #########################################
   #########################################
 sub metaeval {  sub metaeval {
     my $metastring=shift;      my $metastring=shift;
         
Line 131  sub metaeval { Line 211  sub metaeval {
        }         }
 }  }
   
 # -------------------------------------------------------- Read a metadata file  #########################################
   #########################################
   
   =pod
   
   =item B<metaread>
   
   Read a metadata file
   
   Parameters:
   
   =over
   
   =item I<$logfile>
   
   File output stream to output errors and warnings to.
   
   =item I<$fn>
   
   File name (including path).
   
   =back
   
   Returns:
   
   =over 4
   
   =item Scalar string (if successful)
   
   XHTML text that indicates successful reading of the metadata.
   
   =back
   
   =cut
   
   #########################################
   #########################################
 sub metaread {  sub metaread {
     my ($logfile,$fn)=@_;      my ($logfile,$fn)=@_;
     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>'.$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);
Line 148  sub metaread { Line 264  sub metaread {
     return '<br><b>Processed file:</b> <tt>'.$fn.'</tt>';      return '<br><b>Processed file:</b> <tt>'.$fn.'</tt>';
 }  }
   
 # ---------------------------- convert 'time' format into a datetime sql format  #########################################
   #########################################
   
   =pod
   
   =item B<sqltime>
   
   Convert 'time' format into a datetime sql format
   
   Parameters:
   
   =over 4
   
   =item I<$timef>
   
   Seconds since 00:00:00 UTC, January 1, 1970.
   
   =back
   
   Returns:
   
   =over 4
   
   =item Scalar string
   
   MySQL-compatible datetime string.
   
   =back
   
   =cut
   
   #########################################
   #########################################
 sub sqltime {  sub sqltime {
     my $timef=shift @_;      my $timef=shift @_;
     my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =      my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
Line 157  sub sqltime { Line 305  sub sqltime {
     return "$year-$mon-$mday $hour:$min:$sec";      return "$year-$mon-$mday $hour:$min:$sec";
 }  }
   
 # --------------------------------------------------------- Various form fields  
   
   #########################################
   #########################################
   
   =pod
   
   =item Form-field-generating subroutines.
   
   For input parameters, these subroutines take in values
   such as I<$name>, I<$value> and other form field metadata.
   The output (scalar string that is returned) is an XHTML
   string which presents the form field (foreseeably inside
   <form></form> tags).
   
   =over 4
   
   =item B<textfield>
   
   =item B<hiddenfield>
   
   =item B<selectbox>
   
   =back
   
   =cut
   
   #########################################
   #########################################
 sub textfield {  sub textfield {
     my ($title,$name,$value)=@_;      my ($title,$name,$value)=@_;
     return "\n<p><b>$title:</b><br>".      return "\n<p><b>$title:</b><br>".
            '<input type=text name="'.$name.'" size=80 value="'.$value.'">';             '<input type="text" name="'.$name.'" size=80 value="'.$value.'" />';
 }  }
   
 sub hiddenfield {  sub hiddenfield {
     my ($name,$value)=@_;      my ($name,$value)=@_;
     return "\n".'<input type=hidden name="'.$name.'" value="'.$value.'">';      return "\n".'<input type="hidden" name="'.$name.'" value="'.$value.'" />';
 }  }
   
 sub selectbox {  sub selectbox {
Line 185  sub selectbox { Line 359  sub selectbox {
     return $selout.'</select>';      return $selout.'</select>';
 }  }
   
 # -------------------------------------------------------- Publication Step One  #########################################
   #########################################
   
   =pod
   
   =item B<urlfixup>
   
   Fix up a url?  First step of publication
   
   =cut
   
   #########################################
   #########################################
 sub urlfixup {  sub urlfixup {
     my ($url,$target)=@_;      my ($url,$target)=@_;
     unless ($url) { return ''; }      unless ($url) { return ''; }
Line 207  sub urlfixup { Line 392  sub urlfixup {
     return $url;      return $url;
 }  }
   
   #########################################
   #########################################
   
   =pod
   
   =item B<absoluteurl>
   
   Currently undocumented.
   
   =cut
   
   #########################################
   #########################################
 sub absoluteurl {  sub absoluteurl {
     my ($url,$target)=@_;      my ($url,$target)=@_;
     unless ($url) { return ''; }      unless ($url) { return ''; }
Line 218  sub absoluteurl { Line 415  sub absoluteurl {
     return $url;      return $url;
 }  }
   
   #########################################
   #########################################
   
   =pod
   
   =item B<set_allow>
   
   Currently undocumented    
   
   =cut
   
   #########################################
   #########################################
 sub set_allow {  sub set_allow {
     my ($allow,$logfile,$target,$tag,$oldurl)=@_;      my ($allow,$logfile,$target,$tag,$oldurl)=@_;
     my $newurl=&urlfixup($oldurl,$target);      my $newurl=&urlfixup($oldurl,$target);
Line 236  sub set_allow { Line 446  sub set_allow {
     return $return_url      return $return_url
 }  }
   
   #########################################
   #########################################
   
   =pod
   
   =item B<get_subscribed_hosts>
   
   Currently undocumented    
   
   =cut
   
   #########################################
   #########################################
 sub get_subscribed_hosts {  sub get_subscribed_hosts {
     my ($target)=@_;      my ($target)=@_;
     my @subscribed;      my @subscribed;
Line 246  sub get_subscribed_hosts { Line 469  sub get_subscribed_hosts {
     while ($filename=readdir(DIR)) {      while ($filename=readdir(DIR)) {
  if ($filename=~/$srcf\.(\w+)$/) {   if ($filename=~/$srcf\.(\w+)$/) {
     my $subhost=$1;      my $subhost=$1;
     if ($subhost ne 'meta' && $subhost ne 'subscription') {      if (($subhost ne 'meta' && $subhost ne 'subscription') &&
                   ($subhost ne $Apache::lonnet::perlvar{'lonHostID'})) {
  push(@subscribed,$subhost);   push(@subscribed,$subhost);
     }      }
  }   }
Line 257  sub get_subscribed_hosts { Line 481  sub get_subscribed_hosts {
  &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");      &Apache::lonnet::logthis("Trying $subline");
     if ($subline =~ /(^\w+):/) { push(@subscribed,$1); } else {      if ($subline =~ /(^\w+):/) { 
                   if ($1 ne $Apache::lonnet::perlvar{'lonHostID'}) { 
                      push(@subscribed,$1);
           }
               } else {
  &Apache::lonnet::logthis("No Match for $subline");   &Apache::lonnet::logthis("No Match for $subline");
     }      }
  }   }
     } else {      } else {
  &Apache::lonnet::logthis("Un able to open $target.subscription");   &Apache::lonnet::logthis("Unable to open $target.subscription");
     }      }
     &Apache::lonnet::logthis("Got list of ".join(':',@subscribed));      &Apache::lonnet::logthis("Got list of ".join(':',@subscribed));
     return @subscribed;      return @subscribed;
 }  }
   
   
   #########################################
   #########################################
   
   =pod
   
   =item B<get_max_ids_indices>
   
   Currently undocumented    
   
   =cut
   
   #########################################
   #########################################
 sub get_max_ids_indices {  sub get_max_ids_indices {
     my ($content)=@_;      my ($content)=@_;
     my $maxindex=10;      my $maxindex=10;
Line 300  sub get_max_ids_indices { Line 541  sub get_max_ids_indices {
     return ($needsfixup,$maxid,$maxindex);      return ($needsfixup,$maxid,$maxindex);
 }  }
   
   #########################################
   #########################################
   
   =pod
   
   =item B<get_all_text_unbalanced>
   
   Currently undocumented    
   
   =cut
   
   #########################################
   #########################################
 sub get_all_text_unbalanced {  sub get_all_text_unbalanced {
     #there is a copy of this in lonxml.pm      #there is a copy of this in lonxml.pm
     my($tag,$pars)= @_;      my($tag,$pars)= @_;
Line 329  sub get_all_text_unbalanced { Line 583  sub get_all_text_unbalanced {
     return $result      return $result
 }  }
   
   #########################################
   #########################################
   
   =pod
   
   =item B<fix_ids_and_indices>
   
   Currently undocumented    
   
   =cut
   
   #########################################
   #########################################
 #Arguably this should all be done as a lonnet::ssi instead  #Arguably this should all be done as a lonnet::ssi instead
 sub fix_ids_and_indices {  sub fix_ids_and_indices {
     my ($logfile,$source,$target)=@_;      my ($logfile,$source,$target)=@_;
Line 473  sub fix_ids_and_indices { Line 740  sub fix_ids_and_indices {
   
 =pod  =pod
   
 =item store_metadata  =item B<store_metadata>
   
 Store the metadata in the metadata table in the loncapa database.  Store the metadata in the metadata table in the loncapa database.
 Uses lonmysql to access the database.  Uses lonmysql to access the database.
Line 524  sub store_metadata { Line 791  sub store_metadata {
     return (undef,$status);      return (undef,$status);
 }  }
   
   #########################################
   #########################################
   
   =pod
   
   =item B<publish>
   
   This is the workhorse function of this module.  This subroutine generates
   backup copies, performs any automatic processing (prior to publication,
   especially for rat and ssi files),
   
   I<Additional documentation needed.>
   
   =cut
   
   #########################################
   #########################################
 sub publish {  sub publish {
   
     my ($source,$target,$style)=@_;      my ($source,$target,$style,$batch)=@_;
     my $logfile;      my $logfile;
     my $scrout='';      my $scrout='';
     my $allmeta='';      my $allmeta='';
Line 575  sub publish { Line 859  sub publish {
                if (                 if (
        &Apache::lonnet::getfile($Apache::lonnet::perlvar{'lonDocRoot'}.'/'.         &Apache::lonnet::getfile($Apache::lonnet::perlvar{'lonDocRoot'}.'/'.
                                             $thisdep.'.meta') eq '-1') {                                              $thisdep.'.meta') eq '-1') {
    $scrout.=     $scrout.= ' - <font color="red">Currently not available'.
                            ' - <font color=red>Currently not available</font>';         '</font>';
                } else {                 } else {
                    my %temphash=(&Apache::lonnet::declutter($target).'___'.                     my %temphash=(&Apache::lonnet::declutter($target).'___'.
                              &Apache::lonnet::declutter($thisdep).'___usage'                               &Apache::lonnet::declutter($thisdep).'___usage'
                                  => time);                                   => time);
                    $thisdep=~/^\/res\/(\w+)\/(\w+)\//;                     $thisdep=~/^\/res\/(\w+)\/(\w+)\//;
                    if ((defined($1)) && (defined($2))) {                     if ((defined($1)) && (defined($2))) {
                       &Apache::lonnet::put('resevaldata',\%temphash,$1,$2);                        &Apache::lonnet::put('nohist_resevaldata',\%temphash,
      $1,$2);
    }     }
        }         }
            }             }
Line 592  sub publish { Line 877  sub publish {
   
  #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                return 
               "<font color=red>No write permission to $source, FAIL</font>";   '<font color="red">No write permission to '.$source.
    ', FAIL</font>';
   }    }
           print $org $outstring;            print($org $outstring);
         }          }
   $content=$outstring;    $content=$outstring;
   
     }      }
 # --------------------------------------------- Initial step done, now metadata  # -------------------------------------------- Initial step done, now metadata.
   
 # ---------------------------------------- Storage for metadata keys and fields  # --------------------------------------- Storage for metadata keys and fields.
   
      %metadatafields=();       %metadatafields=();
      %metadatakeys=();       %metadatakeys=();
             
      my %oldparmstores=();       my %oldparmstores=();
             
            unless ($batch) {
      $scrout.='<h3>Metadata Information ' .       $scrout.='<h3>Metadata Information ' .
        Apache::loncommon::help_open_topic("Metadata_Description")         Apache::loncommon::help_open_topic("Metadata_Description")
        . '</h3>';         . '</h3>';
       }
   
 # ------------------------------------------------ First, check out environment  # ------------------------------------------------ First, check out environment
      unless (-e $source.'.meta') {       unless (-e $source.'.meta') {
Line 712  sub publish { Line 999  sub publish {
   
 # ------------------------------------------------------- Now have all metadata  # ------------------------------------------------------- Now have all metadata
   
           my %keywords=();
           
    if (length($content)<500000) {
       my $textonly=$content;
               $textonly=~s/\<script[^\<]+\<\/script\>//g;
               $textonly=~s/\<m\>[^\<]+\<\/m\>//g;
               $textonly=~s/\<[^\>]*\>//g;
               $textonly=~tr/A-Z/a-z/;
               $textonly=~s/[\$\&][a-z]\w*//g;
               $textonly=~s/[^a-z\s]//g;
   
               foreach ($textonly=~m/(\w+)/g) {
    unless ($nokey{$_}) {
                      $keywords{$_}=1;
                   } 
               }
           }
   
               
               foreach (split(/\W+/,$metadatafields{'keywords'})) {
    $keywords{$_}=1;
               }
   # --------------------------------------------------- Now we also have keywords
   # =============================================================================
   # INTERACTIVE MODE
   #
      unless ($batch) {
         $scrout.=          $scrout.=
      '<form name="pubform" action="/adm/publish" method="post">'.       '<form name="pubform" action="/adm/publish" method="post">'.
        '<p><input type="submit" value="Finalize Publication" /></p>'.         '<p><input type="submit" value="Finalize Publication" /></p>'.
Line 747  function uncheckAll(field) Line 1061  function uncheckAll(field)
 END  END
         $keywordout.='<table border=2><tr>';          $keywordout.='<table border=2><tr>';
         my $colcount=0;          my $colcount=0;
         my %keywords=();  
           
  if (length($content)<500000) {  
     my $textonly=$content;  
             $textonly=~s/\<script[^\<]+\<\/script\>//g;  
             $textonly=~s/\<m\>[^\<]+\<\/m\>//g;  
             $textonly=~s/\<[^\>]*\>//g;  
             $textonly=~tr/A-Z/a-z/;  
             $textonly=~s/[\$\&][a-z]\w*//g;  
             $textonly=~s/[^a-z\s]//g;  
   
             foreach ($textonly=~m/(\w+)/g) {  
  unless ($nokey{$_}) {  
                    $keywords{$_}=1;  
                 }   
             }  
         }  
   
               
             foreach (split(/\W+/,$metadatafields{'keywords'})) {  
  $keywords{$_}=1;  
             }  
   
             foreach (sort keys %keywords) {              foreach (sort keys %keywords) {
                 $keywordout.='<td><input type=checkbox name="keywords" value="'.$_.'"';                  $keywordout.='<td><input type=checkbox name="keywords" value="'.$_.'"';
Line 819  END Line 1111  END
         
  $scrout.=&textfield('Publisher/Owner','owner',   $scrout.=&textfield('Publisher/Owner','owner',
                             $metadatafields{'owner'});                              $metadatafields{'owner'});
 # --------------------------------------------------- Correct copyright for rat          
   
   # -------------------------------------------------- Correct copyright for rat.
     if ($style eq 'rat') {      if ($style eq 'rat') {
  if ($metadatafields{'copyright'} eq 'public') {    if ($metadatafields{'copyright'} eq 'public') { 
     delete $metadatafields{'copyright'};      delete $metadatafields{'copyright'};
Line 837  END Line 1129  END
      (&Apache::loncommon::copyrightids));       (&Apache::loncommon::copyrightids));
     }      }
   
     my $copyright_help = Apache::loncommon::help_open_topic("Publishing_Copyright");      my $copyright_help =
           Apache::loncommon::help_open_topic('Publishing_Copyright');
     $scrout =~ s/DISTRIBUTION:/'DISTRIBUTION: ' . $copyright_help/ge;      $scrout =~ s/DISTRIBUTION:/'DISTRIBUTION: ' . $copyright_help/ge;
     return $scrout.      return $scrout.
       '<p><input type="submit" value="Finalize Publication" /></p></form>';          '<p><input type="submit" value="Finalize Publication" /></p></form>';
   # =============================================================================
   # BATCH MODE
   #
     } else {
   # Transfer metadata directly to environment for stage 2
       foreach (keys %metadatafields) {
    $ENV{'form.'.$_}=$metadatafields{$_};
       }
       $ENV{'form.addkey'}='';
       $ENV{'form.keywords'}='';
       foreach (keys %keywords) {
           if ($metadatafields{'keywords'}) {
              if ($metadatafields{'keywords'}=~/$_/) { 
                 $ENV{'form.keywords'}.=$_.','; 
              }
    } elsif (&Apache::loncommon::keyword($_)) {
       $ENV{'form.keywords'}.=$_.',';
           } 
       }
       $ENV{'form.keywords'}=~s/\,$//;
       unless ($ENV{'form.creationdate'}) { $ENV{'form.creationdate'}=time; }
       $ENV{'form.lastrevisiondate'}=time;
       if ((($style eq 'rat') && ($ENV{'form.copyright'} eq 'public')) ||
           (!$ENV{'form.copyright'})) { 
    $ENV{'form.copyright'}='default';
       } 
       $ENV{'form.allmeta'}=&Apache::lonnet::escape($allmeta);
       return $scrout;
     }
 }  }
   
 # -------------------------------------------------------- Publication Step Two  #########################################
   #########################################
   
   =pod 
   
   =item B<phasetwo>
   
   Render second interface showing status of publication steps.
   This is publication step two.
   
   Parameters:
   
   =over 4
   
   =item I<$source>
   
   =item I<$target>
   
   =item I<$style>
   
   =item I<$distarget>
   
   =back
   
   Returns:
   
   =over 4
   
   =item Scalar string
   
   String contains status (errors and warnings) and information associated with
   the server's attempts at publication.
   
   =cut
   
   #########################################
   #########################################
 sub phasetwo {  sub phasetwo {
   
     my ($source,$target,$style,$distarget)=@_;      my ($source,$target,$style,$distarget,$batch)=@_;
     my $logfile;      my $logfile;
     my $scrout='';      my $scrout='';
     unless ($logfile=Apache::File->new('>>'.$source.'.log')) {      unless ($logfile=Apache::File->new('>>'.$source.'.log')) {
Line 869  sub phasetwo { Line 1226  sub phasetwo {
      $metadatafields{'abstract'}=$ENV{'form.abstract'};       $metadatafields{'abstract'}=$ENV{'form.abstract'};
      $metadatafields{'mime'}=$ENV{'form.mime'};       $metadatafields{'mime'}=$ENV{'form.mime'};
      $metadatafields{'language'}=$ENV{'form.language'};       $metadatafields{'language'}=$ENV{'form.language'};
      $metadatafields{'creationdate'}=$ENV{'form.creationdate'};       $metadatafields{'creationdate'}=
      $metadatafields{'lastrevisiondate'}=$ENV{'form.lastrevisiondate'};           &sqltime($ENV{'form.creationdate'});
        $metadatafields{'lastrevisiondate'}=
            &sqltime($ENV{'form.lastrevisiondate'});
      $metadatafields{'owner'}=$ENV{'form.owner'};       $metadatafields{'owner'}=$ENV{'form.owner'};
      $metadatafields{'copyright'}=$ENV{'form.copyright'};       $metadatafields{'copyright'}=$ENV{'form.copyright'};
      $metadatafields{'dependencies'}=$ENV{'form.dependencies'};       $metadatafields{'dependencies'}=$ENV{'form.dependencies'};
   
      my $allkeywords=$ENV{'form.addkey'};       my $allkeywords=$ENV{'form.addkey'};
      if (exists($ENV{'form.keywords'}) && (ref($ENV{'form.keywords'}))) {       if (exists($ENV{'form.keywords'})) {
          my @Keywords = @{$ENV{'form.keywords'}};           if (ref($ENV{'form.keywords'})) {
          foreach (@Keywords) {               $allkeywords .= ','.join(',',@{$ENV{'form.keywords'}});
              $allkeywords.=','.$_;           } else {
                $allkeywords .= ','.$ENV{'form.keywords'};
          }           }
      }       }
      $allkeywords=~s/\W+/\,/;       $allkeywords=~s/\W+/\,/;
Line 920  sub phasetwo { Line 1280  sub phasetwo {
     $metadatafields{'version'} = 'current';      $metadatafields{'version'} = 'current';
     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) {
             $scrout.='<p>Synchronized SQL metadata database';              $scrout.='<p>Synchronized SQL metadata database';
             print $logfile "\nSynchronized SQL metadata database";              print $logfile "\nSynchronized SQL metadata database";
         } else {          } else {
Line 947  if (-e $target) { Line 1307  if (-e $target) {
     }      }
     opendir(DIR,$srcd);      opendir(DIR,$srcd);
     while ($filename=readdir(DIR)) {      while ($filename=readdir(DIR)) {
         if (-l $srcd.'/'.$filename) {
          unlink($srcd.'/'.$filename);
          unlink($srcd.'/'.$filename.'.meta');
         } else {
        if ($filename=~/$srcf\.(\d+)\.$srct$/) {         if ($filename=~/$srcf\.(\d+)\.$srct$/) {
    $maxversion=($1>$maxversion)?$1:$maxversion;     $maxversion=($1>$maxversion)?$1:$maxversion;
        }         }
         }
     }      }
     closedir(DIR);      closedir(DIR);
     $maxversion++;      $maxversion++;
Line 1004  if (-e $target) { Line 1369  if (-e $target) {
            }             }
   
         if (copy($source,$copyfile)) {          if (copy($source,$copyfile)) {
     print $logfile "Copied original source to ".$copyfile."\n";      print $logfile "\nCopied original source to ".$copyfile."\n";
             $scrout.='<p>Copied source file';              $scrout.='<p>Copied source file';
         } else {          } else {
     print $logfile "Unable 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>Failed to copy source, $!, FAIL</font>";
         }          }
   
Line 1016  if (-e $target) { Line 1381  if (-e $target) {
         $copyfile=$copyfile.'.meta';          $copyfile=$copyfile.'.meta';
   
         if (copy($source.'.meta',$copyfile)) {          if (copy($source.'.meta',$copyfile)) {
     print $logfile "Copied original metadata to ".$copyfile."\n";      print $logfile "\nCopied original metadata to ".$copyfile."\n";
             $scrout.='<p>Copied metadata';              $scrout.='<p>Copied metadata';
         } else {          } else {
     print $logfile "Unable 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>Failed to write metadata copy, $!, FAIL</font>";
         }          }
Line 1048  if (-e $target) { Line 1413  if (-e $target) {
     }      }
   
 # ------------------------------------------------ Provide link to new resource  # ------------------------------------------------ Provide link to new resource
     unless ($batch) {
     my $thisdistarget=$target;      my $thisdistarget=$target;
     $thisdistarget=~s/^$docroot//;      $thisdistarget=~s/^$docroot//;
   
Line 1060  if (-e $target) { Line 1425  if (-e $target) {
   
   
     return $warning.$scrout.      return $warning.$scrout.
       '<hr><a href="'.$thisdistarget.'"><font size=+2>View Published Version</font></a>'.        '<hr><a href="'.$thisdistarget.'"><font size="+2">'.
         'View Published Version</font></a>'.
       '<p><a href="'.$thissrc.'"><font size=+2>Back to Source</font></a>'.        '<p><a href="'.$thissrc.'"><font size=+2>Back to Source</font></a>'.
       '<p><a href="'.$thissrcdir.        '<p><a href="'.$thissrcdir.
       '"><font size=+2>Back to Source Directory</font></a>';        '"><font size="+2">Back to Source Directory</font></a>';
     } else {
       return $warning.$scrout;
     }
   }
   
   #########################################
   
   sub batchpublish {
       my ($r,$srcfile,$targetfile)=@_;
       my $thisdisfn=$srcfile;
       $thisdisfn=~s/\/home\/korte\/public_html\///;
       $srcfile=~s/\/+/\//g;
   
       my $docroot=$r->dir_config('lonDocRoot');
       my $thisdistarget=$targetfile;
       $thisdistarget=~s/^$docroot//;
   
   
       undef %metadatafields;
       undef %metadatakeys;
        %metadatafields=();
        %metadatakeys=();
         $srcfile=~/\.(\w+)$/;
         my $thistype=$1;
   
   
         my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);
        
       $r->print('<h2>Publishing <tt>'.$thisdisfn.'</tt></h2>');
   
   # phase one takes
   #  my ($source,$target,$style,$batch)=@_;
       $r->print('<p>'.&publish($srcfile,$targetfile,$thisembstyle,1).'</p>');
   # phase two takes
   # my ($source,$target,$style,$distarget,batch)=@_;
   # $ENV{'form.allmeta'},$ENV{'form.title'},$ENV{'form.author'},...
       $r->print(
   '<p>'.&phasetwo($srcfile,$targetfile,$thisembstyle,$thisdistarget,1).'</p>');
       return '';
 }  }
   
 # ================================================================ Main Handler  #########################################
   
   sub publishdirectory {
       my ($r,$fn,$thisdisfn)=@_;
       my $resdir=
       $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'.$cudom.'/'.$cuname.
         $thisdisfn;
         $r->print('<h1>Directory <tt>'.$thisdisfn.'/</tt></h1>'.
                   'Target: <tt>'.$resdir.'</tt><br />');
   
         my $dirptr=16384; # Mask indicating a directory in stat.cmode.
   
         opendir(DIR,$fn);
         my @files=sort(readdir(DIR));
         foreach my $filename (@files) {
            my ($cdev,$cino,$cmode,$cnlink,
               $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
        my $publishthis=0;
                if (-e $resdir.'/'.$filename) {
           my ($rdev,$rino,$rmode,$rnlink,
           $ruid,$rgid,$rrdev,$rsize,
           $ratime,$rmtime,$rctime,
           $rblksize,$rblocks)=stat($resdir.'/'.$filename);
           if ($rmtime<$cmtime) {
   # previously published, modified now
       $publishthis=1;
                   }
        } else {
   # never published
    $publishthis=1;
        }
                if ($publishthis) {
                   &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename);
        } else {
                    $r->print('<br />Skipping '.$filename.'<br />');
                }
                $r->rflush();
            }
         }
         closedir(DIR);
   }
   #########################################
   
   =pod
   
   =item B<handler>
   
   A basic outline of the handler subroutine follows.
   
   =over 4
   
   =item *
   
   Get query string for limited number of parameters.
   
   =item *
   
   Check filename.
   
   =item *
   
   File is there and owned, init lookup tables.
   
   =item *
   
   Start page output.
   
   =item *
   
   Evaluate individual file, and then output information.
   
   =item *
   
   Publishing from $thisfn to $thistarget with $thisembstyle.
   
   =back
   
   =cut
   
   #########################################
   #########################################
 sub handler {  sub handler {
   my $r=shift;    my $r=shift;
   
Line 1140  sub handler { Line 1635  sub handler {
   
 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=();
   
Line 1164  unless ($ENV{'form.phase'} eq 'two') { Line 1659  unless ($ENV{'form.phase'} eq 'two') {
   
 }  }
   
 # ----------------------------------------------------------- Start page output  # ---------------------------------------------------------- Start page output.
   
   $r->content_type('text/html');    $r->content_type('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(    $r->print(&Apache::loncommon::bodytag('Resource Publication'));
    '<body bgcolor="#FFFFFF"><img align=right src=/adm/lonIcons/lonlogos.gif>');  
   my $thisfn=$fn;    my $thisfn=$fn;
      
 # ------------------------------------------------------------- Individual file  
   {  
       $thisfn=~/\.(\w+)$/;  
       my $thistype=$1;  
       my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);  
   
       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;
     $thisdistarget=~s/^$docroot//;
   
     my $thisdisfn=$thisfn;
     $thisdisfn=~s/^\/home\/$cuname\/public_html\///;
   
       my $thisdistarget=$thistarget;    if ($fn=~/\/$/) {
       $thisdistarget=~s/^$docroot//;  # -------------------------------------------------------- This is a directory
         &publishdirectory($r,$fn,$thisdisfn);
   
       my $thisdisfn=$thisfn;    } else {
       $thisdisfn=~s/^\/home\/$cuname\/public_html\///;  # ---------------------- Evaluate individual file, and then output information.
         $thisfn=~/\.(\w+)$/;
         my $thistype=$1;
         my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);
   
       $r->print('<h2>Publishing '.        $r->print('<h2>Publishing '.
         &Apache::loncommon::filedescription($thistype).' <tt>'.          &Apache::loncommon::filedescription($thistype).' <tt>'.
         $thisdisfn.'</tt></h2><b>Target:</b> <tt>'.$thisdistarget.'</tt><p>');          '<a href="/~'.$cuname.'/'.$thisdisfn.'" target="cat">'.$thisdisfn.
           '</a></tt></h2><b>Target:</b> <tt>'.$thisdistarget.'</tt><p>');
         
        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">Co-Author: '.$cuname.' at '.$cudom.
                '</font></h3>');      '</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('<br /><a href="/adm/diff?filename=/~'.$cuname.'/'.
                     $thisdisfn.                      $thisdisfn.
    '&versionone=priv" target=cat>Diffs with Current Version</a><p>');     '&versionone=priv" target="cat">Diffs with Current Version</a><p>');
       }        }
       
 # ------------ We are 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') {
          $r->print(           $r->print(
           '<hr>'.&publish($thisfn,$thistarget,$thisembstyle));            '<hr />'.&publish($thisfn,$thistarget,$thisembstyle));
        } else {         } else {
          $r->print(           $r->print(
           '<hr>'.&phasetwo($thisfn,$thistarget,$thisembstyle,$thisdistarget));             '<hr />'.&phasetwo($thisfn,$thistarget,
        $thisembstyle,$thisdistarget)); 
        }           }  
   
   }    }

Removed from v.1.89  
changed lines
  Added in v.1.99


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