[LON-CAPA-cvs] cvs: doc /loncapafiles loncapafiles.lpml loncom/interface lonnavmaps.pm lonparmset.pm loncom/lonnet/perl lonnet.pm loncom/lti/templates LTIpassback.tool.meta LTIstandard.tool.meta loncom/publisher packages.tab

raeburn raeburn at source.lon-capa.org
Mon Dec 18 18:14:15 EST 2017


raeburn		Mon Dec 18 23:14:15 2017 EDT

  Added files:                 
    /loncom/lti/templates	LTIpassback.tool.meta LTIstandard.tool.meta 

  Modified files:              
    /loncom/interface	lonparmset.pm lonnavmaps.pm 
    /loncom/publisher	packages.tab 
    /loncom/lonnet/perl	lonnet.pm 
    /doc/loncapafiles	loncapafiles.lpml 
  Log:
  - Bug 6754 LON-CAPA as LTI Consumer
    Parameters available for instance of an external tool will differ,
    depending on whether the tool has been set to be "gradable".
  
  
-------------- next part --------------
Index: loncom/interface/lonparmset.pm
diff -u loncom/interface/lonparmset.pm:1.583 loncom/interface/lonparmset.pm:1.584
--- loncom/interface/lonparmset.pm:1.583	Sun Nov 12 23:05:42 2017
+++ loncom/interface/lonparmset.pm	Mon Dec 18 23:13:53 2017
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set parameters for assessments
 #
-# $Id: lonparmset.pm,v 1.583 2017/11/12 23:05:42 raeburn Exp $
+# $Id: lonparmset.pm,v 1.584 2017/12/18 23:13:53 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1856,23 +1856,27 @@
         my $srcf=$resource->src();
         $srcf=~/\.(\w+)$/;
         $$typep{$id}=$1;
+        my $toolsymb;
+        if ($srcf =~ /ext\.tool$/) {
+            $toolsymb = $resource->symb();
+        }
         $$keyp{$id}='';
         $$uris{$id}=$srcf;
 
-        foreach my $key (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys'))) {
+        foreach my $key (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys',$toolsymb))) {
             next if ($key!~/^parameter_/);
 
 # Hidden parameters
-            next if (&Apache::lonnet::metadata($srcf,$key.'.hidden') eq 'parm');
+            next if (&Apache::lonnet::metadata($srcf,$key.'.hidden',$toolsymb) eq 'parm');
 #
 # allparms is a hash of parameter names
 #
-            my $name=&Apache::lonnet::metadata($srcf,$key.'.name');
+            my $name=&Apache::lonnet::metadata($srcf,$key.'.name',$toolsymb);
             if (!exists($$allparms{$name}) || $$allparms{$name} =~ m/^\s*$/ ) {
                 my ($display,$parmdis);
                 $display = &standard_parameter_names($name);
                 if ($display eq '') {
-                    $display= &Apache::lonnet::metadata($srcf,$key.'.display');
+                    $display= &Apache::lonnet::metadata($srcf,$key.'.display',$toolsymb);
                     $parmdis = $display;
                     $parmdis =~ s/\s*\[Part.*$//g;
                 } else {
@@ -1881,14 +1885,14 @@
                 $$allparms{$name}=$parmdis;
                 if (ref($defkeytype)) {
                     $$defkeytype{$name}=
-                    &Apache::lonnet::metadata($srcf,$key.'.type');
+                    &Apache::lonnet::metadata($srcf,$key.'.type',$toolsymb);
                 }
             }
 
 #
 # allparts is a hash of all parts
 #
-            my $part= &Apache::lonnet::metadata($srcf,$key.'.part');
+            my $part= &Apache::lonnet::metadata($srcf,$key.'.part',$toolsymb);
             $$allparts{$part} = &mt('Part: [_1]',$part);
 #
 # Remember all keys going with this resource
@@ -2112,7 +2116,7 @@
         'lenient' => 'grading',
         'retrypartial' => 'tries',
         'discussvote'  => 'misc',
-        'examcode' => 'high_level_randomization', 
+        'examcode' => 'high_level_randomization',
     );
 }
 
@@ -3150,6 +3154,7 @@
                      .'</p>';
         }
     }
+
 #----------------------------------------------- if all selected, fill in array
     if ($pscat[0] eq "all") {
         @pscat = (keys(%allparms));
@@ -3404,19 +3409,23 @@
                     my %type=   ();
                     my %default=();
                     my $uri=&Apache::lonnet::declutter($uris{$rid});
+                    my $toolsymb;
+                    if ($uri =~ /ext\.tool$/) {
+                        $toolsymb = $symbp{$rid};
+                    }
 
                     my $filter=$env{'form.filter'};
                     foreach my $tempkeyp (&keysplit($keyp{$rid})) {
                         if (grep $_ eq $tempkeyp, @catmarker) {
-                            my $parmname=&Apache::lonnet::metadata($uri,$tempkeyp.'.name');
+                            my $parmname=&Apache::lonnet::metadata($uri,$tempkeyp.'.name',$toolsymb);
     # We may only want certain parameters listed
                             if ($filter) {
                                 unless ($filter=~/\Q$parmname\E/) { next; }
                             }
                             $name{$tempkeyp}=$parmname;
-                            $part{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.part');
+                            $part{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.part',$toolsymb);
 
-                            my $parmdis=&Apache::lonnet::metadata($uri,$tempkeyp.'.display');
+                            my $parmdis=&Apache::lonnet::metadata($uri,$tempkeyp.'.display',$toolsymb);
                             if ($allparms{$name{$tempkeyp}} ne '') {
                                 my $identifier;
                                 if ($parmdis =~ /(\s*\[Part.*)$/) {
@@ -3428,9 +3437,9 @@
                             }
                             unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                             $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
-                            $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp);
-                            $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.type');
-                            $thistitle=&Apache::lonnet::metadata($uri,$tempkeyp.'.title');
+                            $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp,$toolsymb);
+                            $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.type',$toolsymb);
+                            $thistitle=&Apache::lonnet::metadata($uri,$tempkeyp.'.title',$toolsymb);
                         }
                     }
                     my $totalparms=scalar(keys(%name));
@@ -3521,6 +3530,10 @@
 
                     if ($map eq $mapid) {
                         my $uri=&Apache::lonnet::declutter($uris{$rid});
+                        my $toolsymb;
+                        if ($uri =~ /ext\.tool$/) {
+                            $toolsymb = $symbp{$rid};
+                        }
 
 #                    $r->print("Keys: $keyp{$rid} <br />\n");
 
@@ -3537,8 +3550,8 @@
 
                             if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
                                 $part{$tempkeyp}="0";
-                                $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
-                                my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
+                                $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name',$toolsymb);
+                                my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display',$toolsymb);
                                 if ($allparms{$name{$tempkeyp}} ne '') {
                                     my $identifier;
                                     if ($parmdis =~ /(\s*\[Part.*)$/) {
@@ -3551,8 +3564,8 @@
                                 unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                                 $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
                                 $display{$tempkeyp} =~ s/_\w+_/_0_/;
-                                $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
-                                $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
+                                $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp,$toolsymb);
+                                $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type',$toolsymb);
                               }
                         } # end loop through keys
                     }
@@ -3637,6 +3650,10 @@
                 my $rid = $id;
 
                 my $uri=&Apache::lonnet::declutter($uris{$rid});
+                my $toolsymb;
+                if ($uri =~ /ext\.tool$/) {
+                    $toolsymb = $symbp{$rid};
+                }
 
 #--------------------------------------------------------------------
 # @catmarker contains list of all possible parameters including part #s
@@ -3650,8 +3667,8 @@
                     $tempkeyp =~ s/_\w+_/_0_/;
                     if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
                         $part{$tempkeyp}="0";
-                        $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
-                        my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
+                        $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name',$toolsymb);
+                        my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display',$toolsymb);
                         if ($allparms{$name{$tempkeyp}} ne '') {
                             my $identifier;
                             if ($parmdis =~ /(\s*\[Part.*)$/) {
@@ -3664,8 +3681,8 @@
                         unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                         $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
                         $display{$tempkeyp} =~ s/_\w+_/_0_/;
-                        $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
-                        $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
+                        $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp,$toolsymb);
+                        $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type',$toolsymb);
                     }
                 } # end loop through keys
             } # end loop through ids
@@ -6596,8 +6613,12 @@
                     $parmitem = &mt($parmitem);
                     $output .= &mt('Type: [_1]',$parmitem);
                 } else {
+                    my $toolsymb;
+                    if ($middle =~ /ext\.tool$/) {
+                        $toolsymb = $middle;
+                    }
                     my ($level, at all)=&parmval_by_symb($what,$middle,
-                        &Apache::lonnet::metadata($middle,$what),
+                        &Apache::lonnet::metadata($middle,$what,$toolsymb),
                         $uname,$udom,$issection,$issection,$courseopt);
                     my $showvalue = $value;
                     if ($istype{$parmname} eq '') {
Index: loncom/interface/lonnavmaps.pm
diff -u loncom/interface/lonnavmaps.pm:1.536 loncom/interface/lonnavmaps.pm:1.537
--- loncom/interface/lonnavmaps.pm:1.536	Wed Sep 13 23:35:07 2017
+++ loncom/interface/lonnavmaps.pm	Mon Dec 18 23:13:53 2017
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Navigate Maps Handler
 #
-# $Id: lonnavmaps.pm,v 1.536 2017/09/13 23:35:07 raeburn Exp $
+# $Id: lonnavmaps.pm,v 1.537 2017/12/18 23:13:53 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1146,7 +1146,7 @@
     my $linkclose = "</a>";
 	
 	$result .= '<td class="LC_middle">';
-    if ($resource->is_problem() &&
+    if ($resource->is_gradable() &&
         !$firstDisplayed) {
         my $icon = $statusIconMap{$resource->simpleStatus($part)};
         my $alt = $iconAltTags{$icon};
@@ -1171,7 +1171,7 @@
                 
     my $color;
     my $info = '';
-    if ($resource->is_problem() || $resource->is_practice()) {
+    if ($resource->is_gradable() || $resource->is_practice()) {
         $color = $colormap{$resource->status};
 
         if (dueInLessThan24Hours($resource, $part)) {
@@ -1185,9 +1185,9 @@
             }
          }
     }
-    
-    if ($resource->kind() eq "res" &&
-        $resource->is_raw_problem() &&
+
+    if (($resource->kind() eq "res") &&
+        ($resource->is_raw_problem() || $resource->is_gradable()) &&
         !$firstDisplayed) {
         if ($color) {$result .= '<span style="color:'.$color.'"'.$info.'><b>'; }
         $result .= getDescription($resource, $part);
@@ -1234,7 +1234,7 @@
 
 sub render_parts_summary_status {
     my ($resource, $part, $params) = @_;
-    if (!$resource->is_problem() && !$resource->contains_problem) { return '<td></td>'; }
+    if (!$resource->is_gradable() && !$resource->contains_problem) { return '<td></td>'; }
     if ($params->{showParts}) { 
 	return '<td></td>';
     }
@@ -2696,6 +2696,10 @@
 
     my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb);
     $mapname = &Apache::lonnet::deversion($mapname);
+    my $toolsymb = '';
+    if ($fn =~ /ext\.tool$/) {
+        $toolsymb = $symb;
+    }
     my ($recursed, at recurseup); 
     
 # ----------------------------------------------------- Cascading lookup scheme
@@ -2816,9 +2820,9 @@
 
     my $meta_rwhat=$rwhat;
     $meta_rwhat=~s/\./_/g;
-    my $default=&Apache::lonnet::metadata($fn,$meta_rwhat);
+    my $default=&Apache::lonnet::metadata($fn,$meta_rwhat,$toolsymb);
     if (defined($default)) { return [$default,'resource']}
-    $default=&Apache::lonnet::metadata($fn,'parameter_'.$meta_rwhat);
+    $default=&Apache::lonnet::metadata($fn,'parameter_'.$meta_rwhat,$toolsymb);
     if (defined($default)) { return [$default,'resource']}
 # --------------------------------------------------- fifth, check more course
     if (defined($courseopt)) {
@@ -2860,7 +2864,7 @@
        if (defined($partgeneral[0])) { return \@partgeneral; }
     }
     if ($recurse) { return []; }
-    my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$rwhat);
+    my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$rwhat,$toolsymb);
     if (defined($pack_def)) { return [$pack_def,'resource']; }
     return [''];
 }
@@ -4475,6 +4479,19 @@
     }
     return 0;
 }
+sub is_tool {
+    my $self=shift;
+    my $src = $self->src();
+    return ($src =~ /ext\.tool$/);
+}
+sub is_gradable {
+    my $self=shift;
+    my $src = $self->src();
+    if (($src =~ /$LONCAPA::assess_re/) ||
+        (($self->is_tool()) && ($self->parmval('gradable',0) =~ /^yes$/i))) {
+        return !($self->is_practice());
+    }
+}
 #
 #  The has below is the set of status that are considered 'incomplete'
 #
@@ -5136,6 +5153,8 @@
     my $self = shift;
 
     if ($self->ext) { return []; }
+    if (($self->is_tool()) &&
+        ($self->is_gradable())) { return ['0']; }
 
     $self->extractParts();
     return $self->{PARTS};
@@ -5510,6 +5529,14 @@
 
 Attempted, and credit received for attempt (survey and anonymous survey only).
 
+=item * B<INCORRECT_BY_PASSBACK>:
+
+Attempted, but wrong for LTI Tool Provider by passback of grade
+
+=item * B<CORRECT_BY_PASSBACK>:
+
+Correct for LTI Tool Provider by passback of grade
+
 =back
 
 =cut
@@ -5522,6 +5549,8 @@
 sub EXCUSED               { return 15; }
 sub ATTEMPTED             { return 16; }
 sub CREDIT_ATTEMPTED      { return 17; }
+sub INCORRECT_BY_PASSBACK { return 18; }
+sub CORRECT_BY_PASSBACK   { return 19; }
 
 sub getCompletionStatus {
     my $self = shift;
@@ -5536,8 +5565,12 @@
     if ($status eq 'correct_by_override') {
 	return $self->CORRECT_BY_OVERRIDE;
     }
+    if ($status eq 'correct_by_passback') {
+        return $self->CORRECT_BY_PASSBACK;
+    }
     if ($status eq 'incorrect_attempted') {return $self->INCORRECT; }
     if ($status eq 'incorrect_by_override') {return $self->INCORRECT_BY_OVERRIDE; }
+    if ($status eq 'incorrect_by_passback') {return $self->INCORRECT_BY_PASSBACK; }
     if ($status eq 'excused') {return $self->EXCUSED; }
     if ($status eq 'ungraded_attempted') {return $self->ATTEMPTED; }
     if ($status eq 'credit_attempted') {
@@ -5691,7 +5724,8 @@
 
     # There are a few whole rows we can dispose of:
     if ($completionStatus == CORRECT ||
-        $completionStatus == CORRECT_BY_OVERRIDE ) {
+        $completionStatus == CORRECT_BY_OVERRIDE ||
+        $completionStatus == CORRECT_BY_PASSBACK ) {
 	if ( $suppressFeedback ) { return ANSWER_SUBMITTED }
 	my $awarded=$self->awarded($part);
 	if ($awarded < 1 && $awarded > 0) {
@@ -5704,7 +5738,8 @@
 
     # If it's WRONG... and not open
     if ( ($completionStatus == INCORRECT || 
-	  $completionStatus == INCORRECT_BY_OVERRIDE)
+	  $completionStatus == INCORRECT_BY_OVERRIDE ||
+	  $completionStatus == INCORRECT_BY_PASSBACK)
 	 && (!$self->opendate($part) ||  $self->opendate($part) > time()) ) {
 	return INCORRECT;
     }
@@ -5746,7 +5781,8 @@
     }
 
     # If it's WRONG...
-    if ($completionStatus == INCORRECT || $completionStatus == INCORRECT_BY_OVERRIDE) {
+    if ($completionStatus == INCORRECT || $completionStatus == INCORRECT_BY_OVERRIDE ||
+        $completionStatus == INCORRECT_BY_PASSBACK) {
         # and there are TRIES LEFT:
         if ($self->tries($part) < $self->maxtries($part) || !$self->maxtries($part)) {
             return $suppressFeedback ? ANSWER_SUBMITTED : TRIES_LEFT;
Index: loncom/publisher/packages.tab
diff -u loncom/publisher/packages.tab:1.77 loncom/publisher/packages.tab:1.78
--- loncom/publisher/packages.tab:1.77	Mon May  8 14:20:38 2017
+++ loncom/publisher/packages.tab	Mon Dec 18 23:13:58 2017
@@ -171,7 +171,72 @@
 extension_html&cssfile&display:CSS file to link
 extension_html&cssfile&type:string
 
-import_defaults&extension_tool:1
+standardLTI&contentopen&display:Content Opening Date
+standardLTI&contentopen&type:date_start
+standardLTI&contentclose&display:Content Close Date
+standardLTI&contentclose&type:date_end
+standardLTI&hiddenresource&display:Resource hidden from students
+standardLTI&hiddenresource&type:string_yesno
+standardLTI&encrypturl&type:string_yesno
+standardLTI&encrypturl&display:Do not show plain URL
+standardLTI&useslots&display:Use slot based access controls
+standardLTI&useslots&type:string_useslots
+standardLTI&useslots&default:no
+standardLTI&available&display:Slots of availability
+standardLTI&available&type:string
+standardLTI&availablestudent&display:Slots of availability selected by student
+standardLTI&availablestudent&type:string
+standardLTIacc&display:Client IP/Name Access Control
+standardLTI&acc&type:string_ip
+standardLTI&cssfile&display:CSS file to link
+standardLTI&cssfile&type:string
+standardLTI&buttonshide&display:Hide buttons from students
+standardLTI&buttonshide&type:string_yesno
+standardLTI&buttonshide&default:no
+
+passbackLTI&opendate&display:Problem Opening Date
+passbackLTI&opendate&type:date_start
+passbackLTI&duedate&display:Problem Due Date
+passbackLTI&duedate&type:date_end
+passbackLTI&answerdate&display:Problem Answer Date
+passbackLTI&answerdate&type:date_start
+passbackLTI&weight&display:Weight
+passbackLTI&weight&type:float_pos
+passbackLTI&weight&default:1
+passbackLTI&maxtries&display:Maximum Number of Tries
+passbackLTI&maxtries&type:int_pos
+passbackLTI&maxtries&default:99
+passbackLTI&problemstatus&type:string_problemstatus
+passbackLTI&problemstatus&default:yes
+passbackLTI&problemstatus&display:Show Problem Status
+passbackLTI&hiddenresource&display:Resource hidden from students
+passbackLTI&hiddenresource&type:string_yesno
+passbackLTI&encrypturl&type:string_yesno
+passbackLTI&encrypturl&display:Do not show plain URL
+passbackLTI&useslots&display:Use slot based access controls
+passbackLTI&useslots&type:string_useslots
+passbackLTI&useslots&default:no
+passbackLTI&available&display:Slots of availability
+passbackLTI&available&type:string
+passbackLTI&availablestudent&display:Slots of availability selected by student
+passbackLTI&availablestudent&type:string
+passbackLTIacc&display:Client IP/Name Access Control
+passbackLTI&acc&type:string_ip
+passbackLTI&interval&display:Time-Limit
+passbackLTI&interval&type:date_interval
+passbackLTI&discussend&display:Discussion End Time
+passbackLTI&discussend&type:date_end
+passbackLTI&discusshide&display:Hide Closed Discussion
+passbackLTI&discusshide&type:string_yesno
+passbackLTI&discusshide&default:no
+passbackLTI&discussvote&display:Discussion Voting
+passbackLTI&discussvote&type:string_discussvote
+passbackLTI&discussvote&default:no
+passbackLTI&cssfile&display:CSS file to link
+passbackLTI&cssfile&type:string
+passbackLTI&buttonshide&display:Hide buttons from students
+passbackLTI&buttonshide&type:string_yesno
+passbackLTI&buttonshide&default:no
 
 #default parameters for anything that doesn't have any more specific
 #package definitions
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.1361 loncom/lonnet/perl/lonnet.pm:1.1362
--- loncom/lonnet/perl/lonnet.pm:1.1361	Thu Nov 30 15:15:06 2017
+++ loncom/lonnet/perl/lonnet.pm	Mon Dec 18 23:14:03 2017
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1361 2017/11/30 15:15:06 raeburn Exp $
+# $Id: lonnet.pm,v 1.1362 2017/12/18 23:14:03 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -7504,7 +7504,10 @@
 # Free bre to public access
 
     if ($priv eq 'bre') {
-        my $copyright=&metadata($uri,'copyright');
+        my $copyright;
+        unless ($uri =~ /ext\.tool/) {
+            $copyright=&metadata($uri,'copyright');
+        }
 	if (($copyright eq 'public') && (!$env{'request.course.id'})) { 
            return 'F'; 
         }
@@ -11491,9 +11494,13 @@
 	} else {
 	    $filename=$env{'request.filename'};
 	}
-	my $metadata=&metadata($filename,$what);
+        my $toolsymb;
+        if (($filename =~ /ext\.tool$/) && ($what ne '0_gradable')) {
+            $toolsymb = $symbparm;
+        }
+	my $metadata=&metadata($filename,$what,$toolsymb);
 	if (defined($metadata)) { return &get_reply([$metadata,'resource']); }
-	$metadata=&metadata($filename,'parameter_'.$what);
+	$metadata=&metadata($filename,'parameter_'.$what,$toolsymb);
 	if (defined($metadata)) { return &get_reply([$metadata,'resource']); }
 
 # ----------------------------------------------- fifth, look in rest of course
@@ -11519,7 +11526,7 @@
 	    if (defined($partgeneral[0])) { return &get_reply(\@partgeneral); }
 	}
 	if ($recurse) { return undef; }
-	my $pack_def=&packages_tab_default($filename,$varname);
+	my $pack_def=&packages_tab_default($filename,$varname,$toolsymb);
 	if (defined($pack_def)) { return &get_reply([$pack_def,'resource']); }
 # ---------------------------------------------------- Any other user namespace
     } elsif ($realm eq 'environment') {
@@ -11613,11 +11620,11 @@
 }
 
 sub packages_tab_default {
-    my ($uri,$varname)=@_;
+    my ($uri,$varname,$toolsymb)=@_;
     my (undef,$part,$name)=split(/\./,$varname);
 
     my (@extension, at specifics,$do_default);
-    foreach my $package (split(/,/,&metadata($uri,'packages'))) {
+    foreach my $package (split(/,/,&metadata($uri,'packages',$toolsymb))) {
 	my ($pack_type,$pack_part)=split(/_/,$package,2);
 	if ($pack_type eq 'default') {
 	    $do_default=1;
@@ -11685,7 +11692,7 @@
 my %metaentry;
 my %importedpartids;
 sub metadata {
-    my ($uri,$what,$liburi,$prefix,$depthcount)=@_;
+    my ($uri,$what,$toolsymb,$liburi,$prefix,$depthcount)=@_;
     $uri=&declutter($uri);
     # if it is a non metadata possible uri return quickly
     if (($uri eq '') || 
@@ -11709,6 +11716,57 @@
 	my ($result,$cached)=&is_cached_new('meta',$uri);
 	if (defined($cached)) { return $result->{':'.$what}; }
     }
+
+#
+# If the uri is for an external tool the file from
+# which metadata should be retrieved depends on whether
+# the tool had been configured to be gradable (set in the Course
+# Editor or Resource Editor).
+#
+# If a valid symb has been included as the third arg in the call
+# to &metadata() that can be used to retrieve the value of
+# parameter_0_gradable set for the resource, and included in the
+# uploaded map containing the tool. The value is retrieved via
+# &EXT(), if a valid symb is available.  Otherwise the value of
+# gradable in the exttool_$marker.db file for the tool instance
+# is retrived via &get().
+#
+# In order to avoid an infinite loop, &metadata() will return
+# before a call to &EXT(), if the uri is for an external tool
+# and the $what for which metadata is being requested is
+# parameter_0_gradable or 0_gradable.
+#
+
+    if ($uri =~ /ext\.tool$/) {
+        if (($what eq 'parameter_0_gradable') || ($what eq '0_gradable')) {
+            return;
+        } else {
+            my ($checked,$use_passback);
+            if ($toolsymb ne '') {
+                (undef,undef,my $tooluri) = &decode_symb($toolsymb);
+                if ($tooluri eq $uri) {
+                    $checked = 1;
+                    if (&EXT('resource.0.gradable',$toolsymb) =~ /^yes$/i) {
+                        $use_passback = 1;
+                    }
+                }
+            }
+            unless ($checked) {
+                my ($ignore,$cdom,$cnum,$marker) = split(m{/},$uri);
+                $marker=~s/\D//g;
+                if (!$marker) {
+                    my %toolsettings=&get('exttool_'.$marker,['gradable'],$cdom,$cnum);
+                    $use_passback = $toolsettings{'gradable'};
+                }
+            }
+            if ($use_passback) {
+                $filename = '/home/httpd/html/res/lib/templates/LTIpassback.tool';
+            } else {
+                $filename = '/home/httpd/html/res/lib/templates/LTIstandard.tool';
+            }
+        }
+    }
+
     {
 # Imported parts would go here
         my %importedids=();
@@ -11848,7 +11906,7 @@
 
 			if ($depthcount<20) {
 			    my $metadata = 
-				&metadata($uri,'keys', $location,$unikey,
+				&metadata($uri,'keys',$toolsymb,$location,$unikey,
 					  $depthcount+1);
 			    foreach my $meta (split(',',$metadata)) {
 				$metaentry{':'.$meta}=$metaentry{':'.$meta};
@@ -11923,7 +11981,7 @@
 		$dir=~s|[^/]*$||;
 		$location=&filelocation($dir,$location);
 		my $rights_metadata =
-		    &metadata($uri,'keys',$location,'_rights',
+		    &metadata($uri,'keys',$toolsymb,$location,'_rights',
 			      $depthcount+1);
 		foreach my $rights (split(',',$rights_metadata)) {
 		    #$metaentry{':'.$rights}=$metacache{$uri}->{':'.$rights};
@@ -14670,10 +14728,14 @@
 
 =item *
 
-metadata($uri,$what,$liburi,$prefix,$depthcount) : request a
+metadata($uri,$what,$toolsymb,$liburi,$prefix,$depthcount) : request a
 resource's metadata, $what should be either a specific key, or either
 'keys' (to get a list of possible keys) or 'packages' to get a list of
-packages that this resource currently uses, the last 3 arguments are only used internally for recursive metadata.
+packages that this resource currently uses, the last 3 arguments are 
+only used internally for recursive metadata.
+
+the toolsymb is only used where the uri is for an external tool (for which
+the uri as well as the symb are guaranteed to be unique).
 
 this function automatically caches all requests
 
Index: doc/loncapafiles/loncapafiles.lpml
diff -u doc/loncapafiles/loncapafiles.lpml:1.961 doc/loncapafiles/loncapafiles.lpml:1.962
--- doc/loncapafiles/loncapafiles.lpml:1.961	Sat Dec  9 01:37:15 2017
+++ doc/loncapafiles/loncapafiles.lpml	Mon Dec 18 23:14:13 2017
@@ -2,7 +2,7 @@
  "http://lpml.sourceforge.net/DTD/lpml.dtd">
 <!-- loncapafiles.lpml -->
 
-<!-- $Id: loncapafiles.lpml,v 1.961 2017/12/09 01:37:15 raeburn Exp $ -->
+<!-- $Id: loncapafiles.lpml,v 1.962 2017/12/18 23:14:13 raeburn Exp $ -->
 
 <!--
 
@@ -2573,6 +2573,24 @@
 <status>works/unverified</status>
 </file>
 <file>
+<source>loncom/lti/templates/LTIstandard.tool.meta</source>
+<target dist='default'>home/httpd/html/res/lib/templates/LTIstandard.tool.meta</target>
+<categoryname>interface file</categoryname>
+<description>
+Meta file which specifies package source for external tool (LTI) without passback
+of grades 
+</description>
+</file>
+<file>
+<source>loncom/lti/templates/LTIpassback.tool.meta</source>
+<target dist='default'>home/httpd/html/res/lib/templates/LTIpassback.tool.meta</target>
+<categoryname>interface file</categoryname>
+<description>
+Meta file which specifies package source for external tool (LTI) which supports passback
+of grades, and storable parameters.
+</description>
+</file>
+<file>
   <source>loncom/interface/lonpickcode.pm</source>
   <target dist='default'>home/httpd/lib/perl/Apache/lonpickcode.pm</target>
   <categoryname>handler</categoryname>

Index: loncom/lti/templates/LTIpassback.tool.meta
+++ loncom/lti/templates/LTIpassback.tool.meta

<abstract>Launch Tool Provider (LON-CAPA as LTI Consumer)</abstract>
<author>LON-CAPA</author>
<copyright>default</copyright>
<creationdate>1513125481</creationdate>
<customdistributionfile></customdistributionfile>
<dependencies></dependencies>
<keywords>LTI</keywords>
<language>notset</language>
<lastrevisiondate>1513125481</lastrevisiondate>
<mime>tool</mime>
<notes></notes>
<owner>templates at lib</owner>
<parameter part="0" package="passbackLTI"></parameter>
<stores part="0" name="awarded" type="float" display="Partial Credit Factor [Part: 0]"></stores>
<stores part="0" name="solved" type="string" display="Problem Status [Part: 0]"></stores>
<stores part="0" name="tries" type="int_zeropos" display="Number of Attempts [Part: 0]"></stores>
<stores part="0" name="comment" type="string" display="Comment [Part: 0]"></stores>
<stores part="0" name="gradeinfo" type="string" display="Grade Info [Part: 0]"</stores>
<subject>Pass-back scores from LTI Tool Provider</subject>
<title>External Tool</title>

Index: loncom/lti/templates/LTIstandard.tool.meta
+++ loncom/lti/templates/LTIstandard.tool.meta

<abstract>Launch Tool Provider (LON-CAPA as LTI Consumer)</abstract>
<author>LON-CAPA</author>
<copyright>default</copyright>
<creationdate>1513125481</creationdate>
<customdistributionfile></customdistributionfile>
<dependencies></dependencies>
<keywords>LTI</keywords>
<language>notset</language>
<lastrevisiondate>1513125481</lastrevisiondate>
<mime>tool</mime>
<notes></notes>
<owner>templates at lib</owner>
<parameter part="0" package="standardLTI"></parameter>
<subject>LTI Tool Provider</subject>
<title>External Tool</title>


More information about the LON-CAPA-cvs mailing list