--- loncom/interface/lonmeta.pm 2006/03/02 20:57:15 1.152 +++ loncom/interface/lonmeta.pm 2007/01/22 20:04:46 1.202 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Metadata display handler # -# $Id: lonmeta.pm,v 1.152 2006/03/02 20:57:15 www Exp $ +# $Id: lonmeta.pm,v 1.202 2007/01/22 20:04:46 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -39,6 +39,7 @@ use Apache::lonpublisher; use Apache::lonlocal; use Apache::lonmysql; use Apache::lonmsg; +use LONCAPA qw(:DEFAULT :match); ############################################################ @@ -61,7 +62,7 @@ use Apache::lonmsg; ############################################################ sub get_dynamic_metadata_from_sql { my ($url) = shift(); - my ($authordom,$author)=($url=~m:^/res/(\w+)/(\w+)/:); + my ($authordom,$author)=($url=~m{^/res/($match_domain)/($match_username)/}); if (! defined($authordom)) { $authordom = shift(); } @@ -71,20 +72,7 @@ sub get_dynamic_metadata_from_sql { if (! defined($authordom) || ! defined($author)) { return (); } - my @Fields = ('url','count','course','course_list', - '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 $query = 'SELECT * FROM metadata WHERE url LIKE "'.$url.'%"'; my $server = &Apache::lonnet::homeserver($author,$authordom); my $reply = &Apache::lonnet::metadata_query($query,undef,undef, ,[$server]); @@ -106,13 +94,10 @@ sub get_dynamic_metadata_from_sql { 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]; + my %hash=&LONCAPA::lonmetadata::metadata_col_to_hash('metadata', + map { &unescape($_) } split(/\,/,$result)); + foreach my $key (keys(%hash)) { + $ReturnHash{$hash{'url'}}->{$key}=$hash{$key}; } } $finished = 1; @@ -126,7 +111,7 @@ sub get_dynamic_metadata_from_sql { sub dynamicmeta { my $url=&Apache::lonnet::declutter(shift); $url=~s/\.meta$//; - my ($adomain,$aauthor)=($url=~/^(\w+)\/(\w+)\//); + my ($adomain,$aauthor)=($url=~/^($match_domain)\/($match_username)\//); my $regexp=$url; $regexp=~s/(\W)/\\$1/g; $regexp='___'.$regexp.'___'; @@ -185,7 +170,7 @@ sub authordisplay { my ($aname,$adom)=@_; return &Apache::loncommon::aboutmewrapper (&Apache::loncommon::plainname($aname,$adom), - $aname,$adom,'preview').' ['.$aname.'@'.$adom.']'; + $aname,$adom,'preview').' ['.$aname.':'.$adom.']'; } # Pretty display @@ -250,13 +235,7 @@ sub fieldnames { 'lowestgradelevel' => 'Lowest Grade Level', 'highestgradelevel' => 'Highest Grade Level'); - if (! defined($file_type) || $file_type ne 'portfolio') { - %fields = - (%fields, - 'courserestricted' => 'Course Restricting Metadata'); - } - - if (! defined($file_type) || $file_type ne 'portfolio') { + if ( !defined($file_type) || ($file_type ne 'portfolio' && $file_type ne 'groups') ) { %fields = (%fields, 'domain' => 'Domain', @@ -296,25 +275,59 @@ sub fieldnames { } sub portfolio_linked_path { - my ($path) = @_; - my $result = &Apache::portfolio::make_anchor('portfolio','/'); + my ($path,$group,$port_path) = @_; + + my $start = 'portfolio'; + if ($group) { + $start = "groups/$group/".$start; + } + my %anchor_fields = ( + 'selectfile' => $start, + 'currentpath' => '/' + ); + my $result = &Apache::portfolio::make_anchor($port_path,\%anchor_fields,$start); my $fullpath = '/'; my (undef,@tree) = split('/',$path); my $filename = pop(@tree); foreach my $dir (@tree) { $fullpath .= $dir.'/'; $result .= '/'; - $result .= &Apache::portfolio::make_anchor($dir,$fullpath); + my %anchor_fields = ( + 'selectfile' => $dir, + 'currentpath' => $fullpath + ); + $result .= &Apache::portfolio::make_anchor($port_path,\%anchor_fields,$dir); } $result .= "/$filename"; return $result; } +sub get_port_path_and_group { + my ($uri)=@_; + + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + + my ($port_path,$group); + if ($uri =~ m{^/editupload/\Q$cdom\E/\Q$cnum\E/groups/}) { + $group = (split('/',$uri))[5]; + $port_path = '/adm/coursegrp_portfolio'; + } else { + $port_path = '/adm/portfolio'; + } + if ($env{'form.group'} ne $group) { + $env{'form.group'} = $group; + } + return ($port_path,$group); +} + sub portfolio_display_uri { my ($uri,$as_links)=@_; + + my ($port_path,$group) = &get_port_path_and_group($uri); + $uri =~ s|.*/(portfolio/.*)$|$1|; my ($res_uri,$meta_uri) = ($uri,$uri); - if ($uri =~ /\.meta$/) { $res_uri =~ s/\.meta//; } else { @@ -322,10 +335,9 @@ sub portfolio_display_uri { } my ($path) = ($res_uri =~ m|^portfolio(.*/)[^/]*$|); - if ($as_links) { - $res_uri = &portfolio_linked_path($res_uri); - $meta_uri = &portfolio_linked_path($meta_uri); + $res_uri = &portfolio_linked_path($res_uri,$group,$port_path); + $meta_uri = &portfolio_linked_path($meta_uri,$group,$port_path); } return ($res_uri,$meta_uri,$path); } @@ -347,12 +359,20 @@ sub pre_select_course { $r->print('

'.&mt('If you would like to associate this resource ([_1]) with a current or previous course, please select one from the list below, otherwise select, \'None\'',''.$res_uri.'').'

'); $output = &select_course(); $r->print($output.'
'); + &mt('Associate Resource With Selected Course').'" />'); + $r->print(''); + $r->print(''); $r->print(''); - $r->print('

'. + my ($port_path,$group) = &get_port_path_and_group($uri); + my $group_input; + if ($group) { + $group_input = ''; + } + $r->print('

'. ''. - ''. + $group_input. + ''. '
'); return; @@ -363,7 +383,40 @@ sub select_course { $Apache::lonpublisher::metadatafields{'courserestricted'}; my $selected = ($current_restriction eq 'none' ? 'selected="selected"' : ''); - + if ($current_restriction =~ /^course\.($match_domain\_$match_courseid)$/) { + my $assoc_crs = $1; + my $added_metadata_fields = &Apache::lonparmset::get_added_meta_fieldnames($assoc_crs); + if (ref($added_metadata_fields) eq 'HASH') { + if (keys(%{$added_metadata_fields}) > 0) { + my $transfernotes; + foreach my $field_name (keys(%{$added_metadata_fields})) { + my $value = $Apache::lonpublisher::metadatafields{$field_name}; + if ($value) { + $transfernotes .= + &Apache::loncommon::start_data_table_row(). + ''. + $field_name.''.$value.''. + &Apache::loncommon::end_data_table_row(); + } + } + if ($transfernotes ne '') { + my %courseinfo = &Apache::lonnet::coursedescription($assoc_crs,{'one_time' => 1}); + my $assoc_crs_description = $courseinfo{'description'}; + $output .= &mt('This resource is currently associated with a course ([_1]) which includes added metadata fields specific to the course.',$assoc_crs_description).'
'."\n". + &mt('You can choose to transfer data from the added fields to the "Notes" field if you are planning to change the course association.').'

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + 'Copy to notes?'."\n". + 'Field name'."\n". + 'Values'."\n". + &Apache::loncommon::end_data_table_header_row(). + $transfernotes. + &Apache::loncommon::end_data_table().'
'; + } + } + } + } $output .= ''); + &mt('Store Catalog Information').'" />'); - if ($file_type eq 'portfolio') { - $r->print(' -

'. - ''. - ''); + if ($file_type eq 'portfolio' || $file_type eq 'groups') { + my ($port_path,$group) = &get_port_path_and_group($uri); + if ($group ne '') { + $r->print(''); + } + $r->print(''); + $r->print('


'); + if ($group ne '') { + $r->print(''); + } + $r->print(''. + ''); } } @@ -1277,7 +1404,146 @@ ENDEDIT return; } +sub store_metadata { + my ($fn,$uri,$caller) = @_; + my $mfh; + my $formname='store'; + my ($file_content,$output,$outcome); + if (&Apache::loncommon::get_env_multiple('form.new_keywords')) { + $Apache::lonpublisher::metadatafields{'keywords'} = + join (',', &Apache::loncommon::get_env_multiple('form.new_keywords')); + } + foreach my $field (sort(keys(%Apache::lonpublisher::metadatafields))) { + next if ($field =~ /\./); + my $unikey=$field; + $unikey=~/^([A-Za-z_]+)/; + my $tag=$1; + $tag=~tr/A-Z/a-z/; + $file_content.= "\n\<$tag"; + foreach my $key (split(/\,/,$Apache::lonpublisher::metadatakeys{$unikey})) { + my $value = $Apache::lonpublisher::metadatafields{$unikey.'.'.$key}; + $value=~s/\"/\'\'/g; + $file_content.=' '.$key.'="'.$value.'"' ; + } + $file_content.= '>'. + &HTML::Entities::encode + ($Apache::lonpublisher::metadatafields{$unikey},'<>&"'). + ''; + } + if ($fn =~ m|^$Apache::lonnet::perlvar{'lonDocRoot'}/userfiles|) { + my ($path, $new_fn); + if ($fn =~ m|$match_name/groups/\w+/portfolio/|) { + ($path, $new_fn) = ($fn =~ m|/(groups/\w+/portfolio.*)/([^/]*)$|); + } else { + ($path, $new_fn) = ($fn =~ m|/(portfolio.*)/([^/]*)$|); + } + ($outcome,my $result) = + &store_portfolio_metadata($formname,$file_content, + $path,$new_fn,$uri,$caller); + $output .= $result; + } else { + if (! ($mfh=Apache::File->new('>'.$fn))) { + $output .= '

'; + if ($caller eq 'transfer') { + $output .= &mt('Could not transfer data in added fields to notes'); + } else { + $output .= &mt('Could not write metadata'); + } + $output .= ', '.&mt('FAIL').'

'; + $outcome = 'fail'; + } else { + print $mfh ($file_content); + close($mfh); + &update_metadata_table($uri); + $output .= '

'; + if ($caller eq 'transfer') { + $output .= &mt('Transferred data in added fields to notes'); + } else { + $output .= &mt('Wrote Metadata'); + } + $output .= ' '.&Apache::lonlocal::locallocaltime(time). + '

'; + $outcome = 'ok'; + } + } + return ($outcome,$output); +} + +sub store_transferred_addedfields { + my ($fn,$uri,$transfers) = @_; + foreach my $item (@{$transfers}) { + $Apache::lonpublisher::metadatafields{'notes'} .= + ' '.$item.' = '.$Apache::lonpublisher::metadatafields{$item}; + } + my ($outcome,$output) = &store_metadata($fn,$uri,'transfer'); + if ($outcome eq 'ok') { + foreach my $item (@{$transfers}) { + delete($Apache::lonpublisher::metadatafields{$item}); + } + } +} + +sub store_portfolio_metadata { + my ($formname,$content,$path,$new_fn,$uri,$caller) = @_; + my ($outcome,$output); + $env{'form.'.$formname}=$content."\n"; + $env{'form.'.$formname.'.filename'}=$new_fn; + my $result =&Apache::lonnet::userfileupload($formname,'',$path); + if ($result =~ /(error|notfound)/) { + $output = '

'; + if ($caller eq 'transfer') { + $output .= + &mt('Could not transfer data in added fields to notes'); + } else { + $output .= &mt('Could not write metadata'); + } + $output .= ', '.&mt('FAIL').'

'; + $outcome = 'fail'; + } else { + &update_metadata_table($uri); + $output = '

'; + if ($caller eq 'transfer') { + $output .= &mt('Transferred data in added fields to notes'); + } else { + $output .= &mt('Wrote Metadata'); + } + $output .= ' '.&Apache::lonlocal::locallocaltime(time). + '

'; + $outcome = 'ok'; + } + return ($outcome,$output); +} + +sub update_metadata_table { + my ($uri) = @_; + my ($type,$udom,$uname,$file_name,$group) = + &Apache::lonnet::parse_portfolio_url($uri); + $file_name =~ s/\.meta$//; + my $current_permissions = + &Apache::lonnet::get_portfile_permissions($udom,$uname); + my %access_controls = + &Apache::lonnet::get_access_controls($current_permissions,$group, + $file_name); + my $access_hash = $access_controls{$file_name}; + my $available = 0; + if (ref($access_hash) eq 'HASH') { + foreach my $key (keys(%{$access_hash})) { + my ($num,$scope,$end,$start) = + ($key =~ /^([^:]+):([a-z]+)_(\d*)_?(\d*)$/); + if ($scope eq 'public' || $scope eq 'guest') { + $available = 1; + last; + } + } + } + if ($available) { + my $result = + &Apache::lonnet::update_portfolio_table($uname,$udom, + $file_name,'portfolio_metadata',$group,'update'); + } +} + + 1; __END__ -