--- loncom/interface/lonmeta.pm 2004/04/19 16:43:53 1.74
+++ loncom/interface/lonmeta.pm 2005/12/08 02:17:56 1.135
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Metadata display handler
#
-# $Id: lonmeta.pm,v 1.74 2004/04/19 16:43:53 matthew Exp $
+# $Id: lonmeta.pm,v 1.135 2005/12/08 02:17:56 banghart Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -17,7 +17,7 @@
# 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
+# 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
#
@@ -31,9 +31,9 @@ package Apache::lonmeta;
use strict;
use LONCAPA::lonmetadata();
use Apache::Constants qw(:common);
-use Apache::lonnet();
+use Apache::lonnet;
use Apache::loncommon();
-use Apache::lonhtmlcommon();
+use Apache::lonhtmlcommon();
use Apache::lonmsg;
use Apache::lonpublisher;
use Apache::lonlocal;
@@ -41,6 +41,87 @@ 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);
@@ -155,19 +236,25 @@ sub diffgraph {
# The field names
sub fieldnames {
- return &Apache::lonlocal::texthash
- (
- 'title' => 'Title',
+ my $file_type=shift;
+ my %fields =
+ ('title' => 'Title',
'author' =>'Author(s)',
'authorspace' => 'Author Space',
'modifyinguser' => 'Last Modifying User',
'subject' => 'Subject',
+ 'standards' => 'Standards',
'keywords' => 'Keyword(s)',
'notes' => 'Notes',
'abstract' => 'Abstract',
'lowestgradelevel' => 'Lowest Grade Level',
'highestgradelevel' => 'Highest Grade Level',
- 'standards' => 'Standards',
+ 'courserestricted' => 'Course Restricting Metadata');
+
+ if (! defined($file_type) || $file_type ne 'portfolio') {
+ %fields =
+ (%fields,
+ 'domain' => 'Domain',
'mime' => 'MIME Type',
'language' => 'Language',
'creationdate' => 'Creation Date',
@@ -175,6 +262,8 @@ sub fieldnames {
'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)',
@@ -195,13 +284,54 @@ sub fieldnames {
'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('
+ENDCLEAR
my %brokenurls =
&Apache::lonmsg::all_url_author_res_msg($author,$domain);
foreach (sort(keys(%brokenurls))) {
@@ -525,7 +746,7 @@ sub present_uneditable_metadata {
# obsolete
my $obsolete=$content{'obsolete'};
my $obsoletewarning='';
- if (($obsolete) && ($ENV{'user.adv'})) {
+ if (($obsolete) && ($env{'user.adv'})) {
$obsoletewarning=''.
&mt('This resource has been marked obsolete by the author(s)').
'
';
@@ -552,7 +773,9 @@ sub present_uneditable_metadata {
'lastrevisiondate',
'owner',
'copyright',
- 'customdistributionfile',
+ 'customdistributionfile',
+ 'sourceavail',
+ 'sourcerights',
'obsolete',
'obsoletereplacement') {
$table.=''.$lt{$_}.
@@ -568,11 +791,11 @@ $disuri
$obsoletewarning
$versiondisplay
-
+
ENDHEAD
- if ($ENV{'user.adv'}) {
+ if ($env{'user.adv'}) {
&print_dynamic_metadata($r,$uri,\%content);
}
return;
@@ -590,8 +813,6 @@ sub print_dynamic_metadata {
$r->rflush();
my %items=&fieldnames();
my %dynmeta=&dynamicmeta($uri);
- &Apache::lonnet::logthis('dynamic metadata keys:'.$/.
- join("\n",keys(%dynmeta)));
#
# General Access and Usage Statistics
if (exists($dynmeta{'count'}) ||
@@ -600,7 +821,7 @@ sub print_dynamic_metadata {
exists($dynmeta{'goto'}) ||
exists($dynmeta{'course'})) {
$r->print(''.&mt('Access and Usage Statistics').' '.
- '');
+ '');
foreach ('count',
'sequsage','sequsage_list',
'comefrom','comefrom_list',
@@ -625,7 +846,7 @@ sub print_dynamic_metadata {
$r->print(''.
&mt('Overall Assessment Statistical Data').
' '.
- '');
+ '');
$r->print(''.$lt{'stdno'}.' '.
''.
&prettyprint('stdno',$dynmeta{'stdno'}).
@@ -644,7 +865,7 @@ sub print_dynamic_metadata {
$r->print(''.
&mt('Detailed Assessment Statistical Data').
' ');
- my $table = ''.
+ my $table = ''.
''.
'Course '.
'Section(s) '.
@@ -704,7 +925,7 @@ sub print_dynamic_metadata {
exists($dynmeta{'correct'}) ||
exists($dynmeta{'technical'})){
$r->print(''.&mt('Evaluation Data').' '.
- '');
+ '');
foreach ('clear','depth','helpful','correct','technical') {
$r->print(''.$lt{$_}.' '.
''.
@@ -715,8 +936,8 @@ sub print_dynamic_metadata {
$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 ((($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').
@@ -738,7 +959,7 @@ sub print_dynamic_metadata {
# All other stuff
$r->print(''.
&mt('Additional Metadata (non-standard, parameters, exports)').
- ' ');
+ ' ');
foreach (sort(keys(%content))) {
my $name=$_;
if ($name!~/\.display$/) {
@@ -756,16 +977,19 @@ sub print_dynamic_metadata {
$name.'.'.$_).'; ';
}
}
- $r->print(''.$display.': '.$content{$name});
+ $r->print(''.$display.' '.$content{$name});
if ($otherinfo) {
$r->print(' ('.$otherinfo.')');
}
- $r->print(" \n");
+ $r->print(" \n");
}
}
+ $r->print("
");
return;
}
+
+
#####################################################
#####################################################
### ###
@@ -774,32 +998,54 @@ sub print_dynamic_metadata {
#####################################################
#####################################################
sub present_editable_metadata {
- my ($r,$uri) = @_;
+ 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/^\/\~/\/res\/$env{'request.role.domain'}\//;
$target=~s/\.meta$//;
my $bombs=&Apache::lonmsg::retrieve_author_res_msg($target);
if ($bombs) {
- if ($ENV{'form.delmsg'}) {
+ 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');
}
}
- my $del=&mt('Delete 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
-
- $bombs
ENDBOMBS
+ if ($showdel) {
+ $r->print(<
+
+ENDDEL
+ } else {
+ $r->print(' '.$goback.'');
+ }
+ $r->print(' '.$bombs);
} else {
my $displayfile='Catalog Information for '.$disuri;
if ($disuri=~/\/default$/) {
@@ -809,72 +1055,155 @@ ENDBOMBS
&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));
+ my $result=&Apache::lonnet::getfile($fn);
+ if ($result == -1){
+ $r->print('Creating new '.$disuri);
+ } else {
+ &Apache::lonpublisher::metaeval($result);
+ }
$r->print(<Edit Catalog Information
-$bodytag
$displayfile
ENDEDIT
$r->print('');
- my %lt=&fieldnames();
- foreach ('author','title','subject','keywords','abstract','notes',
+ my %lt=&fieldnames($file_type);
+ my $output;
+ my @fields;
+ if ($file_type eq 'portfolio') {
+ @fields = ('author','title','subject','keywords','abstract','notes','lowestgradelevel',
+ 'highestgradelevel','standards','courserestricted');
+ } else {
+ @fields = ('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_'.$_};
+ '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'}) {
+ }
+ if (! $Apache::lonpublisher::metadatafields{'copyright'}) {
$Apache::lonpublisher::metadatafields{'copyright'}=
- 'default';
+ 'default';
+ }
+ if ($metacourse ne 'none') {
+ $r->print('Using: '.$env{$metacourse.".description"}." metadata framework ");
+ }
+ foreach my $field_name(@fields) {
+
+ if (defined($env{'form.new_'.$field_name})) {
+ $Apache::lonpublisher::metadatafields{$field_name}=
+ join(',',&Apache::loncommon::get_env_multiple('form.new_'.$field_name));
+ }
+ if ($metacourse ne 'none') {
+ # handle restrictions here
+ if ($env{$metacourse.'.metadata.'.$field_name.'.options'} =~ m/active/){
+ $output.=(''.$lt{$field_name}.': '.
+ &prettyinput($field_name,
+ $Apache::lonpublisher::metadatafields{$field_name},
+ 'new_'.$field_name,'defaultmeta',undef,undef,undef,undef,$metacourse).'
');
+ } elsif ($field_name eq 'courserestricted') {
+ $output.=(
+ &prettyinput($field_name,
+ $Apache::lonpublisher::metadatafields{$field_name},
+ 'new_'.$field_name,'defaultmeta',undef,undef,undef,undef,$metacourse));
+ }
+ } else {
+ if ($field_name ne 'courserestricted') {
+ $output.=(''.$lt{$field_name}.': '.
+ &prettyinput($field_name,
+ $Apache::lonpublisher::metadatafields{$field_name},
+ 'new_'.$field_name,'defaultmeta').'
');
+ } else {
+ $output.=&prettyinput($field_name,
+ $Apache::lonpublisher::metadatafields{$field_name},
+ 'new_'.$field_name,'defaultmeta');
+ }
}
- $r->print(''.$lt{$_}.': '.
- &prettyinput
- ($_,$Apache::lonpublisher::metadatafields{$_},
- 'new_'.$_,'defaultmeta').'
');
}
- if ($ENV{'form.store'}) {
+ if ($env{'form.store'}) {
my $mfh;
- if (! ($mfh=Apache::File->new('>'.$fn))) {
- $r->print(''.
- &mt('Could not write metadata').', '.
- &mt('FAIL').' ');
+ 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},
+ '<>&"').
+ ''.$tag.'>';
+ }
+ if ($fn =~ /\/portfolio\//) {
+ $fn =~ /\/portfolio\/(.*)$/;
+ my $new_fn = '/'.$1;
+ $env{'form.'.$formname}=$file_content."\n";
+ $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 {
- foreach (sort keys %Apache::lonpublisher::metadatafields) {
- next if ($_ =~ /\./);
- 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.'>';
+ 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(''.&mt('Wrote Metadata'));
}
}
- $r->print(' ');
+ my $button_label;
+ if ($fn =~ /\/portfolio\//) {
+ $button_label = 'Store Metadata';
+ } else {
+ $button_label = 'Store Catalog Information';
+ }
+ $r->print($output.' ');
}
$r->print('
');
return;
@@ -882,3 +1211,5 @@ ENDEDIT
1;
__END__
+
+