Annotation of loncom/publisher/lonpublisher.pm, revision 1.100

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Publication Handler
1.54      albertel    3: #
1.100   ! matthew     4: # $Id: lonpublisher.pm,v 1.99 2002/10/07 13:50:36 www Exp $
1.54      albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
1.1       www        28: # 
                     29: # (TeX Content Handler
                     30: #
                     31: # 05/29/00,05/30,10/11 Gerd Kortemeyer)
                     32: #
1.15      www        33: # 11/28,11/29,11/30,12/01,12/02,12/04,12/23 Gerd Kortemeyer
1.20      www        34: # 03/23 Guy Albertelli
1.23      www        35: # 03/24,03/29,04/03 Gerd Kortemeyer
1.24      harris41   36: # 04/16/2001 Scott Harrison
1.27      www        37: # 05/03,05/05,05/07 Gerd Kortemeyer
1.30      harris41   38: # 05/28/2001 Scott Harrison
1.51      www        39: # 06/23,08/07,08/11,8/13,8/17,8/18,8/24,9/26,10/16 Gerd Kortemeyer
1.58      www        40: # 12/04,12/05 Guy Albertelli
                     41: # 12/05 Gerd Kortemeyer
1.62      www        42: # 12/05 Guy Albertelli
1.64      www        43: # 12/06,12/07 Gerd Kortemeyer
1.66      harris41   44: # 12/15,12/16 Scott Harrison
1.67      www        45: # 12/25 Gerd Kortemeyer
1.71      www        46: # YEAR=2002
                     47: # 1/16,1/17 Scott Harrison
                     48: # 1/17 Gerd Kortemeyer
1.65      harris41   49: #
                     50: ###
                     51: 
                     52: ###############################################################################
                     53: ##                                                                           ##
                     54: ## ORGANIZATION OF THIS PERL MODULE                                          ##
                     55: ##                                                                           ##
                     56: ## 1. Modules used by this module                                            ##
                     57: ## 2. Various subroutines                                                    ##
                     58: ## 3. Publication Step One                                                   ##
                     59: ## 4. Phase Two                                                              ##
                     60: ## 5. Main Handler                                                           ##
                     61: ##                                                                           ##
                     62: ###############################################################################
1.1       www        63: 
1.90      matthew    64: 
                     65: ######################################################################
                     66: ######################################################################
                     67: 
                     68: =pod 
                     69: 
1.94      harris41   70: =head1 NAME
1.90      matthew    71: 
                     72: lonpublisher - LON-CAPA publishing handler
                     73: 
1.94      harris41   74: =head1 SYNOPSIS
1.90      matthew    75: 
1.94      harris41   76: B<lonpublisher> is used by B<mod_perl> inside B<Apache>.  This is the
                     77: invocation by F<loncapa_apache.conf>:
                     78: 
                     79:   <Location /adm/publish>
                     80:   PerlAccessHandler       Apache::lonacc
                     81:   SetHandler perl-script
                     82:   PerlHandler Apache::lonpublisher
                     83:   ErrorDocument     403 /adm/login
                     84:   ErrorDocument     404 /adm/notfound.html
                     85:   ErrorDocument     406 /adm/unauthorized.html
                     86:   ErrorDocument     500 /adm/errorhandler
                     87:   </Location>
                     88: 
                     89: =head1 DESCRIPTION
                     90: 
                     91: B<lonpublisher> takes the proper steps to add resources to the LON-CAPA
1.90      matthew    92: digital library.  This includes updating the metadata table in the
                     93: LON-CAPA database.
                     94: 
1.94      harris41   95: B<lonpublisher> is many things to many people.  
1.90      matthew    96: 
                     97: This module publishes a file.  This involves gathering metadata,
                     98: versioning the file, copying file from construction space to
                     99: publication space, and copying metadata from construction space
                    100: to publication space.
                    101: 
1.94      harris41  102: =head2 SUBROUTINES
                    103: 
                    104: Many of the undocumented subroutines implement various magical
                    105: parsing shortcuts.
1.90      matthew   106: 
                    107: =over 4
                    108: 
                    109: =cut
                    110: 
                    111: ######################################################################
                    112: ######################################################################
                    113: 
                    114: 
1.1       www       115: package Apache::lonpublisher;
                    116: 
1.65      harris41  117: # ------------------------------------------------- modules used by this module
1.1       www       118: use strict;
                    119: use Apache::File;
1.13      www       120: use File::Copy;
1.2       www       121: use Apache::Constants qw(:common :http :methods);
1.76      albertel  122: use HTML::LCParser;
1.4       www       123: use Apache::lonxml;
1.17      albertel  124: use Apache::lonhomework;
1.27      www       125: use Apache::loncacc;
1.24      harris41  126: use DBI;
1.65      harris41  127: use Apache::lonnet();
                    128: use Apache::loncommon();
1.89      matthew   129: use Apache::lonmysql;
1.2       www       130: 
1.3       www       131: my %addid;
1.5       www       132: my %nokey;
1.10      www       133: 
1.7       www       134: my %metadatafields;
                    135: my %metadatakeys;
                    136: 
1.12      www       137: my $docroot;
                    138: 
1.27      www       139: my $cuname;
                    140: my $cudom;
                    141: 
1.90      matthew   142: #########################################
                    143: #########################################
                    144: 
                    145: =pod
                    146: 
1.94      harris41  147: =item B<metaeval>
                    148: 
                    149: Evaluates a string that contains metadata.  This subroutine
                    150: stores values inside I<%metadatafields> and I<%metadatakeys>.
                    151: The hash key is a I<$unikey> corresponding to a unique id
                    152: that is descriptive of the parser location inside the XML tree.
                    153: 
                    154: Parameters:
                    155: 
                    156: =over 4
1.90      matthew   157: 
1.94      harris41  158: =item I<$metastring>
                    159: 
                    160: A string that contains metadata.
                    161: 
                    162: =back
                    163: 
                    164: Returns:
                    165: 
                    166: nothing
1.90      matthew   167: 
                    168: =cut
                    169: 
                    170: #########################################
                    171: #########################################
1.7       www       172: sub metaeval {
                    173:     my $metastring=shift;
                    174:    
1.76      albertel  175:         my $parser=HTML::LCParser->new(\$metastring);
1.7       www       176:         my $token;
                    177:         while ($token=$parser->get_token) {
                    178:            if ($token->[0] eq 'S') {
                    179: 	      my $entry=$token->[1];
                    180:               my $unikey=$entry;
1.32      www       181:               if (defined($token->[2]->{'package'})) { 
                    182:                   $unikey.='_package_'.$token->[2]->{'package'};
                    183:               } 
1.7       www       184:               if (defined($token->[2]->{'part'})) { 
                    185:                  $unikey.='_'.$token->[2]->{'part'}; 
                    186: 	      }
1.32      www       187:               if (defined($token->[2]->{'id'})) { 
1.49      www       188:                   $unikey.='_'.$token->[2]->{'id'};
1.32      www       189:               } 
1.7       www       190:               if (defined($token->[2]->{'name'})) { 
                    191:                  $unikey.='_'.$token->[2]->{'name'}; 
                    192: 	      }
1.65      harris41  193:               foreach (@{$token->[3]}) {
1.7       www       194: 		  $metadatafields{$unikey.'.'.$_}=$token->[2]->{$_};
                    195:                   if ($metadatakeys{$unikey}) {
                    196: 		      $metadatakeys{$unikey}.=','.$_;
                    197:                   } else {
                    198:                       $metadatakeys{$unikey}=$_;
                    199:                   }
1.65      harris41  200:               }
1.7       www       201:               if ($metadatafields{$unikey}) {
1.8       www       202: 		  my $newentry=$parser->get_text('/'.$entry);
1.41      www       203:                   unless (($metadatafields{$unikey}=~/$newentry/) ||
                    204:                           ($newentry eq '')) {
1.8       www       205:                      $metadatafields{$unikey}.=', '.$newentry;
                    206: 		  }
1.7       www       207: 	      } else {
                    208:                  $metadatafields{$unikey}=$parser->get_text('/'.$entry);
                    209:               }
                    210:           }
                    211:        }
                    212: }
                    213: 
1.90      matthew   214: #########################################
                    215: #########################################
                    216: 
                    217: =pod
                    218: 
1.94      harris41  219: =item B<metaread>
1.90      matthew   220: 
                    221: Read a metadata file
                    222: 
1.94      harris41  223: Parameters:
                    224: 
                    225: =over
                    226: 
                    227: =item I<$logfile>
                    228: 
                    229: File output stream to output errors and warnings to.
                    230: 
                    231: =item I<$fn>
                    232: 
                    233: File name (including path).
                    234: 
                    235: =back
                    236: 
                    237: Returns:
                    238: 
                    239: =over 4
                    240: 
                    241: =item Scalar string (if successful)
                    242: 
                    243: XHTML text that indicates successful reading of the metadata.
                    244: 
                    245: =back
                    246: 
1.90      matthew   247: =cut
                    248: 
                    249: #########################################
                    250: #########################################
1.7       www       251: sub metaread {
                    252:     my ($logfile,$fn)=@_;
                    253:     unless (-e $fn) {
1.94      harris41  254: 	print($logfile 'No file '.$fn."\n");
1.7       www       255:         return '<br><b>No file:</b> <tt>'.$fn.'</tt>';
                    256:     }
1.94      harris41  257:     print($logfile 'Processing '.$fn."\n");
1.7       www       258:     my $metastring;
                    259:     {
                    260:      my $metafh=Apache::File->new($fn);
                    261:      $metastring=join('',<$metafh>);
                    262:     }
                    263:     &metaeval($metastring);
                    264:     return '<br><b>Processed file:</b> <tt>'.$fn.'</tt>';
                    265: }
                    266: 
1.90      matthew   267: #########################################
                    268: #########################################
                    269: 
                    270: =pod
                    271: 
1.94      harris41  272: =item B<sqltime>
1.90      matthew   273: 
                    274: Convert 'time' format into a datetime sql format
                    275: 
1.94      harris41  276: Parameters:
                    277: 
                    278: =over 4
                    279: 
                    280: =item I<$timef>
                    281: 
                    282: Seconds since 00:00:00 UTC, January 1, 1970.
                    283: 
                    284: =back
                    285: 
                    286: Returns:
                    287: 
                    288: =over 4
                    289: 
                    290: =item Scalar string
                    291: 
                    292: MySQL-compatible datetime string.
                    293: 
                    294: =back
                    295: 
1.90      matthew   296: =cut
                    297: 
                    298: #########################################
                    299: #########################################
1.25      harris41  300: sub sqltime {
1.70      harris41  301:     my $timef=shift @_;
1.25      harris41  302:     my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
1.70      harris41  303: 	localtime($timef);
1.25      harris41  304:     $mon++; $year+=1900;
                    305:     return "$year-$mon-$mday $hour:$min:$sec";
                    306: }
                    307: 
1.12      www       308: 
1.90      matthew   309: #########################################
                    310: #########################################
                    311: 
                    312: =pod
                    313: 
1.94      harris41  314: =item Form-field-generating subroutines.
                    315: 
                    316: For input parameters, these subroutines take in values
                    317: such as I<$name>, I<$value> and other form field metadata.
                    318: The output (scalar string that is returned) is an XHTML
                    319: string which presents the form field (foreseeably inside
                    320: <form></form> tags).
1.90      matthew   321: 
                    322: =over 4
                    323: 
1.94      harris41  324: =item B<textfield>
1.90      matthew   325: 
1.94      harris41  326: =item B<hiddenfield>
1.90      matthew   327: 
1.94      harris41  328: =item B<selectbox>
1.90      matthew   329: 
                    330: =back
                    331: 
                    332: =cut
                    333: 
                    334: #########################################
                    335: #########################################
1.8       www       336: sub textfield {
1.10      www       337:     my ($title,$name,$value)=@_;
1.8       www       338:     return "\n<p><b>$title:</b><br>".
1.94      harris41  339:            '<input type="text" name="'.$name.'" size=80 value="'.$value.'" />';
1.11      www       340: }
                    341: 
                    342: sub hiddenfield {
                    343:     my ($name,$value)=@_;
1.94      harris41  344:     return "\n".'<input type="hidden" name="'.$name.'" value="'.$value.'" />';
1.8       www       345: }
                    346: 
1.9       www       347: sub selectbox {
1.65      harris41  348:     my ($title,$name,$value,$functionref,@idlist)=@_;
                    349:     my $uctitle=uc($title);
                    350:     my $selout="\n<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:".
                    351: 	"</b></font><br />".'<select name="'.$name.'">';
                    352:     foreach (@idlist) {
                    353:         $selout.='<option value=\''.$_.'\'';
                    354:         if ($_ eq $value) {
                    355: 	    $selout.=' selected>'.&{$functionref}($_).'</option>';
                    356: 	}
                    357:         else {$selout.='>'.&{$functionref}($_).'</option>';}
                    358:     }
1.10      www       359:     return $selout.'</select>';
1.9       www       360: }
                    361: 
1.90      matthew   362: #########################################
                    363: #########################################
                    364: 
                    365: =pod
                    366: 
1.94      harris41  367: =item B<urlfixup>
1.90      matthew   368: 
                    369: Fix up a url?  First step of publication
1.12      www       370: 
1.90      matthew   371: =cut
                    372: 
                    373: #########################################
                    374: #########################################
1.34      www       375: sub urlfixup {
1.35      www       376:     my ($url,$target)=@_;
1.39      www       377:     unless ($url) { return ''; }
1.68      albertel  378:     #javascript code needs no fixing
                    379:     if ($url =~ /^javascript:/i) { return $url; }
1.69      albertel  380:     if ($url =~ /^mailto:/i) { return $url; }
1.68      albertel  381:     #internal document links need no fixing
                    382:     if ($url =~ /^\#/) { return $url; } 
1.35      www       383:     my ($host)=($url=~/(?:http\:\/\/)*([^\/]+)/);
1.65      harris41  384:     foreach (values %Apache::lonnet::hostname) {
1.35      www       385: 	if ($_ eq $host) {
                    386: 	    $url=~s/^http\:\/\///;
                    387:             $url=~s/^$host//;
                    388:         }
1.65      harris41  389:     }
1.40      www       390:     if ($url=~/^http\:\/\//) { return $url; }
1.35      www       391:     $url=~s/\~$cuname/res\/$cudom\/$cuname/;
1.71      www       392:     return $url;
                    393: }
                    394: 
1.90      matthew   395: #########################################
                    396: #########################################
                    397: 
                    398: =pod
                    399: 
1.94      harris41  400: =item B<absoluteurl>
1.90      matthew   401: 
1.94      harris41  402: Currently undocumented.
1.90      matthew   403: 
                    404: =cut
1.71      www       405: 
1.90      matthew   406: #########################################
                    407: #########################################
1.71      www       408: sub absoluteurl {
                    409:     my ($url,$target)=@_;
                    410:     unless ($url) { return ''; }
1.35      www       411:     if ($target) {
                    412: 	$target=~s/\/[^\/]+$//;
                    413:        $url=&Apache::lonnet::hreflocation($target,$url);
                    414:     }
                    415:     return $url;
1.34      www       416: }
                    417: 
1.90      matthew   418: #########################################
                    419: #########################################
                    420: 
                    421: =pod
                    422: 
1.94      harris41  423: =item B<set_allow>
1.90      matthew   424: 
                    425: Currently undocumented    
                    426: 
                    427: =cut
                    428: 
                    429: #########################################
                    430: #########################################
1.81      albertel  431: sub set_allow {
                    432:     my ($allow,$logfile,$target,$tag,$oldurl)=@_;
                    433:     my $newurl=&urlfixup($oldurl,$target);
                    434:     my $return_url=$oldurl;
                    435:     print $logfile 'GUYURL: '.$tag.':'.$oldurl.' - '.$newurl."\n";
                    436:     if ($newurl ne $oldurl) {
                    437: 	$return_url=$newurl;
                    438: 	print $logfile 'URL: '.$tag.':'.$oldurl.' - '.$newurl."\n";
                    439:     }
                    440:     if (($newurl !~ /^javascript:/i) &&
                    441: 	($newurl !~ /^mailto:/i) &&
                    442: 	($newurl !~ /^http:/i) &&
                    443: 	($newurl !~ /^\#/)) {
                    444: 	$$allow{&absoluteurl($newurl,$target)}=1;
                    445:     }
                    446:     return $return_url
                    447: }
                    448: 
1.90      matthew   449: #########################################
                    450: #########################################
                    451: 
                    452: =pod
                    453: 
1.94      harris41  454: =item B<get_subscribed_hosts>
1.90      matthew   455: 
                    456: Currently undocumented    
                    457: 
                    458: =cut
                    459: 
                    460: #########################################
                    461: #########################################
1.85      albertel  462: sub get_subscribed_hosts {
                    463:     my ($target)=@_;
                    464:     my @subscribed;
                    465:     my $filename;
                    466:     $target=~/(.*)\/([^\/]+)$/;
                    467:     my $srcf=$2;
                    468:     opendir(DIR,$1);
                    469:     while ($filename=readdir(DIR)) {
                    470: 	if ($filename=~/$srcf\.(\w+)$/) {
                    471: 	    my $subhost=$1;
1.98      www       472: 	    if (($subhost ne 'meta' && $subhost ne 'subscription') &&
                    473:                 ($subhost ne $Apache::lonnet::perlvar{'lonHostID'})) {
1.85      albertel  474: 		push(@subscribed,$subhost);
                    475: 	    }
                    476: 	}
                    477:     }
                    478:     closedir(DIR);
                    479:     my $sh;
                    480:     if ( $sh=Apache::File->new("$target.subscription") ) {
                    481: 	&Apache::lonnet::logthis("opened $target.subscription");
                    482: 	while (my $subline=<$sh>) {
                    483: 	    &Apache::lonnet::logthis("Trying $subline");
1.98      www       484: 	    if ($subline =~ /(^\w+):/) { 
                    485:                 if ($1 ne $Apache::lonnet::perlvar{'lonHostID'}) { 
                    486:                    push(@subscribed,$1);
                    487: 	        }
                    488:             } else {
1.85      albertel  489: 		&Apache::lonnet::logthis("No Match for $subline");
                    490: 	    }
                    491: 	}
                    492:     } else {
1.94      harris41  493: 	&Apache::lonnet::logthis("Unable to open $target.subscription");
1.85      albertel  494:     }
                    495:     &Apache::lonnet::logthis("Got list of ".join(':',@subscribed));
                    496:     return @subscribed;
                    497: }
                    498: 
1.86      albertel  499: 
1.90      matthew   500: #########################################
                    501: #########################################
                    502: 
                    503: =pod
                    504: 
1.94      harris41  505: =item B<get_max_ids_indices>
1.90      matthew   506: 
                    507: Currently undocumented    
                    508: 
                    509: =cut
                    510: 
                    511: #########################################
                    512: #########################################
1.86      albertel  513: sub get_max_ids_indices {
                    514:     my ($content)=@_;
                    515:     my $maxindex=10;
                    516:     my $maxid=10;
                    517:     my $needsfixup=0;
                    518: 
                    519:     my $parser=HTML::LCParser->new($content);
                    520:     my $token;
                    521:     while ($token=$parser->get_token) {
                    522: 	if ($token->[0] eq 'S') {
                    523: 	    my $counter;
                    524: 	    if ($counter=$addid{$token->[1]}) {
                    525: 		if ($counter eq 'id') {
                    526: 		    if (defined($token->[2]->{'id'})) {
                    527: 			$maxid=($token->[2]->{'id'}>$maxid)?$token->[2]->{'id'}:$maxid;
                    528: 		    } else {
                    529: 			$needsfixup=1;
                    530: 		    }
                    531: 		} else {
                    532: 		    if (defined($token->[2]->{'index'})) {
                    533: 			$maxindex=($token->[2]->{'index'}>$maxindex)?$token->[2]->{'index'}:$maxindex;
                    534: 		    } else {
                    535: 			$needsfixup=1;
                    536: 		    }
                    537: 		}
                    538: 	    }
                    539: 	}
                    540:     }
                    541:     return ($needsfixup,$maxid,$maxindex);
                    542: }
                    543: 
1.90      matthew   544: #########################################
                    545: #########################################
                    546: 
                    547: =pod
                    548: 
1.94      harris41  549: =item B<get_all_text_unbalanced>
1.90      matthew   550: 
                    551: Currently undocumented    
                    552: 
                    553: =cut
                    554: 
                    555: #########################################
                    556: #########################################
1.87      albertel  557: sub get_all_text_unbalanced {
                    558:     #there is a copy of this in lonxml.pm
                    559:     my($tag,$pars)= @_;
                    560:     my $token;
                    561:     my $result='';
                    562:     $tag='<'.$tag.'>';
                    563:     while ($token = $$pars[-1]->get_token) {
                    564: 	if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
                    565: 	    $result.=$token->[1];
                    566: 	} elsif ($token->[0] eq 'PI') {
                    567: 	    $result.=$token->[2];
                    568: 	} elsif ($token->[0] eq 'S') {
                    569: 	    $result.=$token->[4];
                    570: 	} elsif ($token->[0] eq 'E')  {
                    571: 	    $result.=$token->[2];
                    572: 	}
                    573: 	if ($result =~ /(.*)$tag(.*)/) {
1.88      albertel  574: 	    #&Apache::lonnet::logthis('Got a winner with leftovers ::'.$2);
                    575: 	    #&Apache::lonnet::logthis('Result is :'.$1);
1.87      albertel  576: 	    $result=$1;
                    577: 	    my $redo=$tag.$2;
                    578: 	    push (@$pars,HTML::LCParser->new(\$redo));
                    579: 	    $$pars[-1]->xml_mode('1');
                    580: 	    last;
                    581: 	}
                    582:     }
                    583:     return $result
                    584: }
                    585: 
1.90      matthew   586: #########################################
                    587: #########################################
                    588: 
                    589: =pod
                    590: 
1.94      harris41  591: =item B<fix_ids_and_indices>
1.90      matthew   592: 
                    593: Currently undocumented    
                    594: 
                    595: =cut
                    596: 
                    597: #########################################
                    598: #########################################
1.87      albertel  599: #Arguably this should all be done as a lonnet::ssi instead
1.86      albertel  600: sub fix_ids_and_indices {
                    601:     my ($logfile,$source,$target)=@_;
                    602: 
                    603:     my %allow;
                    604:     my $content;
                    605:     {
                    606: 	my $org=Apache::File->new($source);
                    607: 	$content=join('',<$org>);
                    608:     }
                    609: 
                    610:     my ($needsfixup,$maxid,$maxindex)=&get_max_ids_indices(\$content);
                    611: 
                    612:     if ($needsfixup) {
                    613: 	print $logfile "Needs ID and/or index fixup\n".
                    614: 	    "Max ID   : $maxid (min 10)\n".
                    615:                 "Max Index: $maxindex (min 10)\n";
                    616:     }
                    617:     my $outstring='';
                    618:     my @parser;
                    619:     $parser[0]=HTML::LCParser->new(\$content);
                    620:     $parser[-1]->xml_mode(1);
                    621:     my $token;
                    622:     while (@parser) {
                    623: 	while ($token=$parser[-1]->get_token) {
                    624: 	    if ($token->[0] eq 'S') {
                    625: 		my $counter;
                    626: 		my $tag=$token->[1];
                    627: 		my $lctag=lc($tag);
                    628: 		if ($lctag eq 'allow') {
                    629: 		    $allow{$token->[2]->{'src'}}=1;
                    630: 		    next;
                    631: 		}
                    632: 		my %parms=%{$token->[2]};
                    633: 		$counter=$addid{$tag};
                    634: 		if (!$counter) { $counter=$addid{$lctag}; }
                    635: 		if ($counter) {
                    636: 		    if ($counter eq 'id') {
                    637: 			unless (defined($parms{'id'})) {
                    638: 			    $maxid++;
                    639: 			    $parms{'id'}=$maxid;
                    640: 			    print $logfile 'ID: '.$tag.':'.$maxid."\n";
                    641: 			}
                    642: 		    } elsif ($counter eq 'index') {
                    643: 			unless (defined($parms{'index'})) {
                    644: 			    $maxindex++;
                    645: 			    $parms{'index'}=$maxindex;
                    646: 			    print $logfile 'Index: '.$tag.':'.$maxindex."\n";
                    647: 			}
                    648: 		    }
                    649: 		}
                    650: 		foreach my $type ('src','href','background','bgimg') {
                    651: 		    foreach my $key (keys(%parms)) {
                    652: 			if ($key =~ /^$type$/i) {
                    653: 			    $parms{$key}=&set_allow(\%allow,$logfile,
                    654: 						    $target,$tag,
                    655: 						    $parms{$key});
                    656: 			}
                    657: 		    }
                    658: 		}
                    659: 		# probably a <randomlabel> image type <label>
                    660: 		if ($lctag eq 'label' && defined($parms{'description'})) {
                    661: 		    my $next_token=$parser[-1]->get_token();
                    662: 		    if ($next_token->[0] eq 'T') {
                    663: 			$next_token->[1]=&set_allow(\%allow,$logfile,
                    664: 						    $target,$tag,
                    665: 						    $next_token->[1]);
                    666: 		    }
                    667: 		    $parser[-1]->unget_token($next_token);
                    668: 		}
                    669: 		if ($lctag eq 'applet') {
                    670: 		    my $codebase='';
                    671: 		    if (defined($parms{'codebase'})) {
                    672: 			my $oldcodebase=$parms{'codebase'};
                    673: 			unless ($oldcodebase=~/\/$/) {
                    674: 			    $oldcodebase.='/';
                    675: 			}
                    676: 			$codebase=&urlfixup($oldcodebase,$target);
                    677: 			$codebase=~s/\/$//;    
                    678: 			if ($codebase ne $oldcodebase) {
                    679: 			    $parms{'codebase'}=$codebase;
                    680: 			    print $logfile 'URL codebase: '.$tag.':'.
                    681: 				$oldcodebase.' - '.
                    682: 				    $codebase."\n";
                    683: 			}
                    684: 			$allow{&absoluteurl($codebase,$target).'/*'}=1;
                    685: 		    } else {
                    686: 			foreach ('archive','code','object') {
                    687: 			    if (defined($parms{$_})) {
                    688: 				my $oldurl=$parms{$_};
                    689: 				my $newurl=&urlfixup($oldurl,$target);
                    690: 				$newurl=~s/\/[^\/]+$/\/\*/;
                    691: 				print $logfile 'Allow: applet '.$_.':'.
                    692: 				    $oldurl.' allows '.
                    693: 					$newurl."\n";
                    694: 				$allow{&absoluteurl($newurl,$target)}=1;
                    695: 			    }
                    696: 			}
                    697: 		    }
                    698: 		}
                    699: 		my $newparmstring='';
                    700: 		my $endtag='';
                    701: 		foreach (keys %parms) {
                    702: 		    if ($_ eq '/') {
                    703: 			$endtag=' /';
                    704: 		    } else { 
                    705: 			my $quote=($parms{$_}=~/\"/?"'":'"');
                    706: 			$newparmstring.=' '.$_.'='.$quote.$parms{$_}.$quote;
                    707: 		    }
                    708: 		}
                    709: 		if (!$endtag) { if ($token->[4]=~m:/>$:) { $endtag=' /'; }; }
                    710: 		$outstring.='<'.$tag.$newparmstring.$endtag.'>';
1.87      albertel  711: 		if ($lctag eq 'm') {
                    712: 		    $outstring.=&get_all_text_unbalanced('/m',\@parser);
                    713: 		}
1.86      albertel  714: 	    } elsif ($token->[0] eq 'E') {
                    715: 		if ($token->[2]) {
                    716: 		    unless ($token->[1] eq 'allow') {
                    717: 			$outstring.='</'.$token->[1].'>';
                    718: 		    }
                    719: 		}
                    720: 	    } else {
                    721: 		$outstring.=$token->[1];
                    722: 	    }
                    723: 	}
                    724: 	pop(@parser);
                    725:     }
                    726: 
                    727:     if ($needsfixup) {
                    728: 	print $logfile "End of ID and/or index fixup\n".
                    729: 	    "Max ID   : $maxid (min 10)\n".
                    730: 		"Max Index: $maxindex (min 10)\n";
                    731:     } else {
                    732: 	print $logfile "Does not need ID and/or index fixup\n";
                    733:     }
                    734: 
                    735:     return ($outstring,%allow);
                    736: }
                    737: 
1.89      matthew   738: #########################################
                    739: #########################################
                    740: 
                    741: =pod
                    742: 
1.94      harris41  743: =item B<store_metadata>
1.89      matthew   744: 
                    745: Store the metadata in the metadata table in the loncapa database.
                    746: Uses lonmysql to access the database.
                    747: 
                    748: Inputs: \%metadata
                    749: 
                    750: Returns: (error,status).  error is undef on success, status is undef on error.
                    751: 
                    752: =cut
                    753: 
                    754: #########################################
                    755: #########################################
                    756: sub store_metadata {
                    757:     my %metadata = %{shift()};
                    758:     my $error;
                    759:     # Determine if the table exists
                    760:     my $status = &Apache::lonmysql::check_table('metadata');
                    761:     if (! defined($status)) {
                    762:         $error='<font color="red">WARNING: Cannot connect to '.
                    763:             'database!</font>';
                    764:         &Apache::lonnet::logthis($error);
                    765:         return ($error,undef);
                    766:     }
                    767:     if ($status == 0) {
                    768:         # It would be nice to actually create the table....
                    769:         $error ='<font color="red">WARNING: The metadata table does not '.
                    770:             'exist in the LON-CAPA database.</font>';
                    771:         &Apache::lonnet::logthis($error);
                    772:         return ($error,undef);
                    773:     }
                    774:     # Remove old value from table
                    775:     $status = &Apache::lonmysql::remove_from_table
                    776:         ('metadata','url',$metadata{'url'});
                    777:     if (! defined($status)) {
                    778:         $error = '<font color="red">Error when removing old values from '.
                    779:             'metadata table in LON-CAPA database.</font>';
                    780:         &Apache::lonnet::logthis($error);
                    781:         return ($error,undef);
                    782:     }
                    783:     # Store data in table.
                    784:     $status = &Apache::lonmysql::store_row('metadata',\%metadata);
                    785:     if (! defined($status)) {
                    786:         $error='<font color="red">Error occured storing new values in '.
                    787:             'metadata table in LON-CAPA database</font>';
                    788:         &Apache::lonnet::logthis($error);
                    789:         return ($error,undef);
                    790:     }
                    791:     return (undef,$status);
                    792: }
                    793: 
1.90      matthew   794: #########################################
                    795: #########################################
                    796: 
                    797: =pod
                    798: 
1.94      harris41  799: =item B<publish>
                    800: 
                    801: This is the workhorse function of this module.  This subroutine generates
                    802: backup copies, performs any automatic processing (prior to publication,
                    803: especially for rat and ssi files),
1.90      matthew   804: 
1.94      harris41  805: I<Additional documentation needed.>
1.90      matthew   806: 
                    807: =cut
                    808: 
                    809: #########################################
                    810: #########################################
1.2       www       811: sub publish {
1.50      www       812: 
1.97      www       813:     my ($source,$target,$style,$batch)=@_;
1.2       www       814:     my $logfile;
1.4       www       815:     my $scrout='';
1.23      www       816:     my $allmeta='';
                    817:     my $content='';
1.36      www       818:     my %allow=();
1.4       www       819: 
1.2       www       820:     unless ($logfile=Apache::File->new('>>'.$source.'.log')) {
1.7       www       821: 	return 
                    822:          '<font color=red>No write permission to user directory, FAIL</font>';
1.2       www       823:     }
                    824:     print $logfile 
1.11      www       825: "\n\n================= Publish ".localtime()." Phase One  ================\n";
1.2       www       826: 
1.3       www       827:     if (($style eq 'ssi') || ($style eq 'rat')) {
                    828: # ------------------------------------------------------- This needs processing
1.4       www       829: 
                    830: # ----------------------------------------------------------------- Backup Copy
1.3       www       831: 	my $copyfile=$source.'.save';
1.13      www       832:         if (copy($source,$copyfile)) {
1.3       www       833: 	    print $logfile "Copied original file to ".$copyfile."\n";
                    834:         } else {
1.13      www       835: 	    print $logfile "Unable to write backup ".$copyfile.':'.$!."\n";
                    836:           return "<font color=red>Failed to write backup copy, $!,FAIL</font>";
1.3       www       837:         }
1.4       www       838: # ------------------------------------------------------------- IDs and indices
1.86      albertel  839: 	
                    840: 	my $outstring;
                    841: 	($outstring,%allow)=&fix_ids_and_indices($logfile,$source,$target);
1.36      www       842: # ------------------------------------------------------------ Construct Allows
1.62      www       843:     
1.44      www       844: 	$scrout.='<h3>Dependencies</h3>';
1.62      www       845:         my $allowstr='';
1.73      albertel  846:         foreach (sort(keys(%allow))) {
1.59      www       847: 	   my $thisdep=$_;
1.73      albertel  848: 	   if ($thisdep !~ /[^\s]/) { next; }
1.62      www       849:            unless ($style eq 'rat') { 
                    850:               $allowstr.="\n".'<allow src="'.$thisdep.'" />';
                    851: 	   }
1.44      www       852:            $scrout.='<br>';
1.59      www       853:            unless ($thisdep=~/\*/) {
                    854: 	       $scrout.='<a href="'.$thisdep.'">';
1.44      www       855:            }
1.59      www       856:            $scrout.='<tt>'.$thisdep.'</tt>';
                    857:            unless ($thisdep=~/\*/) {
1.44      www       858: 	       $scrout.='</a>';
1.59      www       859:                if (
                    860:        &Apache::lonnet::getfile($Apache::lonnet::perlvar{'lonDocRoot'}.'/'.
                    861:                                             $thisdep.'.meta') eq '-1') {
1.94      harris41  862: 		   $scrout.= ' - <font color="red">Currently not available'.
                    863: 		       '</font>';
1.59      www       864:                } else {
                    865:                    my %temphash=(&Apache::lonnet::declutter($target).'___'.
                    866:                              &Apache::lonnet::declutter($thisdep).'___usage'
                    867:                                  => time);
                    868:                    $thisdep=~/^\/res\/(\w+)\/(\w+)\//;
                    869:                    if ((defined($1)) && (defined($2))) {
1.92      albertel  870:                       &Apache::lonnet::put('nohist_resevaldata',\%temphash,
                    871: 					   $1,$2);
1.59      www       872: 		   }
                    873: 	       }
1.44      www       874:            }
1.65      harris41  875:         }
1.83      www       876:         $outstring=~s/\n*(\<\/[^\>]+\>)\s*$/$allowstr\n$1\n/s;
1.62      www       877: 
1.76      albertel  878: 	#Encode any High ASCII characters
                    879: 	$outstring=&HTML::Entities::encode($outstring,"\200-\377");
1.94      harris41  880: # ------------------------------------------------------------- Write modified.
1.37      www       881: 
1.4       www       882:         {
                    883:           my $org;
                    884:           unless ($org=Apache::File->new('>'.$source)) {
                    885:              print $logfile "No write permit to $source\n";
1.7       www       886:              return 
1.94      harris41  887: 		 '<font color="red">No write permission to '.$source.
                    888: 		 ', FAIL</font>';
1.4       www       889: 	  }
1.94      harris41  890:           print($org $outstring);
1.4       www       891:         }
                    892: 	  $content=$outstring;
1.34      www       893: 
1.37      www       894:     }
1.94      harris41  895: # -------------------------------------------- Initial step done, now metadata.
1.7       www       896: 
1.94      harris41  897: # --------------------------------------- Storage for metadata keys and fields.
1.7       www       898: 
1.8       www       899:      %metadatafields=();
                    900:      %metadatakeys=();
                    901:      
                    902:      my %oldparmstores=();
1.44      www       903:      
1.97      www       904:     unless ($batch) {
1.84      bowersj2  905:      $scrout.='<h3>Metadata Information ' .
                    906:        Apache::loncommon::help_open_topic("Metadata_Description")
                    907:        . '</h3>';
1.97      www       908:     }
1.7       www       909: 
                    910: # ------------------------------------------------ First, check out environment
1.8       www       911:      unless (-e $source.'.meta') {
1.7       www       912:         $metadatafields{'author'}=$ENV{'environment.firstname'}.' '.
                    913: 	                          $ENV{'environment.middlename'}.' '.
                    914: 		                  $ENV{'environment.lastname'}.' '.
                    915: 		                  $ENV{'environment.generation'};
1.8       www       916:         $metadatafields{'author'}=~s/\s+/ /g;
                    917:         $metadatafields{'author'}=~s/\s+$//;
1.27      www       918:         $metadatafields{'owner'}=$cuname.'@'.$cudom;
1.7       www       919: 
                    920: # ------------------------------------------------ Check out directory hierachy
                    921: 
                    922:         my $thisdisfn=$source;
1.27      www       923:         $thisdisfn=~s/^\/home\/$cuname\///;
1.7       www       924: 
                    925:         my @urlparts=split(/\//,$thisdisfn);
                    926:         $#urlparts--;
                    927: 
1.27      www       928:         my $currentpath='/home/'.$cuname.'/';
1.7       www       929: 
1.65      harris41  930:         foreach (@urlparts) {
1.7       www       931: 	    $currentpath.=$_.'/';
                    932:             $scrout.=&metaread($logfile,$currentpath.'default.meta');
1.65      harris41  933:         }
1.7       www       934: 
                    935: # ------------------- Clear out parameters and stores (there should not be any)
                    936: 
1.65      harris41  937:         foreach (keys %metadatafields) {
1.7       www       938: 	    if (($_=~/^parameter/) || ($_=~/^stores/)) {
                    939: 		delete $metadatafields{$_};
                    940:             }
1.65      harris41  941:         }
1.7       www       942: 
1.8       www       943:     } else {
1.7       www       944: # ---------------------- Read previous metafile, remember parameters and stores
                    945: 
                    946:         $scrout.=&metaread($logfile,$source.'.meta');
                    947: 
1.65      harris41  948:         foreach (keys %metadatafields) {
1.7       www       949: 	    if (($_=~/^parameter/) || ($_=~/^stores/)) {
                    950:                 $oldparmstores{$_}=1;
                    951: 		delete $metadatafields{$_};
                    952:             }
1.65      harris41  953:         }
1.7       www       954:         
1.8       www       955:     }
1.7       www       956: 
1.4       www       957: # -------------------------------------------------- Parse content for metadata
1.37      www       958:     if ($style eq 'ssi') {
1.42      www       959:         my $oldenv=$ENV{'request.uri'};
                    960: 
                    961:         $ENV{'request.uri'}=$target;
1.82      albertel  962:         $allmeta=Apache::lonxml::xmlparse(undef,'meta',$content);
1.42      www       963:         $ENV{'request.uri'}=$oldenv;
1.32      www       964: 
1.19      albertel  965:         &metaeval($allmeta);
1.37      www       966:     }
1.7       www       967: # ---------------- Find and document discrepancies in the parameters and stores
                    968: 
                    969:         my $chparms='';
1.65      harris41  970:         foreach (sort keys %metadatafields) {
1.7       www       971: 	    if (($_=~/^parameter/) || ($_=~/^stores/)) {
                    972:                 unless ($_=~/\.\w+$/) { 
                    973:                    unless ($oldparmstores{$_}) {
                    974: 		      print $logfile 'New: '.$_."\n";
                    975:                       $chparms.=$_.' ';
                    976:                    }
                    977: 	        }
                    978:             }
1.65      harris41  979:         }
1.7       www       980:         if ($chparms) {
                    981: 	    $scrout.='<p><b>New parameters or stored values:</b> '.
                    982:                      $chparms;
                    983:         }
                    984: 
1.70      harris41  985:         $chparms='';
1.65      harris41  986:         foreach (sort keys %oldparmstores) {
1.7       www       987: 	    if (($_=~/^parameter/) || ($_=~/^stores/)) {
1.33      www       988:                 unless (($metadatafields{$_.'.name'}) ||
                    989:                         ($metadatafields{$_.'.package'}) || ($_=~/\.\w+$/)) {
1.7       www       990: 		    print $logfile 'Obsolete: '.$_."\n";
                    991:                     $chparms.=$_.' ';
                    992:                 }
                    993:             }
1.65      harris41  994:         }
1.7       www       995:         if ($chparms) {
                    996: 	    $scrout.='<p><b>Obsolete parameters or stored values:</b> '.
                    997:                      $chparms;
                    998:         }
1.37      www       999: 
1.8       www      1000: # ------------------------------------------------------- Now have all metadata
1.5       www      1001: 
1.97      www      1002:         my %keywords=();
                   1003:         
                   1004: 	if (length($content)<500000) {
                   1005: 	    my $textonly=$content;
                   1006:             $textonly=~s/\<script[^\<]+\<\/script\>//g;
                   1007:             $textonly=~s/\<m\>[^\<]+\<\/m\>//g;
                   1008:             $textonly=~s/\<[^\>]*\>//g;
                   1009:             $textonly=~tr/A-Z/a-z/;
                   1010:             $textonly=~s/[\$\&][a-z]\w*//g;
                   1011:             $textonly=~s/[^a-z\s]//g;
                   1012: 
                   1013:             foreach ($textonly=~m/(\w+)/g) {
                   1014: 		unless ($nokey{$_}) {
                   1015:                    $keywords{$_}=1;
                   1016:                 } 
                   1017:             }
                   1018:         }
                   1019: 
                   1020:             
                   1021:             foreach (split(/\W+/,$metadatafields{'keywords'})) {
                   1022: 		$keywords{$_}=1;
                   1023:             }
                   1024: # --------------------------------------------------- Now we also have keywords
                   1025: # =============================================================================
                   1026: # INTERACTIVE MODE
                   1027: #
                   1028:    unless ($batch) {
1.8       www      1029:         $scrout.=
1.77      matthew  1030:      '<form name="pubform" action="/adm/publish" method="post">'.
1.63      albertel 1031:        '<p><input type="submit" value="Finalize Publication" /></p>'.
1.11      www      1032:           &hiddenfield('phase','two').
                   1033:           &hiddenfield('filename',$ENV{'form.filename'}).
                   1034: 	  &hiddenfield('allmeta',&Apache::lonnet::escape($allmeta)).
1.58      www      1035:           &hiddenfield('dependencies',join(',',keys %allow)).
1.10      www      1036:           &textfield('Title','title',$metadatafields{'title'}).
                   1037:           &textfield('Author(s)','author',$metadatafields{'author'}).
                   1038: 	  &textfield('Subject','subject',$metadatafields{'subject'});
1.5       www      1039: 
                   1040: # --------------------------------------------------- Scan content for keywords
1.7       www      1041: 
1.84      bowersj2 1042:         my $keywords_help = Apache::loncommon::help_open_topic("Publishing_Keywords");
1.77      matthew  1043: 	my $keywordout=<<"END";
                   1044: <script>
                   1045: function checkAll(field)
                   1046: {
                   1047:     for (i = 0; i < field.length; i++)
                   1048:         field[i].checked = true ;
                   1049: }
                   1050: 
                   1051: function uncheckAll(field)
                   1052: {
                   1053:     for (i = 0; i < field.length; i++)
                   1054:         field[i].checked = false ;
                   1055: }
                   1056: </script>
1.84      bowersj2 1057: <p><b>Keywords: $keywords_help</b> 
1.77      matthew  1058: <input type="button" value="check all" onclick="javascript:checkAll(document.pubform.keywords)"> 
                   1059: <input type="button" value="uncheck all" onclick="javascript:uncheckAll(document.pubform.keywords)"> 
                   1060: <br />
                   1061: END
                   1062:         $keywordout.='<table border=2><tr>';
1.7       www      1063:         my $colcount=0;
1.5       www      1064: 
1.65      harris41 1065:             foreach (sort keys %keywords) {
1.77      matthew  1066:                 $keywordout.='<td><input type=checkbox name="keywords" value="'.$_.'"';
1.67      www      1067:                 if ($metadatafields{'keywords'}) {
                   1068:                    if ($metadatafields{'keywords'}=~/$_/) { 
                   1069:                       $keywordout.=' checked'; 
                   1070:                    }
                   1071: 	        } elsif (&Apache::loncommon::keyword($_)) {
1.73      albertel 1072: 	            $keywordout.=' checked';
1.67      www      1073:                 } 
1.8       www      1074:                 $keywordout.='>'.$_.'</td>';
1.7       www      1075:                 if ($colcount>10) {
                   1076: 		    $keywordout.="</tr><tr>\n";
                   1077:                     $colcount=0;
                   1078:                 }
1.50      www      1079:                 $colcount++;
1.65      harris41 1080:             }
1.50      www      1081:         
1.51      www      1082: 	$keywordout.='</tr></table>';
                   1083: 
                   1084:         $scrout.=$keywordout;
1.9       www      1085: 
1.12      www      1086:         $scrout.=&textfield('Additional Keywords','addkey','');
                   1087: 
1.10      www      1088:         $scrout.=&textfield('Notes','notes',$metadatafields{'notes'});
1.9       www      1089: 
                   1090:         $scrout.=
                   1091:              '<p><b>Abstract:</b><br><textarea cols=80 rows=5 name=abstract>'.
                   1092:               $metadatafields{'abstract'}.'</textarea>';
                   1093: 
1.11      www      1094: 	$source=~/\.(\w+)$/;
                   1095: 
                   1096: 	$scrout.=&hiddenfield('mime',$1);
                   1097: 
1.10      www      1098:         $scrout.=&selectbox('Language','language',
1.65      harris41 1099:                             $metadatafields{'language'},
1.70      harris41 1100: 			    \&Apache::loncommon::languagedescription,
1.65      harris41 1101: 			    (&Apache::loncommon::languageids),
                   1102: 			     );
1.11      www      1103: 
                   1104:         unless ($metadatafields{'creationdate'}) {
                   1105: 	    $metadatafields{'creationdate'}=time;
                   1106:         }
                   1107:         $scrout.=&hiddenfield('creationdate',$metadatafields{'creationdate'});
                   1108: 
                   1109:         $scrout.=&hiddenfield('lastrevisiondate',time);
                   1110: 
1.9       www      1111: 			   
1.10      www      1112: 	$scrout.=&textfield('Publisher/Owner','owner',
                   1113:                             $metadatafields{'owner'});
1.84      bowersj2 1114: 
1.94      harris41 1115: # -------------------------------------------------- Correct copyright for rat.
1.45      www      1116:     if ($style eq 'rat') {
1.65      harris41 1117: 	if ($metadatafields{'copyright'} eq 'public') { 
                   1118: 	    delete $metadatafields{'copyright'};
                   1119: 	}
                   1120:         $scrout.=&selectbox('Copyright/Distribution','copyright',
                   1121:                             $metadatafields{'copyright'},
1.70      harris41 1122: 			    \&Apache::loncommon::copyrightdescription,
1.65      harris41 1123: 		     (grep !/^public$/,(&Apache::loncommon::copyrightids)));
                   1124:     }
                   1125:     else {
1.10      www      1126:         $scrout.=&selectbox('Copyright/Distribution','copyright',
1.65      harris41 1127:                             $metadatafields{'copyright'},
1.70      harris41 1128: 			    \&Apache::loncommon::copyrightdescription,
1.65      harris41 1129: 			     (&Apache::loncommon::copyrightids));
                   1130:     }
1.84      bowersj2 1131: 
1.94      harris41 1132:     my $copyright_help =
                   1133:         Apache::loncommon::help_open_topic('Publishing_Copyright');
1.84      bowersj2 1134:     $scrout =~ s/DISTRIBUTION:/'DISTRIBUTION: ' . $copyright_help/ge;
1.8       www      1135:     return $scrout.
1.94      harris41 1136:         '<p><input type="submit" value="Finalize Publication" /></p></form>';
1.97      www      1137: # =============================================================================
                   1138: # BATCH MODE
                   1139: #
                   1140:   } else {
                   1141: # Transfer metadata directly to environment for stage 2
                   1142:     foreach (keys %metadatafields) {
                   1143: 	$ENV{'form.'.$_}=$metadatafields{$_};
                   1144:     }
                   1145:     $ENV{'form.addkey'}='';
                   1146:     $ENV{'form.keywords'}='';
                   1147:     foreach (keys %keywords) {
                   1148:         if ($metadatafields{'keywords'}) {
                   1149:            if ($metadatafields{'keywords'}=~/$_/) { 
                   1150:               $ENV{'form.keywords'}.=$_.','; 
                   1151:            }
                   1152: 	} elsif (&Apache::loncommon::keyword($_)) {
                   1153: 	    $ENV{'form.keywords'}.=$_.',';
                   1154:         } 
                   1155:     }
                   1156:     $ENV{'form.keywords'}=~s/\,$//;
                   1157:     unless ($ENV{'form.creationdate'}) { $ENV{'form.creationdate'}=time; }
                   1158:     $ENV{'form.lastrevisiondate'}=time;
                   1159:     if ((($style eq 'rat') && ($ENV{'form.copyright'} eq 'public')) ||
                   1160:         (!$ENV{'form.copyright'})) { 
                   1161: 	$ENV{'form.copyright'}='default';
                   1162:     } 
                   1163:     $ENV{'form.allmeta'}=&Apache::lonnet::escape($allmeta);
                   1164:     return $scrout;
                   1165:   }
1.2       www      1166: }
1.1       www      1167: 
1.90      matthew  1168: #########################################
                   1169: #########################################
                   1170: 
                   1171: =pod 
                   1172: 
1.94      harris41 1173: =item B<phasetwo>
1.90      matthew  1174: 
                   1175: Render second interface showing status of publication steps.
                   1176: This is publication step two.
                   1177: 
1.94      harris41 1178: Parameters:
                   1179: 
                   1180: =over 4
                   1181: 
                   1182: =item I<$source>
                   1183: 
                   1184: =item I<$target>
                   1185: 
                   1186: =item I<$style>
                   1187: 
                   1188: =item I<$distarget>
                   1189: 
                   1190: =back
                   1191: 
                   1192: Returns:
                   1193: 
                   1194: =over 4
                   1195: 
                   1196: =item Scalar string
                   1197: 
                   1198: String contains status (errors and warnings) and information associated with
1.100   ! matthew  1199: the server's attempts at publication.     
1.94      harris41 1200: 
1.90      matthew  1201: =cut
1.12      www      1202: 
1.100   ! matthew  1203: #'stupid emacs
1.90      matthew  1204: #########################################
                   1205: #########################################
1.11      www      1206: sub phasetwo {
                   1207: 
1.100   ! matthew  1208:     my ($r,$source,$target,$style,$distarget,$batch)=@_;
1.11      www      1209:     my $logfile;
                   1210:     unless ($logfile=Apache::File->new('>>'.$source.'.log')) {
                   1211: 	return 
1.100   ! matthew  1212:             '<font color=red>No write permission to user directory, FAIL</font>';
1.11      www      1213:     }
                   1214:     print $logfile 
1.100   ! matthew  1215:         "\n================= Publish ".localtime()." Phase Two  ================\n";
        !          1216:     
        !          1217:     %metadatafields=();
        !          1218:     %metadatakeys=();
        !          1219:     
        !          1220:     &metaeval(&Apache::lonnet::unescape($ENV{'form.allmeta'}));
        !          1221:     
        !          1222:     $metadatafields{'title'}=$ENV{'form.title'};
        !          1223:     $metadatafields{'author'}=$ENV{'form.author'};
        !          1224:     $metadatafields{'subject'}=$ENV{'form.subject'};
        !          1225:     $metadatafields{'notes'}=$ENV{'form.notes'};
        !          1226:     $metadatafields{'abstract'}=$ENV{'form.abstract'};
        !          1227:     $metadatafields{'mime'}=$ENV{'form.mime'};
        !          1228:     $metadatafields{'language'}=$ENV{'form.language'};
        !          1229:     $metadatafields{'creationdate'}=
        !          1230:         &sqltime($ENV{'form.creationdate'});
        !          1231:     $metadatafields{'lastrevisiondate'}=
        !          1232:         &sqltime($ENV{'form.lastrevisiondate'});
        !          1233:     $metadatafields{'owner'}=$ENV{'form.owner'};
        !          1234:     $metadatafields{'copyright'}=$ENV{'form.copyright'};
        !          1235:     $metadatafields{'dependencies'}=$ENV{'form.dependencies'};
        !          1236:     
        !          1237:     my $allkeywords=$ENV{'form.addkey'};
        !          1238:     if (exists($ENV{'form.keywords'})) {
        !          1239:         if (ref($ENV{'form.keywords'})) {
        !          1240:             $allkeywords .= ','.join(',',@{$ENV{'form.keywords'}});
        !          1241:         } else {
        !          1242:             $allkeywords .= ','.$ENV{'form.keywords'};
        !          1243:         }
        !          1244:     }
        !          1245:     $allkeywords=~s/\W+/\,/;
        !          1246:     $allkeywords=~s/^\,//;
        !          1247:     $metadatafields{'keywords'}=$allkeywords;
        !          1248:     
        !          1249:     {
        !          1250:         print $logfile "\nWrite metadata file for ".$source;
        !          1251:         my $mfh;
        !          1252:         unless ($mfh=Apache::File->new('>'.$source.'.meta')) {
        !          1253:             return 
        !          1254:                 '<font color=red>Could not write metadata, FAIL</font>';
        !          1255:         }
        !          1256:         foreach (sort keys %metadatafields) {
        !          1257:             unless ($_=~/\./) {
        !          1258:                 my $unikey=$_;
        !          1259:                 $unikey=~/^([A-Za-z]+)/;
        !          1260:                 my $tag=$1;
        !          1261:                 $tag=~tr/A-Z/a-z/;
        !          1262:                 print $mfh "\n\<$tag";
        !          1263:                 foreach (split(/\,/,$metadatakeys{$unikey})) {
        !          1264:                     my $value=$metadatafields{$unikey.'.'.$_};
        !          1265:                     $value=~s/\"/\'\'/g;
        !          1266:                     print $mfh ' '.$_.'="'.$value.'"';
        !          1267:                 }
        !          1268:                 print $mfh '>'.
        !          1269:                     &HTML::Entities::encode($metadatafields{$unikey})
        !          1270:                         .'</'.$tag.'>';
        !          1271:             }
        !          1272:         }
        !          1273:         $r->print('<p>Wrote Metadata');
        !          1274:         print $logfile "\nWrote metadata";
        !          1275:     }
        !          1276:     
        !          1277: # -------------------------------- Synchronize entry with SQL metadata database
1.12      www      1278: 
1.89      matthew  1279:     $metadatafields{'url'} = $distarget;
                   1280:     $metadatafields{'version'} = 'current';
                   1281:     unless ($metadatafields{'copyright'} eq 'priv') {
                   1282:         my ($error,$success) = &store_metadata(\%metadatafields);
1.91      matthew  1283:         if ($success) {
1.100   ! matthew  1284:             $r->print('<p>Synchronized SQL metadata database');
1.89      matthew  1285:             print $logfile "\nSynchronized SQL metadata database";
                   1286:         } else {
1.100   ! matthew  1287:             $r->print($error);
1.89      matthew  1288:             print $logfile "\n".$error;
                   1289:         }
                   1290:     } else {
1.100   ! matthew  1291:         $r->print('<p>Private Publication - did not synchronize database');
1.89      matthew  1292:         print $logfile "\nPrivate: Did not synchronize data into ".
                   1293:             "SQL metadata database";
1.24      harris41 1294:     }
1.12      www      1295: # ----------------------------------------------------------- Copy old versions
                   1296:    
1.100   ! matthew  1297:     if (-e $target) {
        !          1298:         my $filename;
        !          1299:         my $maxversion=0;
        !          1300:         $target=~/(.*)\/([^\/]+)\.(\w+)$/;
        !          1301:         my $srcf=$2;
        !          1302:         my $srct=$3;
        !          1303:         my $srcd=$1;
        !          1304:         unless ($srcd=~/^\/home\/httpd\/html\/res/) {
        !          1305:             print $logfile "\nPANIC: Target dir is ".$srcd;
        !          1306:             return "<font color=red>Invalid target directory, FAIL</font>";
        !          1307:         }
        !          1308:         opendir(DIR,$srcd);
        !          1309:         while ($filename=readdir(DIR)) {
        !          1310:             if (-l $srcd.'/'.$filename) {
        !          1311:                 unlink($srcd.'/'.$filename);
        !          1312:                 unlink($srcd.'/'.$filename.'.meta');
        !          1313:             } else {
        !          1314:                 if ($filename=~/$srcf\.(\d+)\.$srct$/) {
        !          1315:                     $maxversion=($1>$maxversion)?$1:$maxversion;
        !          1316:                 }
        !          1317:             }
        !          1318:         }
        !          1319:         closedir(DIR);
        !          1320:         $maxversion++;
        !          1321:         $r->print('<p>Creating old version '.$maxversion);
        !          1322:         print $logfile "\nCreating old version ".$maxversion;
        !          1323:         
        !          1324:         my $copyfile=$srcd.'/'.$srcf.'.'.$maxversion.'.'.$srct;
        !          1325:         
1.13      www      1326:         if (copy($target,$copyfile)) {
1.12      www      1327: 	    print $logfile "Copied old target to ".$copyfile."\n";
1.100   ! matthew  1328:             $r->print('<p>Copied old target file');
1.12      www      1329:         } else {
1.13      www      1330: 	    print $logfile "Unable to write ".$copyfile.':'.$!."\n";
1.100   ! matthew  1331:             return "<font color=red>Failed to copy old target, $!, FAIL</font>";
1.12      www      1332:         }
1.100   ! matthew  1333:         
1.12      www      1334: # --------------------------------------------------------------- Copy Metadata
                   1335: 
                   1336: 	$copyfile=$copyfile.'.meta';
1.100   ! matthew  1337:         
1.13      www      1338:         if (copy($target.'.meta',$copyfile)) {
1.14      www      1339: 	    print $logfile "Copied old target metadata to ".$copyfile."\n";
1.100   ! matthew  1340:             $r->print('<p>Copied old metadata')
1.12      www      1341:         } else {
1.13      www      1342: 	    print $logfile "Unable to write metadata ".$copyfile.':'.$!."\n";
1.14      www      1343:             if (-e $target.'.meta') {
1.100   ! matthew  1344:                 return 
        !          1345:                     "<font color=red>Failed to write old metadata copy, $!, FAIL</font>";
1.14      www      1346: 	    }
1.12      www      1347:         }
1.100   ! matthew  1348:         
        !          1349:         
        !          1350:     } else {
        !          1351:         $r->print('<p>Initial version');
        !          1352:         print $logfile "\nInitial version";
        !          1353:     }
1.12      www      1354: 
                   1355: # ---------------------------------------------------------------- Write Source
1.100   ! matthew  1356:     my $copyfile=$target;
        !          1357:     
        !          1358:     my @parts=split(/\//,$copyfile);
        !          1359:     my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]";
        !          1360:     
        !          1361:     my $count;
        !          1362:     for ($count=5;$count<$#parts;$count++) {
        !          1363:         $path.="/$parts[$count]";
        !          1364:         if ((-e $path)!=1) {
        !          1365:             print $logfile "\nCreating directory ".$path;
        !          1366:             $r->print('<p>Created directory '.$parts[$count]);
        !          1367:             mkdir($path,0777);
1.12      www      1368:         }
1.100   ! matthew  1369:     }
        !          1370:     
        !          1371:     if (copy($source,$copyfile)) {
        !          1372:         print $logfile "\nCopied original source to ".$copyfile."\n";
        !          1373:         $r->print('<p>Copied source file');
        !          1374:     } else {
        !          1375:         print $logfile "\nUnable to write ".$copyfile.':'.$!."\n";
        !          1376:         return "<font color=red>Failed to copy source, $!, FAIL</font>";
        !          1377:     }
        !          1378:     
1.12      www      1379: # --------------------------------------------------------------- Copy Metadata
                   1380: 
1.100   ! matthew  1381:     $copyfile=$copyfile.'.meta';
        !          1382:     
        !          1383:     if (copy($source.'.meta',$copyfile)) {
        !          1384:         print $logfile "\nCopied original metadata to ".$copyfile."\n";
        !          1385:         $r->print('<p>Copied metadata');
        !          1386:     } else {
        !          1387:         print $logfile "\nUnable to write metadata ".$copyfile.':'.$!."\n";
        !          1388:         return 
        !          1389:             "<font color=red>Failed to write metadata copy, $!, FAIL</font>";
        !          1390:     }
        !          1391:     $r->rflush;
1.12      www      1392: # --------------------------------------------------- Send update notifications
                   1393: 
1.85      albertel 1394:     my @subscribed=&get_subscribed_hosts($target);
                   1395:     foreach my $subhost (@subscribed) {
1.100   ! matthew  1396: 	$r->print('<p>Notifying host '.$subhost.':');$r->rflush;
1.85      albertel 1397: 	print $logfile "\nNotifying host ".$subhost.':';
                   1398: 	my $reply=&Apache::lonnet::critical('update:'.$target,$subhost);
1.100   ! matthew  1399: 	$r->print($reply);$r->rflush;
1.85      albertel 1400: 	print $logfile $reply;
1.20      www      1401:     }
1.100   ! matthew  1402:     
1.20      www      1403: # ---------------------------------------- Send update notifications, meta only
                   1404: 
1.85      albertel 1405:     my @subscribedmeta=&get_subscribed_hosts("$target.meta");
                   1406:     foreach my $subhost (@subscribedmeta) {
1.100   ! matthew  1407: 	$r->print('<p>Notifying host for metadata only '.$subhost.':');$r->rflush;
1.85      albertel 1408: 	print $logfile "\nNotifying host for metadata only ".$subhost.':';
                   1409: 	my $reply=&Apache::lonnet::critical('update:'.$target.'.meta',
                   1410: 					    $subhost);
1.100   ! matthew  1411: 	$r->print($reply);$r->rflush;
1.85      albertel 1412: 	print $logfile $reply;
1.12      www      1413:     }
1.100   ! matthew  1414:     
1.12      www      1415: # ------------------------------------------------ Provide link to new resource
1.100   ! matthew  1416:     unless ($batch) {
        !          1417:         my $thisdistarget=$target;
        !          1418:         $thisdistarget=~s/^$docroot//;
        !          1419:         
        !          1420:         my $thissrc=$source;
        !          1421:         $thissrc=~s/^\/home\/(\w+)\/public_html/\/priv\/$1/;
        !          1422:         
        !          1423:         my $thissrcdir=$thissrc;
        !          1424:         $thissrcdir=~s/\/[^\/]+$/\//;
        !          1425:         
        !          1426:         
        !          1427:         $r->print(
        !          1428:            '<hr><a href="'.$thisdistarget.'"><font size="+2">'.
        !          1429:            'View Published Version</font></a>'.
        !          1430:            '<p><a href="'.$thissrc.'"><font size=+2>Back to Source</font></a>'.
        !          1431:            '<p><a href="'.$thissrcdir.
        !          1432:                    '"><font size="+2">Back to Source Directory</font></a>');
        !          1433:     }
1.11      www      1434: }
                   1435: 
1.95      www      1436: #########################################
                   1437: 
                   1438: sub batchpublish {
1.97      www      1439:     my ($r,$srcfile,$targetfile)=@_;
1.95      www      1440:     my $thisdisfn=$srcfile;
                   1441:     $thisdisfn=~s/\/home\/korte\/public_html\///;
                   1442:     $srcfile=~s/\/+/\//g;
1.96      www      1443: 
1.97      www      1444:     my $docroot=$r->dir_config('lonDocRoot');
                   1445:     my $thisdistarget=$targetfile;
                   1446:     $thisdistarget=~s/^$docroot//;
                   1447: 
1.96      www      1448: 
                   1449:     undef %metadatafields;
                   1450:     undef %metadatakeys;
                   1451:      %metadatafields=();
                   1452:      %metadatakeys=();
1.97      www      1453:       $srcfile=~/\.(\w+)$/;
                   1454:       my $thistype=$1;
                   1455: 
                   1456: 
                   1457:       my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);
1.96      www      1458:      
1.95      www      1459:     $r->print('<h2>Publishing <tt>'.$thisdisfn.'</tt></h2>');
1.97      www      1460: 
                   1461: # phase one takes
                   1462: #  my ($source,$target,$style,$batch)=@_;
                   1463:     $r->print('<p>'.&publish($srcfile,$targetfile,$thisembstyle,1).'</p>');
1.96      www      1464: # phase two takes
                   1465: # my ($source,$target,$style,$distarget,batch)=@_;
1.97      www      1466: # $ENV{'form.allmeta'},$ENV{'form.title'},$ENV{'form.author'},...
1.100   ! matthew  1467:     $r->print('<p>');
        !          1468:     &phasetwo($r,$srcfile,$targetfile,$thisembstyle,$thisdistarget,1);
        !          1469:     $r->print('</p>');
1.97      www      1470:     return '';
1.95      www      1471: }
1.1       www      1472: 
1.90      matthew  1473: #########################################
1.95      www      1474: 
                   1475: sub publishdirectory {
                   1476:     my ($r,$fn,$thisdisfn)=@_;
1.96      www      1477:     my $resdir=
1.100   ! matthew  1478:     $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'.$cudom.'/'.$cuname.'/'.
1.96      www      1479:       $thisdisfn;
1.100   ! matthew  1480:       $r->print('<h1>Directory <tt>'.$thisdisfn.'</tt></h1>'.
1.96      www      1481:                 'Target: <tt>'.$resdir.'</tt><br />');
1.95      www      1482: 
                   1483:       my $dirptr=16384;		# Mask indicating a directory in stat.cmode.
                   1484: 
                   1485:       opendir(DIR,$fn);
                   1486:       my @files=sort(readdir(DIR));
                   1487:       foreach my $filename (@files) {
                   1488:          my ($cdev,$cino,$cmode,$cnlink,
                   1489:             $cuid,$cgid,$crdev,$csize,
                   1490:             $catime,$cmtime,$cctime,
                   1491:             $cblksize,$cblocks)=stat($fn.'/'.$filename);
                   1492: 
                   1493:          my $extension='';
                   1494:          if ($filename=~/\.(\w+)$/) { $extension=$1; }
                   1495:          if ($cmode&$dirptr) {
                   1496: 	   if (($filename!~/^\./) && ($ENV{'form.pubrec'})) {
                   1497: 	      &publishdirectory($r,$fn.'/'.$filename,$thisdisfn.'/'.$filename);
                   1498: 	   }
                   1499:          } elsif ((&Apache::loncommon::fileembstyle($extension) ne 'hdn') &&
                   1500:                   ($filename!~/^[\#\.]/) && ($filename!~/\~$/)) {
1.96      www      1501: # find out publication status and/or exiting metadata
                   1502: 	     my $publishthis=0;
                   1503:              if (-e $resdir.'/'.$filename) {
                   1504: 	        my ($rdev,$rino,$rmode,$rnlink,
                   1505: 	        $ruid,$rgid,$rrdev,$rsize,
                   1506: 	        $ratime,$rmtime,$rctime,
                   1507: 	        $rblksize,$rblocks)=stat($resdir.'/'.$filename);
                   1508: 	        if ($rmtime<$cmtime) {
                   1509: # previously published, modified now
                   1510: 		    $publishthis=1;
                   1511:                 }
                   1512: 	     } else {
                   1513: # never published
                   1514: 		 $publishthis=1;
                   1515: 	     }
                   1516:              if ($publishthis) {
1.97      www      1517:                 &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename);
1.96      www      1518: 	     } else {
                   1519:                  $r->print('<br />Skipping '.$filename.'<br />');
                   1520:              }
1.95      www      1521:              $r->rflush();
                   1522:          }
                   1523:       }
                   1524:       closedir(DIR);
                   1525: }
1.90      matthew  1526: #########################################
                   1527: 
                   1528: =pod
                   1529: 
1.94      harris41 1530: =item B<handler>
1.90      matthew  1531: 
                   1532: A basic outline of the handler subroutine follows.
                   1533: 
                   1534: =over 4
                   1535: 
1.94      harris41 1536: =item *
                   1537: 
                   1538: Get query string for limited number of parameters.
                   1539: 
                   1540: =item *
                   1541: 
                   1542: Check filename.
                   1543: 
                   1544: =item *
                   1545: 
                   1546: File is there and owned, init lookup tables.
                   1547: 
                   1548: =item *
1.90      matthew  1549: 
1.94      harris41 1550: Start page output.
1.90      matthew  1551: 
1.94      harris41 1552: =item *
1.90      matthew  1553: 
1.94      harris41 1554: Evaluate individual file, and then output information.
1.90      matthew  1555: 
1.94      harris41 1556: =item *
1.90      matthew  1557: 
1.94      harris41 1558: Publishing from $thisfn to $thistarget with $thisembstyle.
1.90      matthew  1559: 
                   1560: =back
                   1561: 
                   1562: =cut
                   1563: 
                   1564: #########################################
                   1565: #########################################
1.1       www      1566: sub handler {
                   1567:   my $r=shift;
1.2       www      1568: 
                   1569:   if ($r->header_only) {
                   1570:      $r->content_type('text/html');
                   1571:      $r->send_http_header;
                   1572:      return OK;
                   1573:   }
                   1574: 
1.43      www      1575: # Get query string for limited number of parameters
                   1576: 
1.80      matthew  1577:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   1578:                                             ['filename']);
1.43      www      1579: 
1.2       www      1580: # -------------------------------------------------------------- Check filename
                   1581: 
                   1582:   my $fn=$ENV{'form.filename'};
                   1583: 
1.27      www      1584:   
1.2       www      1585:   unless ($fn) { 
1.27      www      1586:      $r->log_reason($cuname.' at '.$cudom.
1.2       www      1587:          ' trying to publish empty filename', $r->filename); 
                   1588:      return HTTP_NOT_FOUND;
                   1589:   } 
1.4       www      1590: 
1.31      www      1591:   ($cuname,$cudom)=
                   1592:     &Apache::loncacc::constructaccess($fn,$r->dir_config('lonDefDomain'));
                   1593:   unless (($cuname) && ($cudom)) {
1.27      www      1594:      $r->log_reason($cuname.' at '.$cudom.
1.4       www      1595:          ' trying to publish file '.$ENV{'form.filename'}.
1.27      www      1596:          ' ('.$fn.') - not authorized', 
                   1597:          $r->filename); 
                   1598:      return HTTP_NOT_ACCEPTABLE;
                   1599:   }
                   1600: 
                   1601:   unless (&Apache::lonnet::homeserver($cuname,$cudom) 
                   1602:           eq $r->dir_config('lonHostID')) {
                   1603:      $r->log_reason($cuname.' at '.$cudom.
                   1604:          ' trying to publish file '.$ENV{'form.filename'}.
                   1605:          ' ('.$fn.') - not homeserver ('.
                   1606:          &Apache::lonnet::homeserver($cuname,$cudom).')', 
1.4       www      1607:          $r->filename); 
                   1608:      return HTTP_NOT_ACCEPTABLE;
                   1609:   }
1.2       www      1610: 
1.43      www      1611:   $fn=~s/^http\:\/\/[^\/]+//;
                   1612:   $fn=~s/^\/\~(\w+)/\/home\/$1\/public_html/;
1.2       www      1613: 
                   1614:   my $targetdir='';
1.12      www      1615:   $docroot=$r->dir_config('lonDocRoot'); 
1.27      www      1616:   if ($1 ne $cuname) {
                   1617:      $r->log_reason($cuname.' at '.$cudom.
1.2       www      1618:          ' trying to publish unowned file '.$ENV{'form.filename'}.
                   1619:          ' ('.$fn.')', 
                   1620:          $r->filename); 
                   1621:      return HTTP_NOT_ACCEPTABLE;
                   1622:   } else {
1.27      www      1623:       $targetdir=$docroot.'/res/'.$cudom;
1.2       www      1624:   }
                   1625:                                  
                   1626:   
                   1627:   unless (-e $fn) { 
1.27      www      1628:      $r->log_reason($cuname.' at '.$cudom.
1.2       www      1629:          ' trying to publish non-existing file '.$ENV{'form.filename'}.
                   1630:          ' ('.$fn.')', 
                   1631:          $r->filename); 
                   1632:      return HTTP_NOT_FOUND;
                   1633:   } 
                   1634: 
1.11      www      1635: unless ($ENV{'form.phase'} eq 'two') {
                   1636: 
1.94      harris41 1637: # -------------------------------- File is there and owned, init lookup tables.
1.2       www      1638: 
1.3       www      1639:   %addid=();
                   1640: 
                   1641:   {
                   1642:       my $fh=Apache::File->new($r->dir_config('lonTabDir').'/addid.tab');
                   1643:       while (<$fh>=~/(\w+)\s+(\w+)/) {
                   1644:           $addid{$1}=$2;
                   1645:       }
1.5       www      1646:   }
                   1647: 
                   1648:   %nokey=();
                   1649: 
                   1650:   {
                   1651:      my $fh=Apache::File->new($r->dir_config('lonIncludes').'/un_keyword.tab');
1.65      harris41 1652:       while (<$fh>) {
1.5       www      1653:           my $word=$_;
                   1654:           chomp($word);
                   1655:           $nokey{$word}=1;
1.65      harris41 1656:       }
1.3       www      1657:   }
1.11      www      1658: 
                   1659: }
                   1660: 
1.94      harris41 1661: # ---------------------------------------------------------- Start page output.
1.2       www      1662: 
1.1       www      1663:   $r->content_type('text/html');
                   1664:   $r->send_http_header;
                   1665: 
                   1666:   $r->print('<html><head><title>LON-CAPA Publishing</title></head>');
1.95      www      1667:   $r->print(&Apache::loncommon::bodytag('Resource Publication'));
1.2       www      1668:   my $thisfn=$fn;
1.95      www      1669: 
                   1670:   my $thistarget=$thisfn;
                   1671:       
                   1672:   $thistarget=~s/^\/home/$targetdir/;
                   1673:   $thistarget=~s/\/public\_html//;
                   1674: 
                   1675:   my $thisdistarget=$thistarget;
                   1676:   $thisdistarget=~s/^$docroot//;
                   1677: 
                   1678:   my $thisdisfn=$thisfn;
                   1679:   $thisdisfn=~s/^\/home\/$cuname\/public_html\///;
                   1680: 
                   1681:   if ($fn=~/\/$/) {
                   1682: # -------------------------------------------------------- This is a directory
                   1683:       &publishdirectory($r,$fn,$thisdisfn);
                   1684: 
                   1685:   } else {
1.94      harris41 1686: # ---------------------- Evaluate individual file, and then output information.
1.2       www      1687:       $thisfn=~/\.(\w+)$/;
                   1688:       my $thistype=$1;
1.65      harris41 1689:       my $thisembstyle=&Apache::loncommon::fileembstyle($thistype);
1.2       www      1690: 
                   1691:       $r->print('<h2>Publishing '.
1.66      harris41 1692:         &Apache::loncommon::filedescription($thistype).' <tt>'.
1.95      www      1693:         '<a href="/~'.$cuname.'/'.$thisdisfn.'" target="cat">'.$thisdisfn.
                   1694:         '</a></tt></h2><b>Target:</b> <tt>'.$thisdistarget.'</tt><p>');
1.27      www      1695:    
1.94      harris41 1696:       if (($cuname ne $ENV{'user.name'}) || ($cudom ne $ENV{'user.domain'})) {
                   1697:           $r->print('<h3><font color="red">Co-Author: '.$cuname.' at '.$cudom.
                   1698: 		    '</font></h3>');
1.27      www      1699:       }
1.26      www      1700: 
1.65      harris41 1701:       if (&Apache::loncommon::fileembstyle($thistype) eq 'ssi') {
1.94      harris41 1702:           $r->print('<br /><a href="/adm/diff?filename=/~'.$cuname.'/'.
1.28      www      1703:                     $thisdisfn.
1.94      harris41 1704:   	  '&versionone=priv" target="cat">Diffs with Current Version</a><p>');
1.26      www      1705:       }
1.11      www      1706:   
1.94      harris41 1707: # ------------------ Publishing from $thisfn to $thistarget with $thisembstyle.
1.2       www      1708: 
1.11      www      1709:        unless ($ENV{'form.phase'} eq 'two') {
1.27      www      1710:          $r->print(
1.94      harris41 1711:           '<hr />'.&publish($thisfn,$thistarget,$thisembstyle));
1.11      www      1712:        } else {
1.100   ! matthew  1713:            $r->print('<hr />');
        !          1714:            &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget); 
1.11      www      1715:        }  
1.2       www      1716: 
1.11      www      1717:   }
1.1       www      1718:   $r->print('</body></html>');
1.15      www      1719: 
1.1       www      1720:   return OK;
                   1721: }
                   1722: 
                   1723: 1;
                   1724: __END__
                   1725: 
1.89      matthew  1726: =pod
1.66      harris41 1727: 
                   1728: =back
                   1729: 
1.89      matthew  1730: =cut
1.66      harris41 1731: 

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

Internal Server Error

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

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

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