Diff for /loncom/publisher/lonpublisher.pm between versions 1.108 and 1.239

version 1.108, 2003/02/03 18:03:53 version 1.239, 2008/06/30 18:10:24
Line 25 Line 25
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
 #   
 # (TeX Content Handler  
 #  
 # 05/29/00,05/30,10/11 Gerd Kortemeyer)  
 #  
 # 11/28,11/29,11/30,12/01,12/02,12/04,12/23 Gerd Kortemeyer  
 # 03/23 Guy Albertelli  
 # 03/24,03/29,04/03 Gerd Kortemeyer  
 # 05/03,05/05,05/07 Gerd Kortemeyer  
 # 06/23,08/07,08/11,8/13,8/17,8/18,8/24,9/26,10/16 Gerd Kortemeyer  
 # 12/04,12/05 Guy Albertelli  
 # 12/05 Gerd Kortemeyer  
 # 12/05 Guy Albertelli  
 # 12/06,12/07 Gerd Kortemeyer  
 # 12/25 Gerd Kortemeyer  
 # YEAR=2002  
 # 1/17 Gerd Kortemeyer  
 #  
 ###  ###
   
 ###############################################################################  ###############################################################################
Line 82  invocation by F<loncapa_apache.conf>: Line 64  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 117  use File::Copy; Line 119  use File::Copy;
 use Apache::Constants qw(:common :http :methods);  use Apache::Constants qw(:common :http :methods);
 use HTML::LCParser;  use HTML::LCParser;
 use Apache::lonxml;  use Apache::lonxml;
 use Apache::lonhomework;  
 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::loncfile;
   use LONCAPA::lonmetadata;
   use Apache::lonmsg;
 use vars qw(%metadatafields %metadatakeys);  use vars qw(%metadatafields %metadatakeys);
   use LONCAPA qw(:DEFAULT :match);
    
   
 my %addid;  my %addid;
 my %nokey;  my %nokey;
Line 133  my $docroot; Line 140  my $docroot;
 my $cuname;  my $cuname;
 my $cudom;  my $cudom;
   
   my $registered_cleanup;
   my $modified_urls;
   
   my $lock;
   
 =pod  =pod
   
 =item B<metaeval>  =item B<metaeval>
Line 160  nothing Line 172  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'})) {       next if ($entry =~ m/^(?:parameter|stores)_/);
                   $unikey.='_package_'.$token->[2]->{'package'};      if (defined($token->[2]->{'package'})) { 
               }    $unikey.="\0package\0".$token->[2]->{'package'};
               if (defined($token->[2]->{'part'})) {       } 
                  $unikey.='_'.$token->[2]->{'part'};       if (defined($token->[2]->{'part'})) { 
       }   $unikey.="\0".$token->[2]->{'part'}; 
               if (defined($token->[2]->{'id'})) {       }
                   $unikey.='_'.$token->[2]->{'id'};      if (defined($token->[2]->{'id'})) { 
               }    $unikey.="\0".$token->[2]->{'id'};
               if (defined($token->[2]->{'name'})) {       } 
                  $unikey.='_'.$token->[2]->{'name'};       if (defined($token->[2]->{'name'})) { 
       }   $unikey.="\0".$token->[2]->{'name'}; 
               foreach (@{$token->[3]}) {      }
   $metadatafields{$unikey.'.'.$_}=$token->[2]->{$_};      foreach (@{$token->[3]}) {
                   if ($metadatakeys{$unikey}) {   $metadatafields{$unikey.'.'.$_}=$token->[2]->{$_};
       $metadatakeys{$unikey}.=','.$_;   if ($metadatakeys{$unikey}) {
                   } else {      $metadatakeys{$unikey}.=','.$_;
                       $metadatakeys{$unikey}=$_;   } else {
                   }      $metadatakeys{$unikey}=$_;
               }   }
               if ($metadatafields{$unikey}) {      }
   my $newentry=$parser->get_text('/'.$entry);      my $newentry=$parser->get_text('/'.$entry);
                   unless (($metadatafields{$unikey}=~/$newentry/) ||      if (($entry eq 'customdistributionfile') ||
                           ($newentry eq '')) {   ($entry eq 'sourcerights')) {
                      $metadatafields{$unikey}.=', '.$newentry;   $newentry=~s/^\s*//;
   }   if ($newentry !~m|^/res|) { $newentry=$prefix.$newentry; }
       } else {      }
                  $metadatafields{$unikey}=$parser->get_text('/'.$entry);  # actually store
               }      if ( $entry eq 'rule' && exists($metadatafields{$unikey})) {
           }   $metadatafields{$unikey}.=','.$newentry;
        }      } else {
    $metadatafields{$unikey}=$newentry;
       }
    }
       }
 }  }
   
 #########################################  #########################################
Line 240  XHTML text that indicates successful rea Line 260  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>'.&mt('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>'.&mt('Processed file').':</b> <tt>'.
    &Apache::loncfile::display($fn).'</tt><br />';
 }  }
   
 #########################################  #########################################
Line 261  sub metaread { Line 283  sub metaread {
 sub coursedependencies {  sub coursedependencies {
     my $url=&Apache::lonnet::declutter(shift);      my $url=&Apache::lonnet::declutter(shift);
     $url=~s/\.meta$//;      $url=~s/\.meta$//;
     my ($adomain,$aauthor)=($url=~/^(\w+)\/(\w+)\//);      my ($adomain,$aauthor)=($url=~ m{^($match_domain)/($match_username)/});
     my $regexp=$url;      my $regexp=quotemeta($url);
     $regexp=~s/(\W)/\\$1/g;  
     $regexp='___'.$regexp.'___course';      $regexp='___'.$regexp.'___course';
     my %evaldata=&Apache::lonnet::dump('nohist_resevaldata',$adomain,      my %evaldata=&Apache::lonnet::dump('nohist_resevaldata',$adomain,
        $aauthor,$regexp);         $aauthor,$regexp);
Line 305  string which presents the form field (fo Line 326  string which presents the form field (fo
 #########################################  #########################################
 sub textfield {  sub textfield {
     my ($title,$name,$value)=@_;      my ($title,$name,$value)=@_;
     return "\n<p><b>$title:</b><br>".      $value=~s/^\s+//gs;
            '<input type="text" name="'.$name.'" size=80 value="'.$value.'" />';      $value=~s/\s+$//gs;
       $value=~s/\s+/ /gs;
       $title=&mt($title);
       $env{'form.'.$name}=$value;
       return "\n".&Apache::lonhtmlcommon::row_title($title)
              .'<input type="text" name="'.$name.'" size="80" value="'.$value.'" />'
              .&Apache::lonhtmlcommon::row_closure();
   }
   
   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".&Apache::lonhtmlcommon::row_title($title)
             .'<input type="text" name="'.$name.'" size="80" value="'.$value.'" />'
             .'<br />'
     .'<a href="javascript:openbrowser(\'pubform\',\''.$name.'\',\''.$restriction.'\');">'
             .&mt('Select')
             .'</a>&nbsp;'
     .'<a href="javascript:opensearcher(\'pubform\',\''.$name.'\');">'
             .&mt('Search')
             .'</a>'
             .&Apache::lonhtmlcommon::row_closure();
 }  }
   
 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)=@_;
     my $uctitle=uc($title);      $title=&mt($title);
     my $selout="\n<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:".      $value=(split(/\s*,\s*/,$value))[-1];
  "</b></font><br />".'<select name="'.$name.'">';      if (defined($value)) {
    $env{'form.'.$name}=$value;
       } else {
    $env{'form.'.$name}=$idlist[0];
       }
       my $selout="\n".&Apache::lonhtmlcommon::row_title($title)
                 .'<select name="'.$name.'">';
     foreach (@idlist) {      foreach (@idlist) {
         $selout.='<option value=\''.$_.'\'';          $selout.='<option value=\''.$_.'\'';
         if ($_ eq $value) {          if ($_ eq $value) {
Line 326  sub selectbox { Line 385  sub selectbox {
  }   }
         else {$selout.='>'.&{$functionref}($_).'</option>';}          else {$selout.='>'.&{$functionref}($_).'</option>';}
     }      }
     return $selout.'</select>';      $selout.='</select>'.&Apache::lonhtmlcommon::row_closure();
       return $selout;
 }  }
   
   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 350  sub urlfixup { Line 416  sub urlfixup {
     if ($url =~ /^mailto:/i) { return $url; }      if ($url =~ /^mailto:/i) { return $url; }
     #internal document links need no fixing      #internal document links need no fixing
     if ($url =~ /^\#/) { return $url; }       if ($url =~ /^\#/) { return $url; } 
     my ($host)=($url=~/(?:http\:\/\/)*([^\/]+)/);      my ($host)=($url=~m{(?:(?:http|https|ftp)://)*([^/]+)});
     foreach (values %Apache::lonnet::hostname) {      my @lonids = &Apache::lonnet::machine_ids($host);
  if ($_ eq $host) {      if (@lonids) {
     $url=~s/^http\:\/\///;   $url=~s{^(?:http|https|ftp)://}{};
             $url=~s/^$host//;   $url=~s/^\Q$host\E//;
         }  
     }      }
     if ($url=~/^http\:\/\//) { return $url; }      if ($url=~m{^(?:http|https|ftp)://}) { return $url; }
     $url=~s/\~$cuname/res\/$cudom\/$cuname/;      $url=~s{\Q~$cuname\E}{res/$cudom/$cuname};
     return $url;      return $url;
 }  }
   
Line 409  sub set_allow { Line 474  sub set_allow {
     }      }
     if (($newurl !~ /^javascript:/i) &&      if (($newurl !~ /^javascript:/i) &&
  ($newurl !~ /^mailto:/i) &&   ($newurl !~ /^mailto:/i) &&
  ($newurl !~ /^http:/i) &&   ($newurl !~ /^(?:http|https|ftp):/i) &&
  ($newurl !~ /^\#/)) {   ($newurl !~ /^\#/)) {
  $$allow{&absoluteurl($newurl,$target)}=1;   $$allow{&absoluteurl($newurl,$target)}=1;
     }      }
     return $return_url      return $return_url;
 }  }
   
 #########################################  #########################################
Line 436  sub get_subscribed_hosts { Line 501  sub get_subscribed_hosts {
     $target=~/(.*)\/([^\/]+)$/;      $target=~/(.*)\/([^\/]+)$/;
     my $srcf=$2;      my $srcf=$2;
     opendir(DIR,$1);      opendir(DIR,$1);
       # cycle through listed files, subscriptions used to exist
       # as "filename.lonid"
     while ($filename=readdir(DIR)) {      while ($filename=readdir(DIR)) {
  if ($filename=~/$srcf\.(\w+)$/) {   if ($filename=~/\Q$srcf\E\.($match_lonid)$/) {
     my $subhost=$1;      my $subhost=$1;
     if (($subhost ne 'meta' && $subhost ne 'subscription') &&      if (($subhost ne 'meta' 
    && $subhost ne 'subscription' 
    && $subhost ne 'meta.subscription'
    && $subhost ne 'tmp') &&
                 ($subhost ne $Apache::lonnet::perlvar{'lonHostID'})) {                  ($subhost ne $Apache::lonnet::perlvar{'lonHostID'})) {
  push(@subscribed,$subhost);   push(@subscribed,$subhost);
     }      }
Line 448  sub get_subscribed_hosts { Line 518  sub get_subscribed_hosts {
     closedir(DIR);      closedir(DIR);
     my $sh;      my $sh;
     if ( $sh=Apache::File->new("$target.subscription") ) {      if ( $sh=Apache::File->new("$target.subscription") ) {
  &Apache::lonnet::logthis("opened $target.subscription");  
  while (my $subline=<$sh>) {   while (my $subline=<$sh>) {
     &Apache::lonnet::logthis("Trying $subline");      if ($subline =~ /^($match_lonid):/) { 
     if ($subline =~ /(^\w+):/) {   
                 if ($1 ne $Apache::lonnet::perlvar{'lonHostID'}) {                   if ($1 ne $Apache::lonnet::perlvar{'lonHostID'}) { 
                    push(@subscribed,$1);                     push(@subscribed,$1);
         }          }
             } else {  
  &Apache::lonnet::logthis("No Match for $subline");  
     }      }
  }   }
     } else {  
  &Apache::lonnet::logthis("Unable to open $target.subscription");  
     }      }
     return @subscribed;      return @subscribed;
 }  }
Line 490  sub get_max_ids_indices { Line 554  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 508  sub get_max_ids_indices { Line 574  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 550  sub get_all_text_unbalanced { Line 617  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 594  sub fix_ids_and_indices { Line 661  sub fix_ids_and_indices {
    join(', ',@duplicatedids));     join(', ',@duplicatedids));
     if ($duplicateids) {      if ($duplicateids) {
  print $logfile "Duplicate ID(s) exist, ".join(', ',@duplicatedids)."\n";   print $logfile "Duplicate ID(s) exist, ".join(', ',@duplicatedids)."\n";
  my $outstring='<font color="red">Unable to publish file, it contains duplicated ID(s), ID(s) need to be unique. The duplicated ID(s) are: '.join(', ',@duplicatedids).'</font>';   my $outstring='<span class="LC_error">'.&mt('Unable to publish file, it contains duplicated ID(s), ID(s) need to be unique. The duplicated ID(s) are').': '.join(', ',@duplicatedids).'</span>';
  return ($outstring,1);   return ($outstring,1);
     }      }
     if ($needsfixup) {      if ($needsfixup) {
Line 603  sub fix_ids_and_indices { Line 670  sub fix_ids_and_indices {
                 "Max Index: $maxindex (min 10)\n";                  "Max Index: $maxindex (min 10)\n";
     }      }
     my $outstring='';      my $outstring='';
       my $responsecounter=1;
     my @parser;      my @parser;
     $parser[0]=HTML::LCParser->new(\$content);      $parser[0]=HTML::LCParser->new(\$content);
     $parser[-1]->xml_mode(1);      $parser[-1]->xml_mode(1);
Line 617  sub fix_ids_and_indices { Line 685  sub fix_ids_and_indices {
     $allow{$token->[2]->{'src'}}=1;      $allow{$token->[2]->{'src'}}=1;
     next;      next;
  }   }
    if ($lctag eq 'base') { next; }
                   if (($lctag eq 'part') || ($lctag eq 'problem')) {
                       $responsecounter=0;
                   }
                   if ($lctag=~/response$/) { $responsecounter++; }
  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});
       }
  }   }
     }      }
  }   }
  # 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] =~ s/[\n\r\f]+//g;
  $next_token->[1]=&set_allow(\%allow,$logfile,   $next_token->[1]=&set_allow(\%allow,$logfile,
     $target,$tag,      $target,$tag,
     $next_token->[1]);      $next_token->[1]);
Line 656  sub fix_ids_and_indices { Line 739  sub fix_ids_and_indices {
  }   }
  if ($lctag eq 'applet') {   if ($lctag eq 'applet') {
     my $codebase='';      my $codebase='';
     if (defined($parms{'codebase'})) {      my $havecodebase=0;
  my $oldcodebase=$parms{'codebase'};      foreach my $key (keys(%parms)) {
    if (lc($key) eq 'codebase') { 
       $codebase=$parms{$key};
       $havecodebase=1; 
    }
       }
       if ($havecodebase) {
    my $oldcodebase=$codebase;
  unless ($oldcodebase=~/\/$/) {   unless ($oldcodebase=~/\/$/) {
     $oldcodebase.='/';      $oldcodebase.='/';
  }   }
Line 671  sub fix_ids_and_indices { Line 761  sub fix_ids_and_indices {
  }   }
  $allow{&absoluteurl($codebase,$target).'/*'}=1;   $allow{&absoluteurl($codebase,$target).'/*'}=1;
     } else {      } else {
  foreach ('archive','code','object') {   foreach my $key (keys(%parms)) {
     if (defined($parms{$_})) {      if ($key =~ /(archive|code|object)/i) {
  my $oldurl=$parms{$_};   my $oldurl=$parms{$key};
  my $newurl=&urlfixup($oldurl,$target);   my $newurl=&urlfixup($oldurl,$target);
  $newurl=~s/\/[^\/]+$/\/\*/;   $newurl=~s/\/[^\/]+$/\/\*/;
  print $logfile 'Allow: applet '.$_.':'.   print $logfile 'Allow: applet '.lc($key).':'.
     $oldurl.' allows '.      $oldurl.' allows '.$newurl."\n";
  $newurl."\n";  
  $allow{&absoluteurl($newurl,$target)}=1;   $allow{&absoluteurl($newurl,$target)}=1;
     }      }
  }   }
Line 696  sub fix_ids_and_indices { Line 785  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' || $lctag eq 'answer' 
     $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]) {
     unless ($token->[1] eq 'allow') {      unless ($token->[1] eq 'allow') {
  $outstring.='</'.$token->[1].'>';   $outstring.='</'.$token->[1].'>';
     }      }
  }                  }
                   if ((($token->[1] eq 'part') || ($token->[1] eq 'problem'))
                       && (!$responsecounter)) {
                       my $outstring='<span class="LC_error">'.&mt('Found [_1] without responses. This resource cannot be published.',$token->[1]).'</span>';
                       return ($outstring,1);
                   }
     } else {      } else {
  $outstring.=$token->[1];   $outstring.=$token->[1];
     }      }
Line 742  Returns: (error,status).  error is undef Line 837  Returns: (error,status).  error is undef
 #########################################  #########################################
 #########################################  #########################################
 sub store_metadata {  sub store_metadata {
     my %metadata = %{shift()};      my %metadata = @_;
     my $error;      my $error;
     # Determine if the table exists      # Determine if the table exists
     my $status = &Apache::lonmysql::check_table('metadata');      my $status = &Apache::lonmysql::check_table('metadata');
     if (! defined($status)) {      if (! defined($status)) {
         $error='<font color="red">WARNING: Cannot connect to '.          $error='<span class="LC_error">WARNING: Cannot connect to '.
             'database!</font>';              'database!</span>';
         &Apache::lonnet::logthis($error);          &Apache::lonnet::logthis($error);
         return ($error,undef);          return ($error,undef);
     }      }
     if ($status == 0) {      if ($status == 0) {
         # It would be nice to actually create the table....          # It would be nice to actually create the table....
         $error ='<font color="red">WARNING: The metadata table does not '.          $error ='<span class="LC_error">WARNING: The metadata table does not '.
             'exist in the LON-CAPA database.</font>';              'exist in the LON-CAPA database.</span>';
         &Apache::lonnet::logthis($error);          &Apache::lonnet::logthis($error);
         return ($error,undef);          return ($error,undef);
     }      }
     # Remove old value from table      my $dbh = &Apache::lonmysql::get_dbh();
     $status = &Apache::lonmysql::remove_from_table      if (($metadata{'obsolete'}) || ($metadata{'copyright'} eq 'priv')) {
         ('metadata','url',$metadata{'url'});          # remove this entry
     if (! defined($status)) {   my $delitem = 'url = '.$dbh->quote($metadata{'url'});
         $error = '<font color="red">Error when removing old values from '.   $status = &LONCAPA::lonmetadata::delete_metadata($dbh,undef,$delitem);
             'metadata table in LON-CAPA database.</font>';                                                         
         &Apache::lonnet::logthis($error);      } else {
         return ($error,undef);          $status = &LONCAPA::lonmetadata::update_metadata($dbh,undef,undef,
                                                            \%metadata);
     }      }
     # Store data in table.      if (defined($status) && $status ne '') {
     $status = &Apache::lonmysql::store_row('metadata',\%metadata);          $error='<span class="LC_error">Error occured saving new values in '.
     if (! defined($status)) {              'metadata table in LON-CAPA database</span>';
         $error='<font color="red">Error occured storing new values in '.  
             '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,'success');
   }
   
   
   # ========================================== 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" /><span class="LC_error"><b>'.
         $errorcount.' '.
         &mt('error(s)').'</b></span> ');
    }
    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
   #
   # 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 790  This is the workhorse function of this m Line 934  This is the workhorse function of this m
 backup copies, performs any automatic processing (prior to publication,  backup copies, performs any automatic processing (prior to publication,
 especially for rat and ssi files),  especially for rat and ssi files),
   
   Returns a 2 element array, the first is the string to be shown to the
   user, the second is an error code, either 1 (an error occured) or 0
   (no error occurred)
   
 I<Additional documentation needed.>  I<Additional documentation needed.>
   
 =cut  =cut
Line 806  sub publish { Line 954  sub publish {
     my %allow=();      my %allow=();
   
     unless ($logfile=Apache::File->new('>>'.$source.'.log')) {      unless ($logfile=Apache::File->new('>>'.$source.'.log')) {
  return    return ('<span class="LC_error">'.&mt('No write permission to user directory, FAIL').'</span>',1);
          '<font color=red>No write permission to user directory, FAIL</font>';  
     }      }
     print $logfile       print $logfile 
 "\n\n================= Publish ".localtime()." Phase One  ================\n";  "\n\n================= Publish ".localtime()." Phase One  ================\n".$env{'user.name'}.':'.$env{'user.domain'}."\n";
   
     if (($style eq 'ssi') || ($style eq 'rat')) {      if (($style eq 'ssi') || ($style eq 'rat') || ($style eq 'prv')) {
 # ------------------------------------------------------- This needs processing  # ------------------------------------------------------- This needs processing
   
 # ----------------------------------------------------------------- Backup Copy  # ----------------------------------------------------------------- Backup Copy
Line 821  sub publish { Line 968  sub publish {
     print $logfile "Copied original file to ".$copyfile."\n";      print $logfile "Copied original file to ".$copyfile."\n";
         } else {          } else {
     print $logfile "Unable to write backup ".$copyfile.':'.$!."\n";      print $logfile "Unable to write backup ".$copyfile.':'.$!."\n";
           return "<font color=red>Failed to write backup copy, $!,FAIL</font>";      return ("<span class=\"LC_error\">".&mt("Failed to write backup copy, [_1], FAIL",$1)."</span>",1);
         }          }
 # ------------------------------------------------------------- IDs and indices  # ------------------------------------------------------------- IDs and indices
   
  my ($outstring,$error);   my ($outstring,$error);
  ($outstring,$error,%allow)=&fix_ids_and_indices($logfile,$source,   ($outstring,$error,%allow)=&fix_ids_and_indices($logfile,$source,
  $target);   $target);
  if ($error) { return $outstring; }   if ($error) { return ($outstring,$error); }
 # ------------------------------------------------------------ Construct Allows  # ------------------------------------------------------------ Construct Allows
           
  $scrout.='<h3>Dependencies</h3>';   $scrout.='<h3>'.&mt('Dependencies').'</h3>';
         my $allowstr='';          my $allowstr='';
         foreach (sort(keys(%allow))) {          foreach my $thisdep (sort(keys(%allow))) {
    my $thisdep=$_;  
    if ($thisdep !~ /[^\s]/) { next; }     if ($thisdep !~ /[^\s]/) { next; }
              if ($thisdep =~/\$/) {
                 $scrout.='<br /><span class="LC_warning">'
                          .&mt('The resource depends on another resource with variable filename, i.e., [_1].','<tt>'.$thisdep.'</tt>').'<br />'
                          .&mt('You likely need to explicitly allow access to all possible dependencies using the [_1]-tag.','<tt>&lt;allow&gt;</tt>')
                          .'</span><br />';
              }
            unless ($style eq 'rat') {              unless ($style eq 'rat') { 
               $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'}.'/'.
                                             $thisdep.'.meta') eq '-1') {                                              $thisdep.'.meta') eq '-1') {
    $scrout.= ' - <font color="red">Currently not available'.     $scrout.= ' - <span class="LC_error">'.&mt('Currently not available').
        '</font>';         '</span>';
                } 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=~m{^/res/($match_domain)/($match_username)/};
                    if ((defined($1)) && (defined($2))) {                     if ((defined($1)) && (defined($2))) {
                       &Apache::lonnet::put('nohist_resevaldata',\%temphash,                        &Apache::lonnet::put('nohist_resevaldata',\%temphash,
    $1,$2);     $1,$2);
Line 863  sub publish { Line 1015  sub publish {
        }         }
            }             }
         }          }
         $outstring=~s/\n*(\<\/[^\>]+\>)\s*$/$allowstr\n$1\n/s;          $outstring=~s/\n*(\<\/[^\>]+\>[^<]*)$/$allowstr\n$1\n/s;
   
  #Encode any High ASCII characters  
  $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 ('<span class="LC_error">'.&mt('No write permission to').
  '<font color="red">No write permission to '.$source.       ' '.$source.
  ', FAIL</font>';       ', '.&mt('FAIL').'</span>',1);
   }    }
           print($org $outstring);            print($org $outstring);
         }          }
Line 885  sub publish { Line 1035  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>';
     }      }
   
 # ------------------------------------------------ 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;
   
 # ------------------------------------------------ Check out directory hierachy  # ------------------------------------------------ Check out directory hierachy
   
         my $thisdisfn=$source;          my $thisdisfn=$source;
         $thisdisfn=~s/^\/home\/$cuname\///;          $thisdisfn=~s/^\/home\/\Q$cuname\E\///;
   
         my @urlparts=split(/\//,$thisdisfn);          my @urlparts=split(/\//,$thisdisfn);
         $#urlparts--;          $#urlparts--;
   
         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|^\.\./||;
         }          }
   
   # ----------------------------------------------------------- Parse file itself
   # read %metadatafields from file itself
    
    $allmeta=&parseformeta($source,$style);
   
 # ------------------- Clear out parameters and stores (there should not be any)  # ------------------- Clear out parameters and stores (there should not be any)
   
         foreach (keys %metadatafields) {          foreach (keys %metadatafields) {
Line 941  sub publish { Line 1099  sub publish {
  delete $metadatafields{$_};   delete $metadatafields{$_};
             }              }
         }          }
           # ------------------------------------------------------------- Save some stuff
     }          my %savemeta=();
           foreach ('title') {
 # -------------------------------------------------- Parse content for metadata              $savemeta{$_}=$metadatafields{$_};
     if ($style eq 'ssi') {   }
         my $oldenv=$ENV{'request.uri'};  # ------------------------------------------ See if anything new in file itself
    
         $ENV{'request.uri'}=$target;   $allmeta=&parseformeta($source,$style);
         $allmeta=Apache::lonxml::xmlparse(undef,'meta',$content);  # ----------------------------------------------------------- Restore the stuff
         $ENV{'request.uri'}=$oldenv;          foreach (keys %savemeta) {
       $metadatafields{$_}=$savemeta{$_};
    }
      }
   
         &metaeval($allmeta);         
     }  
 # ---------------- Find and document discrepancies in the parameters and stores  # ---------------- Find and document discrepancies in the parameters and stores
   
         my $chparms='';      my $chparms='';
         foreach (sort keys %metadatafields) {      foreach (sort keys %metadatafields) {
     if (($_=~/^parameter/) || ($_=~/^stores/)) {   if (($_=~/^parameter/) || ($_=~/^stores/)) {
                 unless ($_=~/\.\w+$/) {       unless ($_=~/\.\w+$/) { 
                    unless ($oldparmstores{$_}) {   unless ($oldparmstores{$_}) {
       print $logfile 'New: '.$_."\n";      my $disp_key = $_;
                       $chparms.=$_.' ';      $disp_key =~ tr/\0/_/;
                    }      print $logfile ('New: '.$disp_key."\n");
         }      $chparms .= $disp_key.' ';
             }   }
         }      }
         if ($chparms) {   }
     $scrout.='<p><b>New parameters or stored values:</b> '.      }
                      $chparms;      if ($chparms) {
         }   $scrout.='<p><b>'.&mt('New parameters or saved values').
       ':</b> '.$chparms.'</p>';
       }
   
         $chparms='';      $chparms='';
         foreach (sort keys %oldparmstores) {      foreach (sort keys %oldparmstores) {
     if (($_=~/^parameter/) || ($_=~/^stores/)) {   if (($_=~/^parameter/) || ($_=~/^stores/)) {
                 unless (($metadatafields{$_.'.name'}) ||      unless (($metadatafields{$_.'.name'}) ||
                         ($metadatafields{$_.'.package'}) || ($_=~/\.\w+$/)) {      ($metadatafields{$_.'.package'}) || ($_=~/\.\w+$/)) {
     print $logfile 'Obsolete: '.$_."\n";   my $disp_key = $_;
                     $chparms.=$_.' ';   $disp_key =~ tr/\0/_/;
                 }   print $logfile ('Obsolete: '.$disp_key."\n");
             }   $chparms.=$disp_key.' ';
         }      }
         if ($chparms) {   }
     $scrout.='<p><b>Obsolete parameters or stored values:</b> '.      }
                      $chparms;      if ($chparms) {
         }   $scrout.='<p><b>'.&mt('Obsolete parameters or saved values').':</b> '.
       $chparms.'</p><h1><span class="LC_warning">'.&mt('Warning!').
       '</span></h1><p><span class="LC_warning">'.
       &mt('If this resource is in active use, student performance data from the previous version may become inaccessible.').'</span></p><hr />';
       }
       if ($metadatafields{'copyright'} eq 'priv') {
           $scrout.='</p><h1><span class="LC_warning">'.&mt('Warning!').
               '</span></h1><p><span class="LC_warning">'.
               &mt('Copyright/distribution option "Private" is no longer supported. Select another option from below. Consider "Custom Rights" for maximum control over the usage of your resource.').'</span></p><hr />';
       }
   
 # ------------------------------------------------------- Now have all metadata  # ------------------------------------------------------- Now have all metadata
   
         my %keywords=();      my %keywords=();
                   
  if (length($content)<500000) {      if (length($content)<500000) {
     my $textonly=$content;   my $textonly=$content;
             $textonly=~s/\<script[^\<]+\<\/script\>//g;   $textonly=~s/\<script[^\<]+\<\/script\>//g;
             $textonly=~s/\<m\>[^\<]+\<\/m\>//g;   $textonly=~s/\<m\>[^\<]+\<\/m\>//g;
             $textonly=~s/\<[^\>]*\>//g;   $textonly=~s/\<[^\>]*\>//g;
             $textonly=~tr/A-Z/a-z/;   $textonly=~tr/A-Z/a-z/;
             $textonly=~s/[\$\&][a-z]\w*//g;   $textonly=~s/[\$\&][a-z]\w*//g;
             $textonly=~s/[^a-z\s]//g;   $textonly=~s/[^a-z\s]//g;
   
             foreach ($textonly=~m/(\w+)/g) {   foreach ($textonly=~m/(\w+)/g) {
  unless ($nokey{$_}) {      unless ($nokey{$_}) {
                    $keywords{$_}=1;   $keywords{$_}=1;
                 }       } 
             }   }
         }      }
   
                           
             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="Finalize Publication" /></p>'.  
           &hiddenfield('phase','two').      my $intr_scrout.='<br />'
           &hiddenfield('filename',$ENV{'form.filename'}).                      .'<form name="pubform" action="/adm/publish" method="post">';
   &hiddenfield('allmeta',&Apache::lonnet::escape($allmeta)).      unless ($env{'form.makeobsolete'}) {
           &hiddenfield('dependencies',join(',',keys %allow)).         $intr_scrout.='<p>'
           &textfield('Title','title',$metadatafields{'title'}).                      .&mt('Searching for your resource will be based on the following metadata. Please provide as much data as possible.')
           &textfield('Author(s)','author',$metadatafields{'author'}).                      .'</p>'
   &textfield('Subject','subject',$metadatafields{'subject'});                      .'<p><input type="submit" value="'
                       .&mt('Finalize Publication')
                       .'" /></p>';
       }
       $intr_scrout.=&Apache::lonhtmlcommon::start_pick_box();
       $intr_scrout.=
    &hiddenfield('phase','two').
    &hiddenfield('filename',$env{'form.filename'}).
    &hiddenfield('allmeta',&escape($allmeta)).
    &hiddenfield('dependencies',join(',',keys %allow));
       unless ($env{'form.makeobsolete'}) {
          $intr_scrout.=
    &textfield('Title','title',$metadatafields{'title'}).
    &textfield('Author(s)','author',$metadatafields{'author'}).
    &textfield('Subject','subject',$metadatafields{'subject'});
    # --------------------------------------------------- Scan content for keywords
   
 # --------------------------------------------------- Scan content for keywords      my $keywords_help = &Apache::loncommon::help_open_topic("Publishing_Keywords");
       my $keywordout=<<"END";
         my $keywords_help = Apache::loncommon::help_open_topic("Publishing_Keywords");  
  my $keywordout=<<"END";  
 <script>  <script>
 function checkAll(field)  function checkAll(field) {
 {  
     for (i = 0; i < field.length; i++)      for (i = 0; i < field.length; i++)
         field[i].checked = true ;          field[i].checked = true ;
 }  }
   
 function uncheckAll(field)  function uncheckAll(field) {
 {  
     for (i = 0; i < field.length; i++)      for (i = 0; i < field.length; i++)
         field[i].checked = false ;          field[i].checked = false ;
 }  }
 </script>  </script>
 <p><b>Keywords: $keywords_help</b>   
 <input type="button" value="check all" onclick="javascript:checkAll(document.pubform.keywords)">   
 <input type="button" value="uncheck all" onclick="javascript:uncheckAll(document.pubform.keywords)">   
 <br />  
 END  END
         $keywordout.='<table border=2><tr>';      $keywordout.="\n".&Apache::lonhtmlcommon::row_title(&mt('Keywords'))
         my $colcount=0;                  .$keywords_help
                   .'<input type="button" value="'.&mt('check all').'" onclick="javascript:checkAll(document.pubform.keywords)" />'
                   .'<input type="button" value="'.&mt('uncheck all').'" onclick="javascript:uncheckAll(document.pubform.keywords)" />'
                   .'</p><br />'
                   .'<table border="2"><tr>';
       my $colcount=0;
   
       foreach (sort keys %keywords) {
    $keywordout.='<td><label><input type="checkbox" name="keywords" value="'.$_.'"';
    if ($metadatafields{'keywords'}) {
       if ($metadatafields{'keywords'}=~/\Q$_\E/) {
    $keywordout.=' checked="on"';
    $env{'form.keywords'}.=$_.',';
       }
    } elsif (&Apache::loncommon::keyword($_)) {
       $keywordout.=' checked="on"';
       $env{'form.keywords'}.=$_.',';
    }
    $keywordout.=' />'.$_.'</label></td>';
    if ($colcount>10) {
       $keywordout.="</tr><tr>\n";
       $colcount=0;
    }
    $colcount++;
       }
       $env{'form.keywords'}=~s/\,$//;
   
             foreach (sort keys %keywords) {      $keywordout.='</tr></table>'
                 $keywordout.='<td><input type=checkbox name="keywords" value="'.$_.'"';                   .&Apache::lonhtmlcommon::row_closure();
                 if ($metadatafields{'keywords'}) {  
                    if ($metadatafields{'keywords'}=~/$_/) {       $intr_scrout.=$keywordout;
                       $keywordout.=' checked';   
                    }      $intr_scrout.=&textfield('Additional Keywords','addkey','');
         } elsif (&Apache::loncommon::keyword($_)) {  
             $keywordout.=' checked';      $intr_scrout.=&textfield('Notes','notes',$metadatafields{'notes'});
                 }   
                 $keywordout.='>'.$_.'</td>';  
                 if ($colcount>10) {  
     $keywordout.="</tr><tr>\n";  
                     $colcount=0;  
                 }  
                 $colcount++;  
             }  
           
  $keywordout.='</tr></table>';  
   
         $scrout.=$keywordout;      $intr_scrout.="\n".&Apache::lonhtmlcommon::row_title(&mt('Abstract'))
                    .'<textarea cols="80" rows="5" name="abstract">'
                    .$metadatafields{'abstract'}
                    .'</textarea>'
                    .&Apache::lonhtmlcommon::row_closure();
   
         $scrout.=&textfield('Additional Keywords','addkey','');      $source=~/\.(\w+)$/;
   
         $scrout.=&textfield('Notes','notes',$metadatafields{'notes'});      $intr_scrout.="\n".&Apache::lonhtmlcommon::row_title(&mt('Grade Levels'))
                    .&mt('Lowest Grade Level:').'&nbsp;'
                    .&select_level_form($metadatafields{'lowestgradelevel'},'lowestgradelevel')
   #                .&Apache::lonhtmlcommon::row_closure();
   #   $intr_scrout.="\n".&Apache::lonhtmlcommon::row_title(&mt('Highest Grade Level'))
                    .' '.&mt('Highest Grade Level:').'&nbsp;'
                    .&select_level_form($metadatafields{'highestgradelevel'},'highestgradelevel')
                    .&Apache::lonhtmlcommon::row_closure();
   
         $scrout.=      $intr_scrout.=&textfield('Standards','standards',$metadatafields{'standards'});
              '<p><b>Abstract:</b><br><textarea cols=80 rows=5 name=abstract>'.  
               $metadatafields{'abstract'}.'</textarea>';  
   
  $source=~/\.(\w+)$/;      $intr_scrout.=&hiddenfield('mime',$1);
   
  $scrout.=&hiddenfield('mime',$1);      my $defaultlanguage=$metadatafields{'language'};
       $defaultlanguage =~ s/\s*notset\s*//g;
       $defaultlanguage =~ s/^,\s*//g;
       $defaultlanguage =~ s/,\s*$//g;
   
         $scrout.=&selectbox('Language','language',      $intr_scrout.=&selectbox('Language','language',
                             $metadatafields{'language'},       $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',  
                             $metadatafields{'owner'});  
   
       $intr_scrout.=&textfield('Publisher/Owner','owner',
        $metadatafields{'owner'});
   
   # ---------------------------------------------- Retrofix for unused copyright
       if ($metadatafields{'copyright'} eq 'free') {
    $metadatafields{'copyright'}='default';
    $metadatafields{'sourceavail'}='open';
       }
       if ($metadatafields{'copyright'} eq 'priv') {
           $metadatafields{'copyright'}='domain';
       }
   # ------------------------------------------------ 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.
     if ($style eq 'rat') {   if ($style eq 'rat') {
  if ($metadatafields{'copyright'} eq 'public') {   # -------------------------------------- Retrofix for non-applicable copyright
     delete $metadatafields{'copyright'};      if ($metadatafields{'copyright'} eq 'public') { 
  }   delete $metadatafields{'copyright'};
         $scrout.=&selectbox('Copyright/Distribution','copyright',   $defaultoption='default';
                             $metadatafields{'copyright'},      }
     \&Apache::loncommon::copyrightdescription,      $intr_scrout.=&selectbox('Copyright/Distribution','copyright',
      (grep !/^public$/,(&Apache::loncommon::copyrightids)));       $defaultoption,
     }       \&Apache::loncommon::copyrightdescription,
     else {      (grep !/^(public|priv)$/,(&Apache::loncommon::copyrightids)));
         $scrout.=&selectbox('Copyright/Distribution','copyright',   } else {
                             $metadatafields{'copyright'},      $intr_scrout.=&selectbox('Copyright/Distribution','copyright',
     \&Apache::loncommon::copyrightdescription,       $defaultoption,
      (&Apache::loncommon::copyrightids));       \&Apache::loncommon::copyrightdescription,
     }       (grep !/^priv$/,(&Apache::loncommon::copyrightids)));
    }
     my $copyright_help =   my $copyright_help =
         Apache::loncommon::help_open_topic('Publishing_Copyright');      &Apache::loncommon::help_open_topic('Publishing_Copyright');
     $scrout =~ s/DISTRIBUTION:/'DISTRIBUTION: ' . $copyright_help/ge;          my $replace=&mt('Copyright/Distribution:');
     return $scrout.   $intr_scrout =~ s/$replace/$replace.' '.$copyright_help/ge;
         '<p><input type="submit" value="Finalize Publication" /></p></form>';  
 # =============================================================================   $intr_scrout.=&text_with_browse_field('Custom Distribution File','customdistributionfile',$metadatafields{'customdistributionfile'},'rights');
 # BATCH MODE   $intr_scrout.=&selectbox('Source Distribution','sourceavail',
 #   $defaultsourceoption,
   } else {   \&Apache::loncommon::source_copyrightdescription,
 # Transfer metadata directly to environment for stage 2   (&Apache::loncommon::source_copyrightids));
     foreach (keys %metadatafields) {  # $intr_scrout.=&text_with_browse_field('Source Custom Distribution File','sourcerights',$metadatafields{'sourcerights'},'rights');
  $ENV{'form.'.$_}=$metadatafields{$_};   my $uctitle=&mt('Obsolete');
     }          my $obsolete_checked=($metadatafields{'obsolete'})?' checked="1" ':'';
     $ENV{'form.addkey'}='';          $intr_scrout.="\n".&Apache::lonhtmlcommon::row_title($uctitle)
     $ENV{'form.keywords'}='';                       .'<input type="checkbox" name="obsolete" '.$obsolete_checked.'/ >'
     foreach (keys %keywords) {                       .&Apache::lonhtmlcommon::row_closure(1);
         if ($metadatafields{'keywords'}) {          $intr_scrout.=&text_with_browse_field('Suggested Replacement for Obsolete File',
            if ($metadatafields{'keywords'}=~/$_/) {       'obsoletereplacement',
               $ENV{'form.keywords'}.=$_.',';       $metadatafields{'obsoletereplacement'});
            }      } else {
  } elsif (&Apache::loncommon::keyword($_)) {   $intr_scrout.=&hiddenfield('copyright','private');
     $ENV{'form.keywords'}.=$_.',';  
         }   
     }      }
     $ENV{'form.keywords'}=~s/\,$//;     } else {
     unless ($ENV{'form.creationdate'}) { $ENV{'form.creationdate'}=time; }         $intr_scrout.=
     $ENV{'form.lastrevisiondate'}=time;   &hiddenfield('title',$metadatafields{'title'}).
     if ((($style eq 'rat') && ($ENV{'form.copyright'} eq 'public')) ||   &hiddenfield('author',$metadatafields{'author'}).
         (!$ENV{'form.copyright'})) {    &hiddenfield('subject',$metadatafields{'subject'}).
  $ENV{'form.copyright'}='default';   &hiddenfield('keywords',$metadatafields{'keywords'}).
     }    &hiddenfield('abstract',$metadatafields{'abstract'}).
     $ENV{'form.allmeta'}=&Apache::lonnet::escape($allmeta);   &hiddenfield('notes',$metadatafields{'notes'}).
     return $scrout;   &hiddenfield('mime',$metadatafields{'mime'}).
   }   &hiddenfield('creationdate',$metadatafields{'creationdate'}).
    &hiddenfield('lastrevisiondate',time).
    &hiddenfield('owner',$metadatafields{'owner'}).
    &hiddenfield('lowestgradelevel',$metadatafields{'lowestgradelevel'}).
    &hiddenfield('standards',$metadatafields{'standards'}).
    &hiddenfield('highestgradelevel',$metadatafields{'highestgradelevel'}).
    &hiddenfield('language',$metadatafields{'language'}).
    &hiddenfield('copyright',$metadatafields{'copyright'}).
    &hiddenfield('sourceavail',$metadatafields{'sourceavail'}).
    &hiddenfield('customdistributionfile',$metadatafields{'customdistributionfile'}).
    &hiddenfield('obsolete',1).
    &text_with_browse_field('Suggested Replacement for Obsolete File',
       'obsoletereplacement',
       $metadatafields{'obsoletereplacement'});
      }
       if (!$batch) {
    $scrout.=$intr_scrout
               .&Apache::lonhtmlcommon::end_pick_box()
               .'<p><input type="submit" value="'
       .&mt($env{'form.makeobsolete'}?'Make Obsolete':'Finalize Publication')
               .'" /></p>'
               .'</form>';
       }
       return($scrout,0);
 }  }
   
 #########################################  #########################################
Line 1184  Returns: Line 1429  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 1199  sub phasetwo { Line 1444  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;
   #
   # Unless trying to get rid of something, check name validity
   #
       unless ($env{'form.obsolete'}) {
    if ($target=~/(\_\_\_|\&\&\&|\:\:\:)/) {
       $r->print('<span class="LC_error">'.
         &mt('Unsupported character combination [_1] in filename, FAIL.',"<tt>'.$1.'</tt>").
         '</span>');
       return 0;
    }
    unless ($target=~/\.(\w+)$/) {
       $r->print('<span class="LC_error">'.&mt('No valid extension found in filename, FAIL').'</span>');
       return 0;
    }
    if ($target=~/\.(\d+)\.(\w+)$/) {
       $r->print('<span class="LC_error">'.&mt('Cannot publish versioned resource, FAIL').'</span>');
       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')) {
  return    $r->print(
             '<font color=red>No write permission to user directory, FAIL</font>';          '<span class="LC_error">'.
    &mt('No write permission to user directory, FAIL').'</span>');
           return 0;
       }
       
       if ($source =~ /\.rights$/) {
    $r->print('<p><span class="LC_warning">'.&mt('Warning: It can take up to 1 hour for rights changes to fully propagate.').'</span></p>');
     }      }
   
     print $logfile       print $logfile 
         "\n================= Publish ".localtime()." Phase Two  ================\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{'dependencies'}=$ENV{'form.dependencies'};      $metadatafields{'highestgradelevel'}=$env{'form.highestgradelevel'};
       $metadatafields{'customdistributionfile'}=
                                    $env{'form.customdistributionfile'};
       $metadatafields{'sourceavail'}=$env{'form.sourceavail'};
       $metadatafields{'obsolete'}=$env{'form.obsolete'};
       $metadatafields{'obsoletereplacement'}=
                           $env{'form.obsoletereplacement'};
       $metadatafields{'dependencies'}=$env{'form.dependencies'};
       $metadatafields{'modifyinguser'}=$env{'user.name'}.':'.
                                    $env{'user.domain'};
       $metadatafields{'authorspace'}=$cuname.':'.$cudom;
       $metadatafields{'domain'}=$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
       if ($metadatafields{'copyright'} eq 'custom') {
    my $file=$metadatafields{'customdistributionfile'};
    unless ($file=~/\.rights$/) {
               $r->print(
                   '<span class="LC_error">'.&mt('No valid custom distribution rights file specified, FAIL').
    '</span>');
       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>Could not write metadata, FAIL</font>';                  '<span class="LC_error">'.&mt('Could not write metadata, FAIL').
    '</span>');
       return 0;
         }          }
         foreach (sort keys %metadatafields) {          foreach (sort keys %metadatafields) {
             unless ($_=~/\./) {              unless ($_=~/\./) {
Line 1258  sub phasetwo { Line 1561  sub phasetwo {
                     print $mfh ' '.$_.'="'.$value.'"';                      print $mfh ' '.$_.'="'.$value.'"';
                 }                  }
                 print $mfh '>'.                  print $mfh '>'.
                     &HTML::Entities::encode($metadatafields{$unikey})                      &HTML::Entities::encode($metadatafields{$unikey},'<>&"')
                         .'</'.$tag.'>';                          .'</'.$tag.'>';
             }              }
         }          }
         $r->print('<p>Wrote Metadata');          $r->print('<p>'.&mt('Wrote Metadata').'</p>');
         print $logfile "\nWrote metadata";          print $logfile "\nWrote metadata";
     }      }
           
Line 1270  sub phasetwo { Line 1573  sub phasetwo {
   
     $metadatafields{'url'} = $distarget;      $metadatafields{'url'} = $distarget;
     $metadatafields{'version'} = 'current';      $metadatafields{'version'} = 'current';
     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');   $r->print('<p>'.&mt('Synchronized SQL metadata database').'</p>');
             print $logfile "\nSynchronized SQL metadata database";   print $logfile "\nSynchronized SQL metadata database";
         } else {  
             $r->print($error);  
             print $logfile "\n".$error;  
         }  
     } else {      } else {
         $r->print('<p>Private Publication - did not synchronize database');   $r->print($error);
         print $logfile "\nPrivate: Did not synchronize data into ".   print $logfile "\n".$error;
             "SQL metadata database";  
     }      }
   # --------------------------------------------- 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 1295  sub phasetwo { Line 1597  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(
    "<span class=\"LC_error\">".&mt('Invalid target directory, FAIL')."</span>");
       return 0;
         }          }
         opendir(DIR,$srcd);          opendir(DIR,$srcd);
         while ($filename=readdir(DIR)) {          while ($filename=readdir(DIR)) {
Line 1303  sub phasetwo { Line 1607  sub phasetwo {
                 unlink($srcd.'/'.$filename);                  unlink($srcd.'/'.$filename);
                 unlink($srcd.'/'.$filename.'.meta');                  unlink($srcd.'/'.$filename.'.meta');
             } else {              } else {
                 if ($filename=~/$srcf\.(\d+)\.$srct$/) {                  if ($filename=~/\Q$srcf\E\.(\d+)\.\Q$srct\E$/) {
                     $maxversion=($1>$maxversion)?$1:$maxversion;                      $maxversion=($1>$maxversion)?$1:$maxversion;
                 }                  }
             }              }
         }          }
         closedir(DIR);          closedir(DIR);
         $maxversion++;          $maxversion++;
         $r->print('<p>Creating old version '.$maxversion);          $r->print('<p>Creating old version '.$maxversion.'</p>');
         print $logfile "\nCreating old version ".$maxversion;          print $logfile "\nCreating old version ".$maxversion."\n";
                   
         my $copyfile=$srcd.'/'.$srcf.'.'.$maxversion.'.'.$srct;          my $copyfile=$srcd.'/'.$srcf.'.'.$maxversion.'.'.$srct;
                   
         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');              $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>";              $r->print("<span class=\"LC_error\">".&mt('Failed to copy old target').
    ", $!, ".&mt('FAIL')."</span>");
       return 0;
         }          }
                   
 # --------------------------------------------------------------- Copy Metadata  # --------------------------------------------------------------- Copy Metadata
Line 1329  sub phasetwo { Line 1635  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')              $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                   $r->print( 
                     "<font color=red>Failed to write old metadata copy, $!, FAIL</font>";                      "<span class=\"LC_error\">".
   &mt('Failed to write old metadata copy').", $!, ".&mt('FAIL')."</span>");
    return 0;
     }      }
         }          }
                   
                   
     } else {      } else {
         $r->print('<p>Initial version');          $r->print('<p>'.&mt('Initial version').'</p>');
         print $logfile "\nInitial version";          print $logfile "\nInitial version";
     }      }
   
Line 1355  sub phasetwo { Line 1663  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]);              $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');          $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>";          $r->print("<span class=\"LC_error\">".
       &mt('Failed to copy source').", $!, ".&mt('FAIL')."</span>");
    return 0;
     }      }
           
 # --------------------------------------------------------------- Copy Metadata  # --------------------------------------------------------------- Copy Metadata
Line 1374  sub phasetwo { Line 1684  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');          $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>Failed to write metadata copy, $!, FAIL</font>";              "<span class=\"LC_error\">".&mt('Failed to write metadata copy').", $!, ".&mt('FAIL')."</span>");
    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>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.'<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>Notifying host for metadata only '.$subhost.':');$r->rflush;      $thisdistarget=~s/^\Q$docroot\E//;
  print $logfile "\nNotifying host for metadata only ".$subhost.':';      &Apache::lonnet::devalidate_cache_new('resversion',$target);
  my $reply=&Apache::lonnet::critical('update:'.$target.'.meta',      &Apache::lonnet::devalidate_cache_new('meta',
     $subhost);   &Apache::lonnet::declutter($thisdistarget));
  $r->print($reply.'<br />');$r->rflush;  
  print $logfile $reply;  
     }  
       
 # --------------------------------------------------- Notify subscribed courses  
     my %courses=&coursedependencies($target);  
     my $now=time;  
     foreach (keys %courses) {  
  $r->print('<p>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.'<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/^$docroot//;  
                   
         my $thissrc=$source;          my $thissrc=$source;
         $thissrc=~s/^\/home\/(\w+)\/public_html/\/priv\/$1/;          $thissrc=~s{^/home/($match_username)/public_html}{/priv/$1};
                   
         my $thissrcdir=$thissrc;          my $thissrcdir=$thissrc;
         $thissrcdir=~s/\/[^\/]+$/\//;          $thissrcdir=~s/\/[^\/]+$/\//;
                   
                   
         $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><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>');                     '"><font size="+2">'.
     &mt('Back to Source Directory').'</font></a></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();
       }
       if ($lock) { &Apache::lonnet::remove_lock($lock); }
       return OK;
 }  }
   
 #########################################  #########################################
   
 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 1449  sub batchpublish { Line 1783  sub batchpublish {
   
     my $docroot=$r->dir_config('lonDocRoot');      my $docroot=$r->dir_config('lonDocRoot');
     my $thisdistarget=$targetfile;      my $thisdistarget=$targetfile;
     $thisdistarget=~s/^$docroot//;      $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)=@_;
     $r->print('<p>'.&publish($srcfile,$targetfile,$thisembstyle,1).'</p>');      my ($outstring,$error)=&publish($srcfile,$targetfile,$thisembstyle,1);
       $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'},...
     $r->print('<p>');      if (!$error) {
     &phasetwo($r,$srcfile,$targetfile,$thisembstyle,$thisdistarget,1);   $r->print('<p>');
     $r->print('</p>');   &phasetwo($r,$srcfile,$targetfile,$thisembstyle,$thisdistarget,1);
    $r->print('</p>');
       }
       %env=%oldenv;
     return '';      return '';
 }  }
   
Line 1483  sub publishdirectory { Line 1819  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>'.&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; }          $lock=0;
          if ($cmode&$dirptr) {      } else {
    if (($filename!~/^\./) && ($ENV{'form.pubrec'})) {          unless ($lock) { $lock=&Apache::lonnet::set_lock(&mt('Publishing [_1]',$fn)); }
       &publishdirectory($r,$fn.'/'.$filename,$thisdisfn.'/'.$filename);  # actually publish things
    }   opendir(DIR,$fn);
          } elsif ((&Apache::loncommon::fileembstyle($extension) ne 'hdn') &&   my @files=sort(readdir(DIR));
                   ($filename!~/^[\#\.]/) && ($filename!~/\~$/)) {   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  # 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) {      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 ) {
    $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 "<span class=\"LC_error\">".
       &mt('Failed to copy source').", $!, ".&mt('FAIL')."</span>";
       }
   
   # --------------------------------------------------- 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 1572  Publishing from $thisfn to $thistarget w Line 1984  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
   
     &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=$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.
          ' trying to publish empty filename', $r->filename);          ' trying to publish empty filename', $r->filename); 
      return HTTP_NOT_FOUND;   return HTTP_NOT_FOUND;
   }       } 
   
   ($cuname,$cudom)=      unless (($cuname) && ($cudom)) {
     &Apache::loncacc::constructaccess($fn,$r->dir_config('lonDefDomain'));   $r->log_reason($cuname.' at '.$cudom.
   unless (($cuname) && ($cudom)) {         ' trying to publish file '.$env{'form.filename'}.
      $r->log_reason($cuname.' at '.$cudom.         ' ('.$fn.') - not authorized', 
          ' trying to publish file '.$ENV{'form.filename'}.         $r->filename); 
          ' ('.$fn.') - not authorized',    return HTTP_NOT_ACCEPTABLE;
          $r->filename);       }
      return HTTP_NOT_ACCEPTABLE;  
   }      my $home=&Apache::lonnet::homeserver($cuname,$cudom);
       my $allowed=0;
   unless (&Apache::lonnet::homeserver($cuname,$cudom)       my @ids=&Apache::lonnet::current_machine_ids();
           eq $r->dir_config('lonHostID')) {      foreach my $id (@ids) { if ($id eq $home) { $allowed = 1; }  }
      $r->log_reason($cuname.' at '.$cudom.      unless ($allowed) {
          ' trying to publish file '.$ENV{'form.filename'}.   $r->log_reason($cuname.' at '.$cudom.
          ' ('.$fn.') - not homeserver ('.         ' trying to publish file '.$env{'form.filename'}.
          &Apache::lonnet::homeserver($cuname,$cudom).')',          ' ('.$fn.') - not homeserver ('.$home.')', 
          $r->filename);          $r->filename); 
      return HTTP_NOT_ACCEPTABLE;   return HTTP_NOT_ACCEPTABLE;
   }      }
   
   $fn=~s/^http\:\/\/[^\/]+//;      $fn=~s{^http://[^/]+}{};
   $fn=~s/^\/\~(\w+)/\/home\/$1\/public_html/;      $fn=~s{^/~($match_username)}{/home/$1/public_html};
   
   my $targetdir='';      my $targetdir='';
   $docroot=$r->dir_config('lonDocRoot');       $docroot=$r->dir_config('lonDocRoot'); 
   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 '.$ENV{'form.filename'}.         ' trying to publish unowned file '.
          ' ('.$fn.')',          $env{'form.filename'}.' ('.$fn.')', 
          $r->filename);          $r->filename); 
      return HTTP_NOT_ACCEPTABLE;   return HTTP_NOT_ACCEPTABLE;
   } else {      } else {
       $targetdir=$docroot.'/res/'.$cudom;   $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') {  
   
 # -------------------------------- 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');
    while (<$fh>=~/(\w+)\s+(\w+)/) {
       $addid{$1}=$2;
    }
       }
   
   {      %nokey=();
       my $fh=Apache::File->new($r->dir_config('lonTabDir').'/addid.tab');  
       while (<$fh>=~/(\w+)\s+(\w+)/) {  
           $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;  
       }  
   }  
   
 }      {
    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>');      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;
   
   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/^$docroot//;      $thisdistarget=~s/^\Q$docroot\E//;
   
   my $thisdisfn=$thisfn;      my $thisdisfn=$thisfn;
   $thisdisfn=~s/^\/home\/$cuname\/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 /><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);
           if ($thistype eq 'page') {  $thisembstyle = 'rat'; }
       $r->print('<h2>Publishing '.  
         &Apache::loncommon::filedescription($thistype).' <tt>'.   $r->print('<h2>'.&mt('Publishing [_1]','<tt>'.$thisdisfn.'</tt>').'</h2>');
         '<a href="/~'.$cuname.'/'.$thisdisfn.'" target="cat">'.$thisdisfn.  
         '</a></tt></h2><b>Target:</b> <tt>'.$thisdistarget.'</tt><p>');          $r->print('<h3>'.&mt('Resource Details').'</h3>');
      
       if (($cuname ne $ENV{'user.name'}) || ($cudom ne $ENV{'user.domain'})) {          $r->print(&Apache::lonhtmlcommon::start_pick_box());
           $r->print('<h3><font color="red">Co-Author: '.$cuname.' at '.$cudom.  
     '</font></h3>');          $r->print(&Apache::lonhtmlcommon::row_title(&mt('Type'))
       }                   .&Apache::loncommon::filedescription($thistype)
                    .&Apache::lonhtmlcommon::row_closure()
       if (&Apache::loncommon::fileembstyle($thistype) eq 'ssi') {                   );
           $r->print('<br /><a href="/adm/diff?filename=/~'.$cuname.'/'.  
                     $thisdisfn.          $r->print(&Apache::lonhtmlcommon::row_title(&mt('Link to Resource'))
    '&versiontwo=priv" target="cat">Diffs with Current Version</a><p>');                   .'<tt>'
       }                   );
    $r->print(<<ENDCAPTION);
   <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>'
                    .&Apache::lonhtmlcommon::row_closure()
                    );
   
           $r->print(&Apache::lonhtmlcommon::row_title(&mt('Target'))
                    .'<tt>'.$thisdistarget.'</tt>'
                    .&Apache::lonhtmlcommon::row_closure()
                    );
   
   # SB - ToDo:   
    if (($cuname ne $env{'user.name'})||($cudom ne $env{'user.domain'})) {
   #           $r->print(&Apache::lonhtmlcommon::row_title('<span class="LC_warning">'.&mt('Co-Author').'</span>')
               $r->print(&Apache::lonhtmlcommon::row_title(&mt('Co-Author'))
                        .'<span class="LC_warning">'
        .&mt('[_1] at [_2]',$cuname,$cudom)
                        .'</span>'
                        .&Apache::lonhtmlcommon::row_closure()
                        );
    }
   
    if (&Apache::loncommon::fileembstyle($thistype) eq 'ssi') {
               $r->print(&Apache::lonhtmlcommon::row_title(&mt('Diffs')));
       $r->print(<<ENDDIFF);
   <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>'
                        .&Apache::lonhtmlcommon::row_closure()
                        );
   
    }
   
           $r->print(&Apache::lonhtmlcommon::end_pick_box());
       
 # ------------------ 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(  # ---------------------------------------------------------- Parse for problems
           '<hr />'.&publish($thisfn,$thistarget,$thisembstyle));      my ($warningcount,$errorcount);
        } else {      if ($thisembstyle eq 'ssi') {
            $r->print('<hr />');   ($warningcount,$errorcount)=&checkonthis($r,$thisfn);
            &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget);       }
        }        unless ($errorcount) {
    my ($outstring,$error)=
   }      &publish($thisfn,$thistarget,$thisembstyle);
   $r->print('</body></html>');   $r->print('<hr />'.$outstring);
       } else {
    $r->print('<h3 class="LC_error">'.
     &mt('The document contains errors and cannot be published.').
     '</h3>');
       }
    } else {
       &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget); 
       $r->print('<hr />');
    }
       }
       $r->print(&Apache::loncommon::end_page());
   
   return OK;      return OK;
 }  }
   
 1;  1;
Line 1737  __END__ Line 2209  __END__
   
 =back  =back
   
   =back
   
 =cut  =cut
   

Removed from v.1.108  
changed lines
  Added in v.1.239


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