--- loncom/publisher/lonpublisher.pm 2008/06/30 18:10:24 1.239 +++ loncom/publisher/lonpublisher.pm 2009/07/30 09:42:25 1.262 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Publication Handler # -# $Id: lonpublisher.pm,v 1.239 2008/06/30 18:10:24 bisitz Exp $ +# $Id: lonpublisher.pm,v 1.262 2009/07/30 09:42:25 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -118,11 +118,14 @@ use Apache::File; use File::Copy; use Apache::Constants qw(:common :http :methods); use HTML::LCParser; +use HTML::Entities; +use Encode::Encoder; use Apache::lonxml; use Apache::loncacc; use DBI; use Apache::lonnet; use Apache::loncommon(); +use Apache::lonhtmlcommon; use Apache::lonmysql; use Apache::lonlocal; use Apache::loncfile; @@ -263,8 +266,9 @@ sub metaread { my ($logfile,$fn,$prefix)=@_; unless (-e $fn) { print($logfile 'No file '.$fn."\n"); - return '
'.&mt('No file').': '. - &Apache::loncfile::display($fn).''; + return '
' + .&mt('No file: [_1]' + ,' '.&Apache::loncfile::display($fn).'
'); } print($logfile 'Processing '.$fn."\n"); my $metastring; @@ -273,8 +277,9 @@ sub metaread { $metastring=join('',<$metafh>); } &metaeval($metastring,$prefix); - return '
'.&mt('Processed file').': '. - &Apache::loncfile::display($fn).'
'; + return '
' + .&mt('Processed file: [_1]' + ,' '.&Apache::loncfile::display($fn).'
'); } ######################################### @@ -325,7 +330,7 @@ string which presents the form field (fo ######################################### ######################################### sub textfield { - my ($title,$name,$value)=@_; + my ($title,$name,$value,$noline)=@_; $value=~s/^\s+//gs; $value=~s/\s+$//gs; $value=~s/\s+/ /gs; @@ -333,11 +338,11 @@ sub textfield { $env{'form.'.$name}=$value; return "\n".&Apache::lonhtmlcommon::row_title($title) .'' - .&Apache::lonhtmlcommon::row_closure(); + .&Apache::lonhtmlcommon::row_closure($noline); } sub text_with_browse_field { - my ($title,$name,$value,$restriction)=@_; + my ($title,$name,$value,$restriction,$noline)=@_; $value=~s/^\s+//gs; $value=~s/\s+$//gs; $value=~s/\s+/ /gs; @@ -352,7 +357,7 @@ sub text_with_browse_field { .'' .&mt('Search') .'' - .&Apache::lonhtmlcommon::row_closure(); + .&Apache::lonhtmlcommon::row_closure($noline); } sub hiddenfield { @@ -379,11 +384,11 @@ sub selectbox { my $selout="\n".&Apache::lonhtmlcommon::row_title($title) .''.&Apache::lonhtmlcommon::row_closure(); return $selout; @@ -690,6 +695,7 @@ sub fix_ids_and_indices { $responsecounter=0; } if ($lctag=~/response$/) { $responsecounter++; } + if ($lctag eq 'import') { $responsecounter++; } my %parms=%{$token->[2]}; $counter=$addid{$tag}; if (!$counter) { $counter=$addid{$lctag}; } @@ -842,15 +848,17 @@ sub store_metadata { # Determine if the table exists my $status = &Apache::lonmysql::check_table('metadata'); if (! defined($status)) { - $error='WARNING: Cannot connect to '. - 'database!'; + $error='' + .&mt('WARNING: Cannot connect to database!') + .''; &Apache::lonnet::logthis($error); return ($error,undef); } if ($status == 0) { # It would be nice to actually create the table.... - $error ='WARNING: The metadata table does not '. - 'exist in the LON-CAPA database.'; + $error ='' + .&mt('WARNING: The metadata table does not exist in the LON-CAPA database!') + .''; &Apache::lonnet::logthis($error); return ($error,undef); } @@ -865,8 +873,9 @@ sub store_metadata { \%metadata); } if (defined($status) && $status ne '') { - $error='Error occured saving new values in '. - 'metadata table in LON-CAPA database'; + $error='' + .&mt('Error occurred saving new values in metadata table in LON-CAPA database!') + .''; &Apache::lonnet::logthis($error); &Apache::lonnet::logthis($status); return ($error,undef); @@ -886,17 +895,21 @@ sub checkonthis { 'return_only_error_and_warning_counts' => 1)); my ($errorcount,$warningcount)=split(':',$result); if (($errorcount) || ($warningcount)) { - $r->print('
'.$uri.': '); - if ($errorcount) { - $r->print(''. - $errorcount.' '. - &mt('error(s)').' '); - } - if ($warningcount) { - $r->print(''. - $warningcount.' '. - &mt('warning(s)').''); - } + $r->print('

'.&mt('Warnings and Errors').'

'); + $r->print(''.$uri.':'); + $r->print(''); } else { #$r->print(''.&mt('ok').''); } @@ -935,7 +948,7 @@ backup copies, performs any automatic pr especially for rat and ssi files), Returns a 2 element array, the first is the string to be shown to the -user, the second is an error code, either 1 (an error occured) or 0 +user, the second is an error code, either 1 (an error occurred) or 0 (no error occurred) I @@ -978,30 +991,30 @@ sub publish { if ($error) { return ($outstring,$error); } # ------------------------------------------------------------ Construct Allows - $scrout.='

'.&mt('Dependencies').'

'; + my $outdep=''; # Collect dependencies output data my $allowstr=''; foreach my $thisdep (sort(keys(%allow))) { if ($thisdep !~ /[^\s]/) { next; } if ($thisdep =~/\$/) { - $scrout.='
' + $outdep.='
' .&mt('The resource depends on another resource with variable filename, i.e., [_1].',''.$thisdep.'').'
' .&mt('You likely need to explicitly allow access to all possible dependencies using the [_1]-tag.','<allow>') - .'
'; + ."
\n"; } unless ($style eq 'rat') { $allowstr.="\n".''; } - $scrout.='
'; + $outdep.='
'; if ($thisdep!~/[\*\$]/ && $thisdep!~m|^/adm/|) { - $scrout.=''; + $outdep.=''; } - $scrout.=''.$thisdep.''; + $outdep.=''.$thisdep.''; if ($thisdep!~/[\*\$]/ && $thisdep!~m|^/adm/|) { - $scrout.=''; + $outdep.=''; if ( &Apache::lonnet::getfile($Apache::lonnet::perlvar{'lonDocRoot'}.'/'. $thisdep.'.meta') eq '-1') { - $scrout.= ' - '.&mt('Currently not available'). + $outdep.= ' - '.&mt('Currently not available'). ''; } else { my %temphash=(&Apache::lonnet::declutter($target).'___'. @@ -1014,6 +1027,12 @@ sub publish { } } } + $outdep.='

'; + } + + if ($outdep) { + $scrout.='

'.&mt('Dependencies').'

' + .$outdep } $outstring=~s/\n*(\<\/[^\>]+\>[^<]*)$/$allowstr\n$1\n/s; @@ -1043,7 +1062,7 @@ sub publish { my %oldparmstores=(); unless ($batch) { - $scrout.='

'.&mt('Metadata Information').' ' . + $scrout.='

'.&mt('Metadata').' ' . &Apache::loncommon::help_open_topic("Metadata_Description") . '

'; } @@ -1147,15 +1166,16 @@ sub publish { } } if ($chparms) { - $scrout.='

'.&mt('Obsolete parameters or saved values').': '. - $chparms.'

'.&mt('Warning!'). - '

'. - &mt('If this resource is in active use, student performance data from the previous version may become inaccessible.').'


'; + $scrout.='

'.&mt('Obsolete parameters or saved values').': ' + .$chparms.'

' + .'

'.&mt('Warning!').'
' + .&mt('If this resource is in active use, student performance data from the previous version may become inaccessible.') + .'


'; } if ($metadatafields{'copyright'} eq 'priv') { - $scrout.='

'.&mt('Warning!'). - '

'. - &mt('Copyright/distribution option "Private" is no longer supported. Select another option from below. Consider "Custom Rights" for maximum control over the usage of your resource.').'


'; + $scrout.='

'.&mt('Warning!').'
' + .&mt('Copyright/distribution option "Private" is no longer supported. Select another option from below. Consider "Custom Rights" for maximum control over the usage of your resource.') + .'


'; } # ------------------------------------------------------- Now have all metadata @@ -1167,17 +1187,22 @@ sub publish { $textonly=~s/\//g; $textonly=~s/\[^\<]+\<\/m\>//g; $textonly=~s/\<[^\>]*\>//g; - $textonly=~tr/A-Z/a-z/; - $textonly=~s/[\$\&][a-z]\w*//g; - $textonly=~s/[^a-z\s]//g; - - foreach ($textonly=~m/(\w+)/g) { - unless ($nokey{$_}) { - $keywords{$_}=1; - } - } - } + #this is a work simplification for german authors for present + $textonly=HTML::Entities::decode($textonly); #decode HTML-character + $textonly=Encode::Encoder::encode('utf8', $textonly); #encode to perl internal unicode + $textonly=~tr/A-ZÜÄÖ/a-züäö/; #add lowercase rule for german "Umlaute" + $textonly=~s/[\$\&][a-z]\w*//g; + $textonly=~s/[^a-z^ü^ä^ö^ß\s]//g; #dont delete german "Umlaute" + + foreach ($textonly=~m/[^\s]+/g) { #match all but whitespaces + unless ($nokey{$_}) { + $keywords{$_}=1; + } + } + + + } foreach my $addkey (split(/[\"\'\,\;]/,$metadatafields{'keywords'})) { $addkey=~s/\s+/ /g; @@ -1198,7 +1223,7 @@ sub publish { my $intr_scrout.='
' .'
'; unless ($env{'form.makeobsolete'}) { - $intr_scrout.='

' + $intr_scrout.='

' .&mt('Searching for your resource will be based on the following metadata. Please provide as much data as possible.') .'

' .'

' .'' .'


' - .''; + .&Apache::loncommon::start_data_table(); + my $cols_per_row = 10; my $colcount=0; + my $wordcount=0; + my $numkeywords = scalar(keys(%keywords)); - foreach (sort keys %keywords) { - $keywordout.=''; - if ($colcount>10) { - $keywordout.="\n"; - $colcount=0; - } - $colcount++; + foreach my $word (sort(keys(%keywords))) { + if ($colcount == 0) { + $keywordout .= &Apache::loncommon::start_data_table_row(); + } + $colcount++; + $wordcount++; + if (($wordcount == $numkeywords) && ($colcount < $cols_per_row)) { + my $colspan = 1+$cols_per_row-$colcount; + $keywordout .= ''; + if ($colcount == $cols_per_row) { + $keywordout.=&Apache::loncommon::end_data_table_row(); + $colcount=0; + } + } + if ($colcount > 0) { + $keywordout .= &Apache::loncommon::end_data_table_row(); } + $env{'form.keywords'}=~s/\,$//; - $keywordout.='
'; + } else { + $keywordout .= ''; + } + $keywordout.='
' + $keywordout.=&Apache::loncommon::end_data_table_row() + .&Apache::loncommon::end_data_table() .&Apache::lonhtmlcommon::row_closure(); $intr_scrout.=$keywordout; @@ -1309,9 +1352,12 @@ END $intr_scrout.=&hiddenfield('lastrevisiondate',time); - + my $pubowner_last; + if ($style eq 'prv') { + $pubowner_last = 1; + } $intr_scrout.=&textfield('Publisher/Owner','owner', - $metadatafields{'owner'}); + $metadatafields{'owner'},$pubowner_last); # ---------------------------------------------- Retrofix for unused copyright if ($metadatafields{'copyright'} eq 'free') { @@ -1356,13 +1402,13 @@ END (&Apache::loncommon::source_copyrightids)); # $intr_scrout.=&text_with_browse_field('Source Custom Distribution File','sourcerights',$metadatafields{'sourcerights'},'rights'); my $uctitle=&mt('Obsolete'); - my $obsolete_checked=($metadatafields{'obsolete'})?' checked="1" ':''; + my $obsolete_checked=($metadatafields{'obsolete'})?' checked="checked"':''; $intr_scrout.="\n".&Apache::lonhtmlcommon::row_title($uctitle) - .'' + .'' .&Apache::lonhtmlcommon::row_closure(1); $intr_scrout.=&text_with_browse_field('Suggested Replacement for Obsolete File', 'obsoletereplacement', - $metadatafields{'obsoletereplacement'}); + $metadatafields{'obsoletereplacement'},'',1); } else { $intr_scrout.=&hiddenfield('copyright','private'); } @@ -1388,7 +1434,7 @@ END &hiddenfield('obsolete',1). &text_with_browse_field('Suggested Replacement for Obsolete File', 'obsoletereplacement', - $metadatafields{'obsoletereplacement'}); + $metadatafields{'obsoletereplacement'},'',1); } if (!$batch) { $scrout.=$intr_scrout @@ -1459,7 +1505,7 @@ sub phasetwo { return 0; } if ($target=~/\.(\d+)\.(\w+)$/) { - $r->print(''.&mt('Cannot publish versioned resource, FAIL').''); + $r->print(''.&mt('Filename of resource contains internal version number. Cannot publish such resources, FAIL').''); return 0; } } @@ -1595,7 +1641,8 @@ sub phasetwo { my $srcf=$2; my $srct=$3; my $srcd=$1; - unless ($srcd=~/^\/home\/httpd\/html\/res/) { + my $docroot = $Apache::lonnet::perlvar{'lonDocRoot'}; + unless ($srcd=~/^\Q$docroot\E\/res/) { print $logfile "\nPANIC: Target dir is ".$srcd; $r->print( "".&mt('Invalid target directory, FAIL').""); @@ -1607,14 +1654,14 @@ sub phasetwo { unlink($srcd.'/'.$filename); unlink($srcd.'/'.$filename.'.meta'); } else { - if ($filename=~/\Q$srcf\E\.(\d+)\.\Q$srct\E$/) { + if ($filename=~/^\Q$srcf\E\.(\d+)\.\Q$srct\E$/) { $maxversion=($1>$maxversion)?$1:$maxversion; } } } closedir(DIR); $maxversion++; - $r->print('

Creating old version '.$maxversion.'

'); + $r->print('

'.&mt('Creating old version [_1]',$maxversion).'

'); print $logfile "\nCreating old version ".$maxversion."\n"; my $copyfile=$srcd.'/'.$srcf.'.'.$maxversion.'.'.$srct; @@ -1663,8 +1710,12 @@ sub phasetwo { $path.="/$parts[$count]"; if ((-e $path)!=1) { print $logfile "\nCreating directory ".$path; - $r->print('

'.&mt('Created directory').' '.$parts[$count].'

'); mkdir($path,0777); + $r->print('

' + .&mt('Created directory [_1]' + ,''.$parts[$count].'') + .'

' + ); } } @@ -1707,27 +1758,39 @@ sub phasetwo { &Apache::lonnet::devalidate_cache_new('meta', &Apache::lonnet::declutter($thisdistarget)); +# ------------------------------------------------------------- Everything done + $logfile->close(); + $r->print('

'.&mt('Done').'

'); + # ------------------------------------------------ Provide link to new resource unless ($batch) { - my $thissrc=$source; $thissrc=~s{^/home/($match_username)/public_html}{/priv/$1}; my $thissrcdir=$thissrc; $thissrcdir=~s/\/[^\/]+$/\//; - + $r->print(&Apache::lonhtmlcommon::start_funclist()); + unless ($env{'request.role'}=~/^(aa)/) { + $r->print( + &Apache::lonhtmlcommon::add_item_funclist( + '' + .&mt('View Published Version') + .'') + ); + } $r->print( - '
'. - &mt('View Published Version').''. - '

'. - &mt('Back to Source').'

'. - '

'. - &mt('Back to Source Directory').'

'); + &Apache::lonhtmlcommon::add_item_funclist( + '' + .&mt('Back to Source') + .'') + .&Apache::lonhtmlcommon::add_item_funclist( + '' + .&mt('Back to Source Directory') + .'') + .&Apache::lonhtmlcommon::end_funclist() + ); } - $logfile->close(); - $r->print('

'.&mt('Done').'

'); return 1; } @@ -1794,7 +1857,11 @@ sub batchpublish { my $thisembstyle=&Apache::loncommon::fileembstyle($thistype); - $r->print('

'.&mt('Publishing').' '.$thisdisfn.'

'); + $r->print('

' + .&mt('Publishing [_1]' + ,''.$thisdisfn.'') + .'

' + ); # phase one takes # my ($source,$target,$style,$batch)=@_; @@ -1821,22 +1888,36 @@ sub publishdirectory { my $resdir= $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'.$cudom.'/'.$cuname.'/'. $thisdisfn; - $r->print('

'.&mt('Directory').' '.$thisdisfn.'

'. - &mt('Target').': '.$resdir.'
'); + $r->print(&Apache::lonhtmlcommon::start_pick_box() + .&Apache::lonhtmlcommon::row_title(&mt('Directory')) + .''.$thisdisfn.'' + .&Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title(&mt('Target')) + .''.$resdir.'' + ); my $dirptr=16384; # Mask indicating a directory in stat.cmode. unless ($env{'form.phase'} eq 'two') { # ask user what they want + $r->print(&Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title(&mt('Options')) + ); $r->print(''. &hiddenfield('phase','two'). &hiddenfield('filename',$env{'form.filename'}). &checkbox('pubrec','include subdirectories'). &checkbox('forcerepub','force republication of previously published files'). &checkbox('obsolete','make file(s) obsolete'). - &checkbox('forceoverride','force directory level catalog information over existing'). + &checkbox('forceoverride','force directory level metadata over existing'). '
'); + $r->print(&Apache::lonhtmlcommon::row_closure(1) + .&Apache::lonhtmlcommon::end_pick_box() + ); $lock=0; } else { + $r->print(&Apache::lonhtmlcommon::row_closure(1) + .&Apache::lonhtmlcommon::end_pick_box() + ); unless ($lock) { $lock=&Apache::lonnet::set_lock(&mt('Publishing [_1]',$fn)); } # actually publish things opendir(DIR,$fn); @@ -1904,7 +1985,7 @@ sub defaultmetapublish { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; - $r->print(&Apache::loncommon::start_page('Catalog Information Publication')); + $r->print(&Apache::loncommon::start_page('Metadata Publication')); # ---------------------------------------------------------------- Write Source my $copyfile=$target; @@ -1916,8 +1997,12 @@ sub defaultmetapublish { for ($count=5;$count<$#parts;$count++) { $path.="/$parts[$count]"; if ((-e $path)!=1) { - $r->print('

'.&mt('Created directory').' '.$parts[$count].'

'); mkdir($path,0777); + $r->print('

' + .&mt('Created directory [_1]' + ,''.$parts[$count].'') + .'

' + ); } } @@ -1939,7 +2024,7 @@ sub defaultmetapublish { # ------------------------------------------------------------------- Link back my $link=$fn; $link=~s/^\/home\/$cuname\/public_html\//\/priv\/$cuname\//; - $r->print("".&mt('Back to Catalog Information').''); + $r->print("".&mt('Back to Metadata').''); $r->print(&Apache::loncommon::end_page()); return OK; } @@ -2090,10 +2175,25 @@ sub handler { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; + # Breadcrumbs + &Apache::lonhtmlcommon::clear_breadcrumbs(); + &Apache::lonhtmlcommon::add_breadcrumb({ + 'text' => 'Construction Space', + 'href' => &Apache::loncommon::authorspace(), + }); + &Apache::lonhtmlcommon::add_breadcrumb({ + 'text' => 'Resource Publication', + 'href' => '', + }); + my $js=''; - $r->print(&Apache::loncommon::start_page('Resource Publication',$js)); + $r->print(&Apache::loncommon::start_page('Resource Publication',$js) + .&Apache::lonhtmlcommon::breadcrumbs() + .&Apache::loncommon::head_subbox( + &Apache::loncommon::CSTR_pageheader()) # FIXME crumbs broken? + ); my $thisfn=$fn; @@ -2124,7 +2224,11 @@ sub handler { my $thisembstyle=&Apache::loncommon::fileembstyle($thistype); if ($thistype eq 'page') { $thisembstyle = 'rat'; } - $r->print('

'.&mt('Publishing [_1]',''.$thisdisfn.'').'

'); + $r->print('

' + .&mt('Publishing [_1]' + ,''.$thisdisfn.'') + .'

' + ); $r->print('

'.&mt('Resource Details').'

'); @@ -2148,32 +2252,28 @@ ENDCAPTION $r->print(&Apache::lonhtmlcommon::row_title(&mt('Target')) .''.$thisdistarget.'' - .&Apache::lonhtmlcommon::row_closure() ); - -# SB - ToDo: if (($cuname ne $env{'user.name'})||($cudom ne $env{'user.domain'})) { -# $r->print(&Apache::lonhtmlcommon::row_title(''.&mt('Co-Author').'') - $r->print(&Apache::lonhtmlcommon::row_title(&mt('Co-Author')) + $r->print(&Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title(&mt('Co-Author')) .'' - .&mt('[_1] at [_2]',$cuname,$cudom) + .&Apache::loncommon::plainname($cuname,$cudom) .' ('.$cuname.':'.$cudom.')' .'' - .&Apache::lonhtmlcommon::row_closure() ); } if (&Apache::loncommon::fileembstyle($thistype) eq 'ssi') { - $r->print(&Apache::lonhtmlcommon::row_title(&mt('Diffs'))); + $r->print(&Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title(&mt('Diffs'))); $r->print(< ENDDIFF - $r->print(&mt('Diffs with Current Version').'' - .&Apache::lonhtmlcommon::row_closure() - ); - + $r->print(&mt('Diffs with Current Version').''); } - - $r->print(&Apache::lonhtmlcommon::end_pick_box()); + + $r->print(&Apache::lonhtmlcommon::row_closure(1) + .&Apache::lonhtmlcommon::end_pick_box() + ); # ------------------ Publishing from $thisfn to $thistarget with $thisembstyle. @@ -2186,7 +2286,7 @@ ENDDIFF unless ($errorcount) { my ($outstring,$error)= &publish($thisfn,$thistarget,$thisembstyle); - $r->print('
'.$outstring); + $r->print($outstring); } else { $r->print('

'. &mt('The document contains errors and cannot be published.'). @@ -2194,7 +2294,6 @@ ENDDIFF } } else { &phasetwo($r,$thisfn,$thistarget,$thisembstyle,$thisdistarget); - $r->print('
'); } } $r->print(&Apache::loncommon::end_page());