# The LearningOnline Network with CAPA # Metadata display handler # # $Id: lonmeta.pm,v 1.128 2005/11/18 23:47:33 banghart 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; ############################################################ ############################################################ ## ## &get_dynamic_metadata_from_sql($url) ## ## Queries sql database for dynamic metdata ## Returns a hash of hashes, with keys of urls which match $url ## Returned fields are given below. ## ## Examples: ## ## %DynamicMetadata = &Apache::lonmeta::get_dynmaic_metadata_from_sql ## ('/res/msu/korte/'); ## ## $DynamicMetadata{'/res/msu/korte/example.problem'}->{$field} ## ############################################################ ############################################################ sub get_dynamic_metadata_from_sql { my ($url) = shift(); my ($authordom,$author)=($url=~m:^/res/(\w+)/(\w+)/:); if (! defined($authordom)) { $authordom = shift(); } if (! defined($author)) { $author = shift(); } if (! defined($authordom) || ! defined($author)) { return (); } my @Fields = ('url','count','course', 'goto','goto_list', 'comefrom','comefrom_list', 'sequsage','sequsage_list', 'stdno','stdno_list', 'dependencies', 'avetries','avetries_list', 'difficulty','difficulty_list', 'disc','disc_list', 'clear','technical','correct', 'helpful','depth'); # my $query = 'SELECT '.join(',',@Fields). ' FROM metadata WHERE url LIKE "'.$url.'%"'; my $server = &Apache::lonnet::homeserver($author,$authordom); my $reply = &Apache::lonnet::metadata_query($query,undef,undef, ,[$server]); return () if (! defined($reply) || ref($reply) ne 'HASH'); my $filename = $reply->{$server}; if (! defined($filename) || $filename =~ /^error/) { return (); } my $max_time = time + 10; # wait 10 seconds for results at most my %ReturnHash; # # Look for results my $finished = 0; while (! $finished && time < $max_time) { my $datafile=$Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/'.$filename; if (! -e "$datafile.end") { next; } my $fh; if (!($fh=Apache::File->new($datafile))) { next; } while (my $result = <$fh>) { chomp($result); next if (! $result); my @Data = map { &Apache::lonnet::unescape($_); } split(',',$result); my $url = $Data[0]; for (my $i=0;$i<=$#Fields;$i++) { $ReturnHash{$url}->{$Fields[$i]}=$Data[$i]; } } $finished = 1; } # return %ReturnHash; } # 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); # # Debugging code I will probably need later if (0) { &Apache::lonnet::logthis('Dynamic Metadata'); while(my($k,$v)=each(%Data)){ &Apache::lonnet::logthis(' "'.$k.'"=>"'.$v.'"'); } &Apache::lonnet::logthis('-------------------'); } 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').' ['.$aname.'@'.$adom.']'; } # Pretty display sub evalgraph { my $value=shift; if (! $value) { return ''; } my $val=int($value*10.+0.5)-10; my $output=''; if ($val>=20) { $output.=''; } else { $output.=''. ''; } $output.=''; if ($val>20) { $output.=''. ''; } else { $output.=''; } $output.='
          ('.sprintf("%5.2f",$value).')
'; return $output; } sub diffgraph { my $value=shift; if (! $value) { return ''; } my $val=int(40.0*$value+0.5); my @colors=('#FF9933','#EEAA33','#DDBB33','#CCCC33', '#BBDD33','#CCCC33','#DDBB33','#EEAA33'); my $output=''; for (my $i=0;$i<8;$i++) { if ($val>$i*5) { $output.=''; } else { $output.=''; } } $output.='
   ('.sprintf("%3.2f",$value).')
'; return $output; } # The field names sub fieldnames { my $file_type=shift; my %fields = ('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', 'courserestricted' => 'Course Restricting Metadata'); if (! defined($file_type) || $file_type ne 'portfolio') { %fields = (%fields, 'domain' => 'Domain', 'standards' => 'Standards', 'mime' => 'MIME Type', 'language' => 'Language', 'creationdate' => 'Creation Date', 'lastrevisiondate' => 'Last Revision Date', 'owner' => 'Publisher/Owner', 'copyright' => 'Copyright/Distribution', 'customdistributionfile' => 'Custom Distribution File', 'sourceavail' => 'Source Available', 'sourcerights' => 'Source 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', 'disc' => 'Degree of discrimination', 'dependencies' => 'Resources used by this resource', ); } return &Apache::lonlocal::texthash(%fields); } sub select_course { my ($r)=@_; my %courses; foreach my $key (keys (%env)) { if ($key =~ m/\.metadata\./) { $key =~ m/^course\.(.+)(\.metadata.+$)/; my $course = $1; my $coursekey = 'course.'.$course.'.description'; my $value = $env{$coursekey}; $courses{$coursekey} = $value; } } $r->print('

Course Related Meta-Data


'); $r->print('
'); $r->print('Select course restrictions
'); $r->print(''); } $key =~ m/(^.+)\.description$/; $r->print(''); } unless ($meta_not_found) { $r->print('
'); $r->print(''); $r->print('
'); } return 'ok'; } # Pretty printing of metadata field sub prettyprint { my ($type,$value,$target,$prefix,$form,$noformat)=@_; # $target,$prefix,$form are optional and for filecrumbs only if (! defined($value)) { return ' '; } # Title if ($type eq 'title') { return ''.$value.''; } # 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); } # Copyright if ($type eq 'sourceavail') { return &Apache::loncommon::source_copyrightdescription($value); } # MIME if ($type eq 'mime') { return ' '. &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 if (! $env{'user.adv'}) { return '- '.&mt('not displayed').' -'; } # File if (($type eq 'customdistributionfile') || ($type eq 'obsoletereplacement') || ($type eq 'goto_list') || ($type eq 'comefrom_list') || ($type eq 'sequsage_list') || ($type eq 'dependencies')) { return ''; } # 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' || $type eq 'disc') { return &diffgraph($value); } # List of courses if ($type=~/\_list/) { my @Courses = split(/\s*\,\s*/,$value); my $Str; foreach my $course (@Courses) { my %courseinfo = &Apache::lonnet::coursedescription($course); if (! exists($courseinfo{'num'}) || $courseinfo{'num'} eq '') { next; } if ($Str ne '') { $Str .= '
'; } $Str .= ''. $courseinfo{'description'}.''; } return $Str; } # No pretty print found return $value; } # Pretty input of metadata field sub direct { return shift; } sub selectbox { my ($name,$value,$functionref,@idlist)=@_; if (! defined($functionref)) { $functionref=\&direct; } my $selout=''; } sub relatedfield { my ($show,$relatedsearchflag,$relatedsep,$fieldname,$relatedvalue)=@_; if (! $relatedsearchflag) { return ''; } if (! defined($relatedsep)) { $relatedsep=' '; } if (! $show) { return $relatedsep.' '; } return $relatedsep.''; } sub prettyinput { my ($type,$value,$fieldname,$formname, $relatedsearchflag,$relatedsep,$relatedvalue,$size,$course_key)=@_; if (! defined($size)) { $size = 80; } my $output; if (defined($course_key)) { my $stu_add; my $only_one; my %meta_options; my @cur_values_inst; my $cur_values_stu; my $values = $env{$course_key.'.metadata.'.$_.'.values'}; if ($env{$course_key.'.metadata.'.$_.'.options'} =~ m/stuadd/) { $stu_add = 'true'; } if ($env{$course_key.'.metadata.'.$_.'.options'} =~ m/onlyone/) { $only_one = 'true'; } # need to take instructor values out of list where instructor and student # values may be mixed. if ($values && $stu_add) { foreach (split(/,/,$values)) { $_ =~ s/^\s+//; $meta_options{$_} = $_; } foreach (split(/,/,$value)) { $_ =~ s/^\s+//; if ($meta_options{$_}) { push(@cur_values_inst,$_); } else { $cur_values_stu .= $_.','; } } } if ($type eq 'author') { return ''. &relatedfield(1,$relatedsearchflag,$relatedsep,$fieldname, $relatedvalue); } if ($type eq 'courserestricted') { return (''); } if ($type eq 'authorspace') { } if ($type eq 'modifyinguser') { } if ($type eq 'subject') { } if ($type eq 'keywords') { if ($only_one) { $output .= (&Apache::loncommon::select_form($value,'new_keywords',%meta_options)); } else { $output .= (&Apache::loncommon::multiple_select_form('new_keywords',\@cur_values_inst,undef,\%meta_options)); } if ($stu_add) { $output .= ''. &relatedfield(1,$relatedsearchflag,$relatedsep,$fieldname, $relatedvalue); } return ($output); } if ($type eq 'notes') { } if ($type eq 'abstract') { } if (($type eq 'lowestgradelevel') || ($type eq 'highestgradelevel')) { return &Apache::loncommon::select_level_form($value,$fieldname). &relatedfield(0,$relatedsearchflag,$relatedsep); } return(); } # 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); } # Source Copyright if ($type eq 'sourceavail') { return &selectbox($fieldname, $value, \&Apache::loncommon::source_copyrightdescription, (&Apache::loncommon::source_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 ''. &relatedfield(0,$relatedsearchflag,$relatedsep); } # Obsolete replacement file if ($type eq 'obsoletereplacement') { return '".&mt('Select').''. &relatedfield(0,$relatedsearchflag,$relatedsep); } # Customdistribution file if ($type eq 'customdistributionfile') { return '".&mt('Select').''. &relatedfield(0,$relatedsearchflag,$relatedsep); } # Source Customdistribution file if ($type eq 'sourcerights') { return '".&mt('Select').''. &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/\"/\"\;/gs; return ''. &relatedfield(1,$relatedsearchflag,$relatedsep,$fieldname, $relatedvalue); } # Main Handler sub handler { my $r=shift; # my $uri=$r->uri; # # Set document type &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; # my ($resdomain,$resuser)= (&Apache::lonnet::declutter($uri)=~/^(\w+)\/(\w+)\//); my $html=&Apache::lonxml::xmlbegin(); $r->print($html.''. 'Catalog Information'. ''); if ($uri=~m:/adm/bombs/(.*)$:) { $r->print(&Apache::loncommon::bodytag('Error Messages')); # Looking for all bombs? &report_bombs($r,$uri); } elsif ($uri=~/\/portfolio\//) { ($resdomain,$resuser)= (&Apache::lonnet::declutter($uri)=~m|^(\w+)/(\w+)/portfolio|); $r->print(&Apache::loncommon::bodytag ('Edit Portfolio File Information','','','',$resdomain)); &present_editable_metadata($r,$uri,'portfolio'); &select_course($r); } elsif ($uri=~/^\/\~/) { # Construction space $r->print(&Apache::loncommon::bodytag ('Edit Catalog Information','','','',$resdomain)); &present_editable_metadata($r,$uri); } else { $r->print(&Apache::loncommon::bodytag ('Catalog Information','','','',$resdomain)); &present_uneditable_metadata($r,$uri); } $r->print(''); return OK; } ##################################################### ##################################################### ### ### ### Report Bombs ### ### ### ##################################################### ##################################################### sub report_bombs { my ($r,$uri) = @_; # Set document type $uri =~ s:/adm/bombs/::; $uri = &Apache::lonnet::declutter($uri); $r->print('

'.&Apache::lonnet::clutter($uri).'

'); my ($domain,$author)=($uri=~/^(\w+)\/(\w+)\//); if (&Apache::loncacc::constructaccess('/~'.$author.'/',$domain)) { if ($env{'form.clearbombs'}) { &Apache::lonmsg::clear_author_res_msg($uri); } my $clear=&mt('Clear all Messages in Subdirectory'); $r->print(< ENDCLEAR my %brokenurls = &Apache::lonmsg::all_url_author_res_msg($author,$domain); foreach (sort(keys(%brokenurls))) { if ($_=~/^\Q$uri\E/) { $r->print (''.$_.''. &Apache::lonmsg::retrieve_author_res_msg($_). '
'); } } } else { $r->print(&mt('Not authorized')); } return; } ##################################################### ##################################################### ### ### ### Uneditable Metadata Display ### ### ### ##################################################### ##################################################### sub present_uneditable_metadata { my ($r,$uri) = @_; # my %content=(); # 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 uri target prefix form size $disuri=&Apache::lonhtmlcommon::crumbs($disuri,undef, undef, undef,'+1'); $disuri =~ s:
::g; # obsolete my $obsolete=$content{'obsolete'}; my $obsoletewarning=''; if (($obsolete) && ($env{'user.adv'})) { $obsoletewarning='

'. &mt('This resource has been marked obsolete by the author(s)'). '

'; } # my %lt=&fieldnames(); my $table=''; my $title = $content{'title'}; if (! defined($title)) { $title = 'Untitled Resource'; } foreach ('title', 'author', 'subject', 'keywords', 'notes', 'abstract', 'lowestgradelevel', 'highestgradelevel', 'standards', 'mime', 'language', 'creationdate', 'lastrevisiondate', 'owner', 'copyright', 'customdistributionfile', 'sourceavail', 'sourcerights', 'obsolete', 'obsoletereplacement') { $table.=''.$lt{$_}. ''. &prettyprint($_,$content{$_}).''; delete $content{$_}; } # $r->print(<$title

$disuri
$obsoletewarning $versiondisplay

$table
ENDHEAD if ($env{'user.adv'}) { &print_dynamic_metadata($r,$uri,\%content); } return; } sub print_dynamic_metadata { my ($r,$uri,$content) = @_; # my %content = %$content; my %lt=&fieldnames(); # my $description = 'Dynamic Metadata (updated periodically)'; $r->print('

'.&mt($description).'

'. &mt('Processing')); $r->rflush(); my %items=&fieldnames(); my %dynmeta=&dynamicmeta($uri); # # General Access and Usage Statistics if (exists($dynmeta{'count'}) || exists($dynmeta{'sequsage'}) || exists($dynmeta{'comefrom'}) || exists($dynmeta{'goto'}) || exists($dynmeta{'course'})) { $r->print('

'.&mt('Access and Usage Statistics').'

'. ''); foreach ('count', 'sequsage','sequsage_list', 'comefrom','comefrom_list', 'goto','goto_list', 'course','course_list') { $r->print(''. '\n"); } $r->print('
'.$lt{$_}.''. &prettyprint($_,$dynmeta{$_})."
'); } else { $r->print('

'.&mt('No Access or Usages Statistics are available for this resource.').'

'); } # # Assessment statistics if ($uri=~/\.(problem|exam|quiz|assess|survey|form)$/) { if (exists($dynmeta{'stdno'}) || exists($dynmeta{'avetries'}) || exists($dynmeta{'difficulty'}) || exists($dynmeta{'disc'})) { # This is an assessment, print assessment data $r->print('

'. &mt('Overall Assessment Statistical Data'). '

'. ''); $r->print(''. ''."\n"); foreach ('avetries','difficulty','disc') { $r->print(''. ''."\n"); } $r->print('
'.$lt{'stdno'}.''. &prettyprint('stdno',$dynmeta{'stdno'}). '
'.$lt{$_}.''. &prettyprint($_,sprintf('%5.2f',$dynmeta{$_})). '
'); } if (exists($dynmeta{'stats'})) { # # New assessment statistics $r->print('

'. &mt('Detailed Assessment Statistical Data'). '

'); my $table = ''. ''. ''. ''. ''. ''. ''. ''. ''. ''.$/; foreach my $identifier (sort(keys(%{$dynmeta{'stats'}}))) { my $data = $dynmeta{'stats'}->{$identifier}; my $course = $data->{'course'}; my %courseinfo = &Apache::lonnet::coursedescription($course); if (! exists($courseinfo{'num'}) || $courseinfo{'num'} eq '') { &Apache::lonnet::logthis('lookup for '.$course.' failed'); next; } $table .= ''; $table .= ''; $table .= ''; $table .= ''; foreach ('avetries','difficulty','disc') { $table .= ''; } $table .= ''; $table .= ''.$/; } $table .= '
CourseSection(s)Num StudentsMean TriesDegree of DifficultyDegree of DiscriminationTime of computation
'.$courseinfo{'description'}.''.$data->{'sections'}.''.$data->{'stdno'}.''; if (exists($data->{$_})) { $table .= sprintf('%.2f',$data->{$_}).' '; } else { $table .= ''; } $table .= ''. &Apache::lonlocal::locallocaltime($data->{'timestamp'}). '
'.$/; $r->print($table); } else { $r->print('No new dynamic data found.'); } } else { $r->print('

'. &mt('No Assessment Statistical Data is available for this resource'). '

'); } # # if (exists($dynmeta{'clear'}) || exists($dynmeta{'depth'}) || exists($dynmeta{'helpful'}) || exists($dynmeta{'correct'}) || exists($dynmeta{'technical'})){ $r->print('

'.&mt('Evaluation Data').'

'. ''); foreach ('clear','depth','helpful','correct','technical') { $r->print(''. '\n"); } $r->print('
'.$lt{$_}.''. &prettyprint($_,$dynmeta{$_})."
'); } else { $r->print('

'.&mt('No Evaluation Data is available for this resource.').'

'); } $uri=~/^\/res\/(\w+)\/(\w+)\//; if ((($env{'user.domain'} eq $1) && ($env{'user.name'} eq $2)) || ($env{'user.role.ca./'.$1.'/'.$2})) { if (exists($dynmeta{'comments'})) { $r->print('

'.&mt('Evaluation Comments').' ('. &mt('visible to author and co-authors only'). ')

'. '
'.$dynmeta{'comments'}.'
'); } else { $r->print('

'.&mt('There are no Evaluation Comments on this resource.').'

'); } my $bombs = &Apache::lonmsg::retrieve_author_res_msg($uri); if (defined($bombs) && $bombs ne '') { $r->print('

'.&mt('Error Messages').' ('. &mt('visible to author and co-authors only').')'. '

'.$bombs); } else { $r->print('

'.&mt('There are currently no Error Messages for this resource.').'

'); } } # # All other stuff $r->print('

'. &mt('Additional Metadata (non-standard, parameters, exports)'). '

'); foreach (sort(keys(%content))) { my $name=$_; if ($name!~/\.display$/) { my $display=&Apache::lonnet::metadata($uri, $name.'.display'); if (! $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('\n"); } } $r->print("
'.$display.''.$content{$name}); if ($otherinfo) { $r->print(' ('.$otherinfo.')'); } $r->print("
"); return; } ##################################################### ##################################################### ### ### ### Editable metadata display ### ### ### ##################################################### ##################################################### sub present_editable_metadata { my ($r,$uri, $file_type) = @_; # Construction Space Call # Header my $disuri=$uri; my $fn=&Apache::lonnet::filelocation('',$uri); $disuri=~s/^\/\~/\/priv\//; $disuri=~s/\.meta$//; $disuri=~s|^/editupload||; my $target=$uri; $target=~s/^\/\~/\/res\/$env{'request.role.domain'}\//; $target=~s/\.meta$//; my $bombs=&Apache::lonmsg::retrieve_author_res_msg($target); if ($bombs) { my $showdel=1; if ($env{'form.delmsg'}) { if (&Apache::lonmsg::del_url_author_res_msg($target) eq 'ok') { $bombs=&mt('Messages deleted.'); $showdel=0; } else { $bombs=&mt('Error deleting messages'); } } if ($env{'form.clearmsg'}) { my $cleardir=$target; $cleardir=~s/\/[^\/]+$/\//; if (&Apache::lonmsg::clear_author_res_msg($cleardir) eq 'ok') { $bombs=&mt('Messages cleared.'); $showdel=0; } else { $bombs=&mt('Error clearing messages'); } } my $del=&mt('Delete Messages for this Resource'); my $clear=&mt('Clear all Messages in Subdirectory'); my $goback=&mt('Back to Source File'); $r->print(<$disuri
ENDBOMBS if ($showdel) { $r->print(< ENDDEL } else { $r->print(''.$goback.''); } $r->print('
'.$bombs); } else { my $displayfile='Catalog Information for '.$disuri; if ($disuri=~/\/default$/) { my $dir=$disuri; $dir=~s/default$//; $displayfile= &mt('Default Cataloging Information for Directory').' '. $dir; } %Apache::lonpublisher::metadatafields=(); %Apache::lonpublisher::metadatakeys=(); my $result=&Apache::lonnet::getfile($fn); if ($result == -1){ $r->print('Creating new '.$disuri); } else { &Apache::lonpublisher::metaeval($result); } $r->print(<$displayfile ENDEDIT $r->print(''); my %lt=&fieldnames($file_type); my $output; my @fields; if ($file_type eq 'portfolio') { @fields = ('author','title','subject','keywords','abstract','notes','lowestgradelevel', 'highestgradelevel','courserestricted'); } else { @fields = ('author','title','subject','keywords','abstract','notes', 'copyright','customdistributionfile','language', 'standards', 'lowestgradelevel','highestgradelevel','sourceavail','sourcerights', 'obsolete','obsoletereplacement'); } my $metacourse; if ($env{'form.metacourse'} ) { $Apache::lonpublisher::metadatafields{'courserestricted'} = $env{'form.metacourse'}; $metacourse = $env{'form.metacourse'}; } else { if (! $Apache::lonpublisher::metadatafields{'courserestricted'}) { $Apache::lonpublisher::metadatafields{'courserestricted'}= 'none'; $metacourse = 'none'; } else { $metacourse = $Apache::lonpublisher::metadatafields{'courserestricted'}; } } if (! $Apache::lonpublisher::metadatafields{'copyright'}) { $Apache::lonpublisher::metadatafields{'copyright'}= 'default'; } if ($metacourse ne 'none') { $r->print('Document metadata restricted by : '.$env{$metacourse.".description"}."
"); } foreach (@fields) { if (defined($env{'form.new_'.$_})) { $Apache::lonpublisher::metadatafields{$_}= join(',',&Apache::loncommon::get_env_multiple('form.new_'.$_)); } my $field_name = $_; if ($metacourse ne 'none') { # handle restrictions here if ($env{$metacourse.'.metadata.'.$_.'.options'} =~ m/active/){ $output.=('

'.$lt{$_}.': '. &prettyinput($_, $Apache::lonpublisher::metadatafields{$_}, 'new_'.$_,'defaultmeta',undef,undef,undef,undef,$metacourse).'

'); } elsif ($_ eq 'courserestricted') { $output.=( &prettyinput($field_name, $Apache::lonpublisher::metadatafields{$_}, 'new_'.$field_name,'defaultmeta',undef,undef,undef,undef,$metacourse)); } } else { if ($_ ne 'courserestricted') { $output.=('

'.$lt{$_}.': '. &prettyinput($_, $Apache::lonpublisher::metadatafields{$_}, 'new_'.$_,'defaultmeta').'

'); } else { $output.=&prettyinput($field_name, $Apache::lonpublisher::metadatafields{$_}, 'new_'.$field_name,'defaultmeta'); } } } $output.=('

'.$lt{$_}.': '. &prettyinput($_, $Apache::lonpublisher::metadatafields{$_}, 'new_'.$_,'defaultmeta',undef,undef,undef,undef,$metacourse).'

'); if ($env{'form.store'}) { my $mfh; my $formname='store'; my $file_content; foreach my $meta_field (keys %env) { if (&Apache::loncommon::get_env_multiple('form.new_keywords')) { $Apache::lonpublisher::metadatafields{'keywords'} = join (',', &Apache::loncommon::get_env_multiple('form.new_keywords')); } } foreach (sort keys %Apache::lonpublisher::metadatafields) { next if ($_ =~ /\./); my $unikey=$_; $unikey=~/^([A-Za-z]+)/; my $tag=$1; $tag=~tr/A-Z/a-z/; $file_content.= "\n\<$tag"; foreach (split(/\,/, $Apache::lonpublisher::metadatakeys{$unikey}) ) { my $value= $Apache::lonpublisher::metadatafields{$unikey.'.'.$_}; $value=~s/\"/\'\'/g; $file_content.=' '.$_.'="'.$value.'"' ; # print $mfh ' '.$_.'="'.$value.'"'; } $file_content.= '>'. &HTML::Entities::encode ($Apache::lonpublisher::metadatafields{$unikey}, '<>&"'). ''; } if ($fn =~ /\/portfolio\//) { $fn =~ /\/portfolio\/(.*)$/; my $new_fn = '/'.$1; $env{'form.'.$formname}=$file_content; $env{'form.'.$formname.'.filename'}=$new_fn; &Apache::lonnet::userfileupload('uploaddoc','', 'portfolio'.$env{'form.currentpath'}); if (&Apache::lonnet::userfileupload($formname,'','portfolio') eq 'error: no uploaded file') { $r->print('

'. &mt('Could not write metadata').', '. &mt('FAIL').'

'); } else { $r->print('

'.&mt('Wrote Metadata'). ' '.&Apache::lonlocal::locallocaltime(time). '

'); } } else { if (! ($mfh=Apache::File->new('>'.$fn))) { $r->print('

'. &mt('Could not write metadata').', '. &mt('FAIL').'

'); } else { print $mfh $file_content; $r->print('

'.&mt('Wrote Metadata'). ' '.&Apache::lonlocal::locallocaltime(time). '

'); } } } $r->print($output.'
'); } $r->print(''); return; } 1; __END__