File:  [LON-CAPA] / loncom / interface / lonmeta.pm
Revision 1.64: download - view: text, annotated - select for diffs
Tue Apr 13 14:42:24 2004 UTC (20 years ago) by matthew
Branches: MAIN
CVS tags: HEAD
Retabination.

# The LearningOnline Network with CAPA
# Metadata display handler
#
# $Id: lonmeta.pm,v 1.64 2004/04/13 14:42:24 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/


package Apache::lonmeta;

use strict;
use LONCAPA::lonmetadata();
use Apache::Constants qw(:common);
use Apache::lonnet();
use Apache::loncommon();
use Apache::lonhtmlcommon();
use Apache::lonmsg;
use Apache::lonpublisher;
use Apache::lonlocal;
use Apache::lonmysql;
use Apache::lonmsg;

# MySQL table columns

my @columns;

# Fetch and evaluate dynamic metadata
sub dynamicmeta {
    my $url=&Apache::lonnet::declutter(shift);
    $url=~s/\.meta$//;
    my ($adomain,$aauthor)=($url=~/^(\w+)\/(\w+)\//);
    my $regexp=$url;
    $regexp=~s/(\W)/\\$1/g;
    $regexp='___'.$regexp.'___';
    my %evaldata=&Apache::lonnet::dump('nohist_resevaldata',$adomain,
				       $aauthor,$regexp);
    my %DynamicData = &LONCAPA::lonmetadata::process_reseval_data(\%evaldata);
    my %Data = &LONCAPA::lonmetadata::process_dynamic_metadata($url,
                                                               \%DynamicData);
    #
    # Deal with 'count' separately
    $Data{'count'} = &access_count($url,$aauthor,$adomain);
    return %Data;
}

sub access_count {
    my ($src,$author,$adomain) = @_;
    my %countdata=&Apache::lonnet::dump('nohist_accesscount',$adomain,
                                        $author,$src);
    if (! exists($countdata{$src})) {
        return &mt('Not Available');
    } else {
        return $countdata{$src};
    }
}

# Try to make an alt tag if there is none
sub alttag {
    my ($base,$src)=@_;
    my $fullpath=&Apache::lonnet::hreflocation($base,$src);
    my $alttag=&Apache::lonnet::metadata($fullpath,'title').' '.
        &Apache::lonnet::metadata($fullpath,'subject').' '.
        &Apache::lonnet::metadata($fullpath,'abstract');
    $alttag=~s/\s+/ /gs;
    $alttag=~s/\"//gs;
    $alttag=~s/\'//gs;
    $alttag=~s/\s+$//gs;
    $alttag=~s/^\s+//gs;
    if ($alttag) { 
        return $alttag; 
    } else { 
        return &mt('No information available'); 
    }
}

# Author display
sub authordisplay {
    my ($aname,$adom)=@_;
    return &Apache::loncommon::aboutmewrapper
        (&Apache::loncommon::plainname($aname,$adom),
         $aname,$adom,'preview').' <tt>['.$aname.'@'.$adom.']</tt>';
}

# Pretty display
sub evalgraph {
    my $value=shift;
    unless ($value) { return ''; }
    my $val=int($value*10.+0.5)-10;
    my $output='<table border=0 cellpadding=0 cellspacing=0><tr>';
    if ($val>=20) {
	$output.='<td width=20 bgcolor="#555555">&nbsp&nbsp;</td>';
    } else {
        $output.='<td width='.($val).' bgcolor="#555555">&nbsp;</td>'.
                 '<td width='.(20-$val).' bgcolor="#FF3333">&nbsp;</td>';
    }
    $output.='<td bgcolor="#FFFF33">&nbsp;</td>';
    if ($val>20) {
	$output.='<td width='.($val-20).' bgcolor="#33FF33">&nbsp;</td>'.
                 '<td width='.(40-$val).' bgcolor="#555555">&nbsp;</td>';
    } else {
        $output.='<td width=20 bgcolor="#555555">&nbsp&nbsp;</td>';
    }
    $output.='<td> ('.$value.') </td></tr></table>';
    return $output;
}

sub diffgraph {
    my $value=shift;
    unless ($value) { return ''; }
    my $val=int(40.0*$value+0.5);
    my @colors=('#FF9933','#EEAA33','#DDBB33','#CCCC33',
                '#BBDD33','#CCCC33','#DDBB33','#EEAA33');
    my $output='<table border=0 cellpadding=0 cellspacing=0><tr>';
    for (my $i=0;$i<8;$i++) {
	if ($val>$i*5) {
            $output.='<td width=5 bgcolor="'.$colors[$i].'">&nbsp;</td>';
        } else {
	    $output.='<td width=5 bgcolor="#555555">&nbsp;</td>';
	}
    }
    $output.='<td> ('.$value.') </td></tr></table>';
    return $output;
}

# Turn MySQL row into hash
sub metadata_col_to_hash {
    my @cols=@_;
    my %hash=();
    for (my $i=0; $i<=$#columns; $i++) {
	$hash{$columns[$i]}=$cols[$i];
    }
    return %hash;
}

# The field names
sub fieldnames {
    return &Apache::lonlocal::texthash
        (
         'title' => 'Title',
         'author' =>'Author(s)',
         'authorspace' => 'Author Space',
         'modifyinguser' => 'Last Modifying User',
         'subject' => 'Subject',
         'keywords' => 'Keyword(s)',
         'notes' => 'Notes',
         'abstract' => 'Abstract',
         'lowestgradelevel' => 'Lowest Grade Level',
         'highestgradelevel' => 'Highest Grade Level',
         'standards' => 'Standards',
         'mime' => 'MIME Type',
         'language' => 'Language',
         'creationdate' => 'Creation Date',
         'lastrevisiondate' => 'Last Revision Date',
         'owner' => 'Publisher/Owner',
         'copyright' => 'Copyright/Distribution',
         'customdistributionfile' => 'Custom Distribution File',
         'obsolete' => 'Obsolete',
         'obsoletereplacement' => 'Suggested Replacement for Obsolete File',
         'count'      => 'Network-wide number of accesses (hits)',
         'course'     => 'Network-wide number of courses using resource',
         'course_list' => 'Network-wide courses using resource',
         'sequsage'      => 'Number of resources using or importing resource',
         'sequsage_list' => 'Resources using or importing resource',
         'goto'       => 'Number of resources that follow this resource in maps',
         'goto_list'  => 'Resources that follow this resource in maps',
         'comefrom'   => 'Number of resources that lead up to this resource in maps',
         'comefrom_list' => 'Resources that lead up to this resource in maps',
         'clear'      => 'Material presented in clear way',
         'depth'      => 'Material covered with sufficient depth',
         'helpful'    => 'Material is helpful',
         'correct'    => 'Material appears to be correct',
         'technical'  => 'Resource is technically correct', 
         'avetries'   => 'Average number of tries till solved',
         'stdno'      => 'Total number of students who have worked on this problem',
         'difficulty' => 'Degree of difficulty'
         );
}

# Pretty printing of metadata field

sub prettyprint {
    my ($type,$value)=@_;
    unless (defined($value)) { return '&nbsp;'; }
    # Title
    if ($type eq 'title') {
	return '<font size="+1" face="arial">'.$value.'</font>';
    }
    # Dates
    if (($type eq 'creationdate') ||
	($type eq 'lastrevisiondate')) {
	return ($value?&Apache::lonlocal::locallocaltime(
			  &Apache::lonmysql::unsqltime($value)):
		&mt('not available'));
    }
    # Language
    if ($type eq 'language') {
	return &Apache::loncommon::languagedescription($value);
    }
    # Copyright
    if ($type eq 'copyright') {
	return &Apache::loncommon::copyrightdescription($value);
    }
    # MIME
    if ($type eq 'mime') {
        return '<img src="'.&Apache::loncommon::icon($value).'" />&nbsp;'.
            &Apache::loncommon::filedescription($value);
    }
    # Person
    if (($type eq 'author') || 
	($type eq 'owner') ||
	($type eq 'modifyinguser') ||
	($type eq 'authorspace')) {
	$value=~s/(\w+)(\:|\@)(\w+)/&authordisplay($1,$3)/gse;
	return $value;
    }
    # Gradelevel
    if (($type eq 'lowestgradelevel') ||
	($type eq 'highestgradelevel')) {
	return &Apache::loncommon::gradeleveldescription($value);
    }
    # Only for advance users below
    unless ($ENV{'user.adv'}) { return '<i>- '.&mt('not displayed').' -</i>' };
    # File
    if (($type eq 'customdistributionfile') ||
	($type eq 'obsoletereplacement') ||
	($type eq 'goto_list') ||
	($type eq 'comefrom_list') ||
	($type eq 'sequsage_list')) {
	return join('<br />',map {
            my $url=&Apache::lonnet::clutter($_);
            '<b>'.&Apache::lonnet::gettitle($url).'</b>'.
                &Apache::lonhtmlcommon::crumbs($url,'preview','',undef,'+0');
        } split(/\s*\,\s*/,$value));
    }
    # Evaluations
    if (($type eq 'clear') ||
	($type eq 'depth') ||
	($type eq 'helpful') ||
	($type eq 'correct') ||
	($type eq 'technical')) {
	return &evalgraph($value);
    }
    # Difficulty
    if ($type eq 'difficulty') {
	return &diffgraph($value);
    }
    # List of courses
    if ($type=~/\_list/) {
	return join('<br />',map {
	    my %courseinfo=&Apache::lonnet::coursedescription($_);  
	    '<a href="/public/'.
		$courseinfo{'domain'}.'/'.$courseinfo{'num'}.'/syllabus" target="preview">'.
		$courseinfo{'description'}.'</a>';
	} split(/\s*\,\s*/,$value));
    }
    # No pretty print found
    return $value;
}

# Pretty input of metadata field
sub direct {
    return shift;
}

sub selectbox {
    my ($name,$value,$functionref,@idlist)=@_;
    unless (defined($functionref)) { $functionref=\&direct; }
    my $selout='<select name="'.$name.'">';
    foreach (@idlist) {
        $selout.='<option value=\''.$_.'\'';
        if ($_ eq $value) {
	    $selout.=' selected>'.&{$functionref}($_).'</option>';
	}
        else {$selout.='>'.&{$functionref}($_).'</option>';}
    }
    return $selout.'</select>';
}

sub relatedfield {
    my ($show,$relatedsearchflag,$relatedsep,$fieldname,$relatedvalue)=@_;
    unless ($relatedsearchflag) { return ''; }
    unless (defined($relatedsep)) { $relatedsep=' '; }
    unless ($show) { return $relatedsep.'&nbsp;'; }
    return $relatedsep.'<input type="checkbox" name="'.$fieldname.'_related"'.
	($relatedvalue?' checked="1"':'').' />';
}

sub prettyinput {
    my ($type,$value,$fieldname,$formname,
	$relatedsearchflag,$relatedsep,$relatedvalue)=@_;
    # Language
    if ($type eq 'language') {
	return &selectbox($fieldname,
			  $value,
			  \&Apache::loncommon::languagedescription,
			  (&Apache::loncommon::languageids)).
                              &relatedfield(0,$relatedsearchflag,$relatedsep);
    }
    # Copyright
    if ($type eq 'copyright') {
	return &selectbox($fieldname,
			  $value,
			  \&Apache::loncommon::copyrightdescription,
			  (&Apache::loncommon::copyrightids)).
                              &relatedfield(0,$relatedsearchflag,$relatedsep);
    }
    # Gradelevels
    if (($type eq 'lowestgradelevel') ||
	($type eq 'highestgradelevel')) {
	return &Apache::loncommon::select_level_form($value,$fieldname).
            &relatedfield(0,$relatedsearchflag,$relatedsep);
    }
    # Obsolete
    if ($type eq 'obsolete') {
	return '<input type="checkbox" name="'.$fieldname.'"'.
	    ($value?' checked="1"':'').' />'.
            &relatedfield(0,$relatedsearchflag,$relatedsep); 
    }
    # Obsolete replacement file
    if ($type eq 'obsoletereplacement') {
	return '<input type="text" name="'.$fieldname.
	    '" size="60" value="'.$value.'" /><a href="javascript:openbrowser'.
	    "('".$formname."','".$fieldname."'".
	    ",'')\">".&mt('Select').'</a>'.
            &relatedfield(0,$relatedsearchflag,$relatedsep); 
    }
    # Customdistribution file
    if ($type eq 'customdistributionfile') {
	return '<input type="text" name="'.$fieldname.
	    '" size="60" value="'.$value.'" /><a href="javascript:openbrowser'.
	    "('".$formname."','".$fieldname."'".
	    ",'rights')\">".&mt('Select').'</a>'.
            &relatedfield(0,$relatedsearchflag,$relatedsep); 
    }
    # Dates
    if (($type eq 'creationdate') ||
	($type eq 'lastrevisiondate')) {
	return 
            &Apache::lonhtmlcommon::date_setter($formname,$fieldname,$value).
            &relatedfield(0,$relatedsearchflag,$relatedsep);
    }
    # No pretty input found
    $value=~s/^\s+//gs;
    $value=~s/\s+$//gs;
    $value=~s/\s+/ /gs;
    $value=~s/\"/\&quod\;/gs;
    return 
        '<input type="text" name="'.$fieldname.'" size="80" '.
        'value="'.$value.'" />'.
        &relatedfield(1,$relatedsearchflag,$relatedsep,$fieldname,
                      $relatedvalue); 
}

# Main Handler
sub handler {
    my $r=shift;
    #
    my $loaderror=&Apache::lonnet::overloaderror($r);
    if ($loaderror) { return $loaderror; }
    #
    my $uri=$r->uri;
    #
    # Looking for all bombs?
    if ($uri=~/\/adm\/bombs\/(.*)$/) {
        # Set document type
        $uri=&Apache::lonnet::declutter($1);
        &Apache::loncommon::content_type($r,'text/html');
        $r->send_http_header;
        #
        return OK if $r->header_only;
        $r->print(&Apache::loncommon::bodytag('Error Messages'));
        $r->print('<h1>'.&Apache::lonnet::clutter($uri).'</h1>');
        my ($domain,$author)=($uri=~/^(\w+)\/(\w+)\//);
        if (&Apache::loncacc::constructaccess('/~'.$author.'/',$domain)) {
            my %brokenurls=&Apache::lonmsg::all_url_author_res_msg($author,
                                                                   $domain);
            foreach (sort keys %brokenurls) {
                if ($_=~/^\Q$uri\E/) {
                    $r->print(&Apache::lonhtmlcommon::crumbs
                              (&Apache::lonnet::clutter($_)).
                              &Apache::lonmsg::retrieve_author_res_msg($_).
                              '<hr />');
                }
            }
        } else {
            $r->print(&mt('Not authorized'));
        }
        $r->print('</body></html>');
    } elsif ($uri!~/^\/\~/) { 
        # This is not in construction space
        my ($resdomain,$resuser)=
            (&Apache::lonnet::declutter($uri)=~/^(\w+)\/(\w+)\//);
        $loaderror=&Apache::lonnet::overloaderror
            ($r,
             &Apache::lonnet::homeserver($resuser,$resdomain));
        if ($loaderror) { return $loaderror; }
        #
        my %content=();
        # Set document type
        &Apache::loncommon::content_type($r,'text/html');
        $r->send_http_header;
        return OK if $r->header_only;
        # Read file
        foreach (split(/\,/,&Apache::lonnet::metadata($uri,'keys'))) {
            $content{$_}=&Apache::lonnet::metadata($uri,$_);
        }
        # Render Output
        # displayed url
        my ($thisversion)=($uri=~/\.(\d+)\.(\w+)\.meta$/);
        $uri=~s/\.meta$//;
        my $disuri=&Apache::lonnet::clutter($uri);
        # version
        my $currentversion=&Apache::lonnet::getversion($disuri);
        my $versiondisplay='';
        if ($thisversion) {
            $versiondisplay=&mt('Version').': '.$thisversion.
                ' ('.&mt('most recent version').': '.
                ($currentversion>0 ? 
                 $currentversion   :
                 &mt('information not available')).')';
        } else {
            $versiondisplay='Version: '.$currentversion;
        }
        # crumbify displayed URL
        $disuri=&Apache::lonhtmlcommon::crumbs($disuri);
        # obsolete
        my $obsolete=$content{'obsolete'};
        my $obsoletewarning='';
        if (($obsolete) && ($ENV{'user.adv'})) {
            $obsoletewarning='<p><font color="red">'.
                &mt('This resource has been marked obsolete by the author(s)').
                '</font></p>';
        }
        #
        my %lt=&fieldnames();
        my $table='';
        my $bodytag=&Apache::loncommon::bodytag
            ('Catalog Information','','','',$resdomain);
        foreach ('title', 
                 'author', 
                 'subject', 
                 'keywords', 
                 'notes', 
                 'abstract',
                 'lowestgradelevel',
                 'highestgradelevel',
                 'standards', 
                 'mime', 
                 'language', 
                 'creationdate', 
                 'lastrevisiondate', 
                 'owner', 
                 'copyright', 
                 'customdistributionfile', 
                 'obsolete', 
                 'obsoletereplacement') {
            $table.='<tr><td bgcolor="#AAAAAA">'.$lt{$_}.
	        '</td><td bgcolor="#CCCCCC">'.
                &prettyprint($_,$content{$_}).'</td></tr>';
            delete $content{$_};
        }
        #
        $r->print(<<ENDHEAD);
<html><head><title>Catalog Information</title></head>
$bodytag
<h2>$content{'title'}</h2>
<h3><tt>$disuri</tt></h3>
$obsoletewarning
$versiondisplay<br />
<table cellspacing=2 border=0>
$table
</table>
ENDHEAD
        if ($ENV{'user.adv'}) {
            # Dynamic Metadata
            $r->print(
                      '<h3>'.&mt('Dynamic Metadata').' ('.
                      &mt('updated periodically').')</h3>'.&mt('Processing').
                      ' ...<br />');
            $r->rflush();
            my %items=&fieldnames();
            my %dynmeta=&dynamicmeta($uri);
            # General Access and Usage Statistics
            $r->print('<h4>'.&mt('Access and Usage Statistics').'</h4>'.
                      '<table cellspacing=2 border=0>');
            foreach ('count',
                     'sequsage','sequsage_list',
                     'comefrom','comefrom_list',
                     'goto','goto_list',
                     'course','course_list') {
                $r->print('<tr><td bgcolor="#AAAAAA">'.$lt{$_}.'</td>'.
                          '<td bgcolor="#CCCCCC">'.
                          &prettyprint($_,$dynmeta{$_})."</td></tr>\n");
            }
            $r->print('</table>');
            if ($uri=~/\.(problem|exam|quiz|assess|survey|form)\.meta$/) {
                # This is an assessment, print assessment data
                $r->print(
                          '<h4>'.&mt('Assessment Statistical Data').'</h4>'.
                          '<table cellspacing=2 border=0>');
                foreach ('stdno','avetries','difficulty') {
                    $r->print('<tr><td bgcolor="#AAAAAA">'.$lt{$_}.'</td>'.
                              '<td bgcolor="#CCCCCC">'.
                              &prettyprint($_,$dynmeta{$_})."</td></tr>\n");
                }
                $r->print('</table>');    
            }
            $r->print('<h4>'.&mt('Evaluation Data').'</h4>'.
                      '<table cellspacing=2 border=0>');
            foreach ('clear','depth','helpful','correct','technical') {
                $r->print('<tr><td bgcolor="#AAAAAA">'.$lt{$_}.'</td>'.
                          '<td bgcolor="#CCCCCC">'.
                          &prettyprint($_,$dynmeta{$_})."</td></tr>\n");
            }
            $r->print('</table>');
            $uri=~/^\/res\/(\w+)\/(\w+)\//; 
            if ((($ENV{'user.domain'} eq $1) && ($ENV{'user.name'} eq $2))
                || ($ENV{'user.role.ca./'.$1.'/'.$2})) {
                $r->print('<h4>'.&mt('Evaluation Comments').' ('.
                          &mt('visible to author and co-authors only').
                          ')</h4>'.
                          '<blockquote>'.$dynmeta{'comments'}.'</blockquote>');
                $r->print('<a name="bombs" /><h4>'.&mt('Error Messages').' ('.
                          &mt('visible to author and co-authors only').')'.
                          '</h4>'.
                          &Apache::lonmsg::retrieve_author_res_msg($uri));
            }
            # All other stuff
            $r->print('<h3>'.
                &mt('Additional Metadata (non-standard, parameters, exports)').
                      '</h3>');
            foreach (sort keys %content) {
                my $name=$_;
                unless ($name=~/\.display$/) {
                    my $display=&Apache::lonnet::metadata($uri,
                                                          $name.'.display');
                    unless ($display) { $display=$name; };
                    my $otherinfo='';
                    foreach ('name','part','type','default') {
                        if (defined(&Apache::lonnet::metadata($uri,
                                                              $name.'.'.$_))) {
                            $otherinfo.=' '.$_.'='.
                                &Apache::lonnet::metadata($uri,
                                                          $name.'.'.$_).'; ';
                        }
                    }
                    $r->print('<b>'.$display.':</b> '.$content{$name});
                    if ($otherinfo) {
                        $r->print(' ('.$otherinfo.')');
                    }
                    $r->print("<br />\n");
                }
            }
        }
        # End Resource Space Call
    } else {
        # Construction Space Call
        # Set document type
        &Apache::loncommon::content_type($r,'text/html');
        $r->send_http_header;
        #
        return OK if $r->header_only;
        # Header
        my $disuri=$uri;
        my $fn=&Apache::lonnet::filelocation('',$uri);
        $disuri=~s/^\/\~/\/priv\//;
        $disuri=~s/\.meta$//;
        my $target=$uri;
        $target=~s/^\/\~/\/res\/$ENV{'request.role.domain'}\//;
        $target=~s/\.meta$//;
        my $bombs=&Apache::lonmsg::retrieve_author_res_msg($target);
        if ($bombs) {
            if ($ENV{'form.delmsg'}) {
                if (&Apache::lonmsg::del_url_author_res_msg($target) eq 'ok') {
                    $bombs=&mt('Messages deleted.');
                } else {
                    $bombs=&mt('Error deleting messages');
                }
            }
            my $bodytag=&Apache::loncommon::bodytag('Error Messages');
            my $del=&mt('Delete Messages');
            $r->print(<<ENDBOMBS);
<html><head><title>Edit Catalog Information</title></head>
$bodytag
<h1>$disuri</h1>
<form method="post" name="defaultmeta">
<input type="submit" name="delmsg" value="$del" />
<br />$bombs
</form>
</body>
</html>
ENDBOMBS
        } else {
            my $displayfile='Catalog Information for '.$disuri;
            if ($disuri=~/\/default$/) {
                my $dir=$disuri;
                $dir=~s/default$//;
                $displayfile=
                    &mt('Default Cataloging Information for Directory').' '.
                    $dir;
            }
            my $bodytag=
                &Apache::loncommon::bodytag('Edit Catalog Information');
            %Apache::lonpublisher::metadatafields=();
            %Apache::lonpublisher::metadatakeys=();
            &Apache::lonpublisher::metaeval(&Apache::lonnet::getfile($fn));
            $r->print(<<ENDEDIT);
<html><head><title>Edit Catalog Information</title></head>
$bodytag
<h1>$displayfile</h1>
<form method="post" name="defaultmeta">
ENDEDIT
            $r->print('<script language="JavaScript">'.
                      &Apache::loncommon::browser_and_searcher_javascript.
                      '</script>');
            my %lt=&fieldnames();
            foreach ('author','title','subject','keywords','abstract','notes',
                     'copyright','customdistributionfile','language',
                     'standards',
                     'lowestgradelevel','highestgradelevel',
                     'obsolete','obsoletereplacement') {
                if (defined($ENV{'form.new_'.$_})) {
                    $Apache::lonpublisher::metadatafields{$_}=
                        $ENV{'form.new_'.$_};
                }
                unless ($Apache::lonpublisher::metadatafields{'copyright'}) {
                    $Apache::lonpublisher::metadatafields{'copyright'}=
                        'default';
                }
                $r->print('<p>'.$lt{$_}.': '.
                          &prettyinput
                          ($_,$Apache::lonpublisher::metadatafields{$_},
                           'new_'.$_,'defaultmeta').'</p>');
            }
            if ($ENV{'form.store'}) {
                my $mfh;
                unless ($mfh=Apache::File->new('>'.$fn)) {
                    $r->print('<p><font color=red>'.
                              &mt('Could not write metadata').', '.
                              &mt('FAIL').'</font>');
                } else {
                    foreach (sort keys %Apache::lonpublisher::metadatafields) {
                        unless ($_=~/\./) {
                            my $unikey=$_;
                            $unikey=~/^([A-Za-z]+)/;
                            my $tag=$1;
                            $tag=~tr/A-Z/a-z/;
                            print $mfh "\n\<$tag";
                            foreach (split(/\,/,
                                 $Apache::lonpublisher::metadatakeys{$unikey})
                                     ) {
                                my $value=
                        $Apache::lonpublisher::metadatafields{$unikey.'.'.$_};
                                $value=~s/\"/\'\'/g;
                                print $mfh ' '.$_.'="'.$value.'"';
                            }
                            print $mfh '>'.
                                &HTML::Entities::encode($Apache::lonpublisher::metadatafields{$unikey},'<>&"').
                                '</'.$tag.'>';
                        }
                    }
                    $r->print('<p>'.&mt('Wrote Metadata'));
                }
            }
            $r->print('<br /><input type="submit" name="store" value="'.
                      &mt('Store Catalog Information').'"></form>'.
                      '</body></html>');
        }
    }
    return OK;
}

# BEGIN Block
BEGIN {
    # Get columns of MySQL metadata table
    @columns=&Apache::lonmysql::col_order('metadata');
}

1;
__END__

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