[LON-CAPA-cvs] cvs: loncom / lond lonsql /auth localstudentphoto.pm /enrollment Enrollment.pm localenroll.pm /html/adm/lonKaputt genericstudent_tn.gif /interface londropadd.pm lonpopulate.pm /lonnet/perl lonnet.pm doc/loncapafiles loncapafiles.lpml

raeburn lon-capa-cvs@mail.lon-capa.org
Tue, 07 Feb 2006 05:08:33 -0000


This is a MIME encoded message

--raeburn1139288913
Content-Type: text/plain

raeburn		Tue Feb  7 00:08:33 2006 EDT

  Added files:                 
    /loncom/html/adm/lonKaputt	genericstudent_tn.gif 

  Modified files:              
    /doc/loncapafiles	loncapafiles.lpml 
    /loncom/enrollment	Enrollment.pm localenroll.pm 
    /loncom/auth	localstudentphoto.pm 
    /loncom	lond lonsql 
    /loncom/lonnet/perl	lonnet.pm 
    /loncom/interface	lonpopulate.pm londropadd.pm 
  Log:
  Add support for student photo import from an institutional repository. Availability of photos of registered students in a course controlled by course environment parameter: 'internal.studentphoto'.  This may be configured to require initial acceptance of conditions of use by course owner.  View classlist in ENRL, and Automated Enrollment Manager now includes option to display thumbnails of student photos.  Nightly enrollment update can import student photos for students added to a course.  Student photos can be updated via the Automated Enrollment Manager.                
  
  
--raeburn1139288913
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20060207000833.txt"

Index: doc/loncapafiles/loncapafiles.lpml
diff -u doc/loncapafiles/loncapafiles.lpml:1.468 doc/loncapafiles/loncapafiles.lpml:1.469
--- doc/loncapafiles/loncapafiles.lpml:1.468	Thu Jan 26 21:16:57 2006
+++ doc/loncapafiles/loncapafiles.lpml	Tue Feb  7 00:08:18 2006
@@ -2,7 +2,7 @@
  "http://lpml.sourceforge.net/DTD/lpml.dtd">
 <!-- loncapafiles.lpml -->
 
-<!-- $Id: loncapafiles.lpml,v 1.468 2006/01/27 02:16:57 www Exp $ -->
+<!-- $Id: loncapafiles.lpml,v 1.469 2006/02/07 05:08:18 raeburn Exp $ -->
 
 <!--
 
@@ -4993,7 +4993,8 @@
 lonlogo_broken_tsp.gif;
 lonlogo_broken.eps;
 lonlogo_broken.jpg;
-lonlogo_broken.mov
+lonlogo_broken.mov;
+genericstudent_tn.gif
 </filenames>
 </fileglob>
 <fileglob>
Index: loncom/enrollment/Enrollment.pm
diff -u loncom/enrollment/Enrollment.pm:1.27 loncom/enrollment/Enrollment.pm:1.28
--- loncom/enrollment/Enrollment.pm:1.27	Wed Jan 11 20:30:44 2006
+++ loncom/enrollment/Enrollment.pm	Tue Feb  7 00:08:21 2006
@@ -1,5 +1,5 @@
 # Automated Enrollment manager
-# $Id: Enrollment.pm,v 1.27 2006/01/12 01:30:44 raeburn Exp $
+# $Id: Enrollment.pm,v 1.28 2006/02/07 05:08:21 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -28,6 +28,7 @@
 use Apache::loncoursedata;
 use Apache::lonnet;
 use Apache::lonmsg;
+use Apache::lonlocal;
 use HTML::Entities;
 use LONCAPA::Configuration;
 use Time::Local;
@@ -36,7 +37,7 @@
 use strict;
 
 sub update_LC {
-    my ($dom,$crs,$adds,$drops,$startdate,$enddate,$authtype,$autharg,$classesref,$groupref,$logmsg,$newusermsg,$context) = @_; 
+    my ($dom,$crs,$adds,$drops,$startdate,$enddate,$authtype,$autharg,$classesref,$groupref,$logmsg,$newusermsg,$context,$phototypes) = @_; 
 # Get institutional code and title of this class
     my %courseinfo = ();
     &get_courseinfo($dom,$crs,\%courseinfo);
@@ -75,6 +76,7 @@
     my $addresult = '';
     my $dropresult = '';
     my $switchresult = '';
+    my $photoresult = '';
     if ($context eq "updatenow") {
         $linefeed = "</li>\n<li>"; 
     } elsif ($context eq "automated") {
@@ -192,6 +194,7 @@
             @{$unameFromINid{$stuID}} = $uname; 
         }
     }
+
 # Explicitly allow access to creation/modification of students if called as an automated process.
     if ($context eq 'automated') {
         $env{'allowed.cst'}='F';
@@ -323,10 +326,46 @@
                     } else {
                         &execute_add($context,'newstudent',$uname,$dom,$auth,$authparam,$first,$middle,$last,$gene,$pid,$usec,$end,$start,$emailenc,$cid,\$addresult,\$enrollcount,$linefeed,$logmsg);
                     }
+                    if ($courseinfo{'showphotos'}) {
+                        my ($result,$resulttype) = 
+                           &Apache::lonnet::auto_checkphotos($uname,$dom,$pid);
+                        if ($resulttype) {
+                            push(@{$$phototypes{$resulttype}},$uname);
+                        }
+                    }
                 }
             }
         }
     }
+    if ($courseinfo{'showphotos'}) {
+        if (keys(%{$phototypes})>0) {
+            my %lt = &photo_response_types();
+            foreach my $type (sort(keys(%{$phototypes}))) {
+                my $numphoto = @{$$phototypes{$type}};
+                if ($numphoto > 0) {
+                    if ($context eq 'updatenow') {
+                        $photoresult .=  '<br /><b>'.
+                                   &mt('For [_1] students, photos ',$numphoto).
+                                                     $lt{$type}.'</b><ul><li>';
+                    } else {
+                        $photoresult .=  "\nFor $numphoto students, photos ".
+                                                               $lt{$type}."\n";
+                    }
+                    foreach my $user (@{$$phototypes{$type}}) { 
+                        $photoresult .= $user.$linefeed;
+                    }
+                    if ($context eq 'updatenow') {
+                        $photoresult = substr($photoresult,0,
+                                                  rindex($photoresult,"<li>"));
+                        $photoresult .= '</ul><br />';
+                    } else {
+                        $photoresult .= "\n";
+                    }
+                }
+            }
+        }
+    }
+
 # Do drops
     if ( ($drops == 1) && (@reg_students > 0) ) {
         foreach my $uname (@localstudents) {
@@ -365,6 +404,9 @@
         if ($context eq "updatenow") {
             $addresult = substr($addresult,0,rindex($addresult,"<li>"));
             $addresult = "The following $enrollcount student(s) was/were added to this LON-CAPA course:<br/><ul><li>".$addresult."</ul><br/><br/>";
+            if ($courseinfo{'showphotos'}) {
+
+            }
         } else {
             $addresult = "The following $enrollcount student(s) was/were added to this LON-CAPA course:\n\n".$addresult."\n\n";
         }
@@ -402,7 +444,7 @@
         }
     }
     my $changecount = $enrollcount + $dropcount + $switchcount;
-    return ($changecount,$addresult.$dropresult.$switchresult);
+    return ($changecount,$addresult.$photoresult.$dropresult.$switchresult);
 }
 
 sub create_newuser {
@@ -787,14 +829,16 @@
     my ($dom,$crs,$courseinfo) = @_;
     my $owner;
     if (defined($dom) && defined($crs)) {
-        my %settings = &Apache::lonnet::get('environment',['internal.coursecode','description'],$dom,$crs);
+        my %settings = &Apache::lonnet::get('environment',['internal.coursecode','internal.showphotos','description'],$dom,$crs);
         if ( defined($settings{'internal.coursecode'}) ) {
             $$courseinfo{'inst_code'} = $settings{'internal.coursecode'};
-
         }
         if ( defined($settings{'description'}) ) {
             $$courseinfo{'description'} = $settings{'description'};
         }
+        if ( defined($settings{'internal.showphotos'}) ) {
+            $$courseinfo{'showphotos'} = $settings{'internal.showphotos'};
+        }
     }
     return;
 }
@@ -811,4 +855,18 @@
 sub CL_startdate { return 9; }
 sub CL_studentID { return 10; }
 
+sub photo_response_types {
+    my %lt = &Apache::lonlocal::texthash (
+                      'same' => 'remained unchanged',
+                      'update' => 'were updated',
+                      'new' => 'were added',
+                      'missing' => 'were missing',
+                      'error' => 'were not imported because an error occurred',
+                      'nouser' => 'were for users without accounts',
+                      'noid' => 'were for users without student IDs',
+    );
+    return %lt;
+}
+
+
 1;
Index: loncom/enrollment/localenroll.pm
diff -u loncom/enrollment/localenroll.pm:1.11 loncom/enrollment/localenroll.pm:1.12
--- loncom/enrollment/localenroll.pm:1.11	Mon Feb  6 23:54:17 2006
+++ loncom/enrollment/localenroll.pm	Tue Feb  7 00:08:21 2006
@@ -1,6 +1,6 @@
 # functions to glue school database system into Lon-CAPA for 
 # automated enrollment
-# $Id: localenroll.pm,v 1.11 2006/02/07 04:54:17 raeburn Exp $
+# $Id: localenroll.pm,v 1.12 2006/02/07 05:08:21 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -335,4 +335,85 @@
     return $outcome;
 }
 
+###############################
+# sub institutional_photos
+#
+# Called when automated enrollment manager is used to update student photos.
+#
+# Incoming data: six arguments
+# (a) $dom (domain)
+# (b) $crs (LONCAPA course number)
+# (c) $affiliates: a reference to a hash with the keys set to the 
+# institutional course IDs for the course.
+# (d) $result: a reference to a hash which will return usernames  
+#     of students (& separated) in following categories (the keys):
+#     new, update, missing, same, deleted, noid, nouser. The list 
+#     includes those students for whom the result of the modification 
+#     process was either addition of a new photo. update of an
+#     existing photo, photo was found to be missing from institution's
+#     data store, photo used is same as before, or photo was 
+#     deleted from storage on LON-CAPA server housing student's
+#     information, no student ID was available. 
+               
+# (e) $action: the type of action needed. (e.g., update, delete);
+# (f) $students: a reference to a hash with the keys set to student 
+# usernames and domains in the form username:domain, and values set
+# to the studentID, if action is required for specific students.  
+#
+# returns 1 parameter: 'ok' if no processing errors.
+# other course or student specific values can be stored as values
+# in the appropriate referenced hashes. 
+###############################
+
+sub institutional_photos {
+    my ($dom,$crs,$affiliates,$result,$action,$students) = @_;
+    my $outcome = 'ok';
+    return $outcome;
+}
+
+###############################
+# sub photo_permission
+#
+# Incoming data: three arguments
+# (a) $dom (domain)
+# (b) $perm_reqd: a reference to a a scalar that is either 'yes'
+# if a course owner must indicate acceptance of conditions of use,
+# 'no' otherwise.
+# (c) $conditions: the text of the conditions of use.
+#    
+# returns 1 parameter: 'ok' if no processing errors.
+# $$perm_reqd is set to 'yes' or 'no'
+# $$agreement is set to conditions of use - plain text string
+#             which will be displayed in a textarea in a web form.
+###############################
+ 
+sub photo_permission {
+   my ($dom,$perm_reqd,$conditions) = @_;
+   $$perm_reqd = 'no';
+   $$conditions = '';
+   my $outcome = 'ok';
+   return $outcome;
+}
+
+
+###############################
+# sub manager_photo_update
+#
+# Incoming data: one argument
+# (a) $dom (domain)
+#
+# returns 2 parameters: update (0 or 1), and comment.
+# Called by automated enrollment manager, to determine 
+# whether "Update Student photos" button will be available,
+# and if so, the message (plain text string) that will be displayed
+# with the button. 
+###############################
+                                                                                        
+sub manager_photo_update {
+    my ($dom) = @_;
+    my $update = 0;
+    my $comment = '';
+    return ($update,$comment);
+}
+
 1;
Index: loncom/auth/localstudentphoto.pm
diff -u loncom/auth/localstudentphoto.pm:1.2 loncom/auth/localstudentphoto.pm:1.3
--- loncom/auth/localstudentphoto.pm:1.2	Tue Nov  2 18:11:56 2004
+++ loncom/auth/localstudentphoto.pm	Tue Feb  7 00:08:24 2006
@@ -1,6 +1,6 @@
 # The LON-CAPA dummy student photo fetch mechnism
 #
-# $Id: localstudentphoto.pm,v 1.2 2004/11/02 23:11:56 albertel Exp $
+# $Id: localstudentphoto.pm,v 1.3 2006/02/07 05:08:24 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -32,10 +32,55 @@
 use LONCAPA::Configuration;
 
 sub fetch {
-    my ($domain,$user)=@_;
+    my ($domain,$user,$pid,$response)=@_;
+    my $temptxt = '';
+    unless (ref($response)) {
+        $response = \$temptxt;
+    }
+    if ($udom eq '' || $uname eq '') {
+        $$response = 'nouser';
+        return '';
+    }
     return &main::propath($domain,$user).
 	'/userfiles/internal/studentphoto.jpg';
 }
 
+sub fetch_thumbnail {
+    my ($udom,$uname) = @_;
+    if ($udom eq '' || $uname eq '') {
+        return '';
+    }
+    my $userdir=&main::propath($udom,$uname);
+    my $filepath = '/userfiles/internal/studentphoto.jpg';
+    my $thumbnail = '/userfiles/internal/studentphoto_tn.gif';
+    my $source =  "$userdir/$filepath";
+    my $dest = "$userdir/$thumbnail";
+    if (-e $dest) {
+        return $dest;
+    } else {
+        if (!-e $source) {
+            my $file = &fetch($udom,$uname);
+        }
+        if (-e $source) {
+            my ($fullsize,$thumbsize)=&localstudentphoto::thumbsettings($udom);
+            if ($fullsize && $thumbsize) {
+                system("convert -size $fullsize $source -thumbnail $thumbsize $dest");
+            }
+            if (-e $dest) {
+                return $dest;
+            }
+        }
+    }
+    return '';
+}   
+
+sub thumbsettings {
+    my ($dom) = @_;
+    my $fullsize = '240x240';
+    my $thumbsize = '40x40';
+    return ($fullsize,$thumbsize);
+}
+
+
 1;
 __END__
Index: loncom/lond
diff -u loncom/lond:1.316 loncom/lond:1.317
--- loncom/lond:1.316	Wed Feb  1 17:08:48 2006
+++ loncom/lond	Tue Feb  7 00:08:27 2006
@@ -2,7 +2,7 @@
 # The LearningOnline Network
 # lond "LON Daemon" Server (port "LOND" 5663)
 #
-# $Id: lond,v 1.316 2006/02/01 22:08:48 albertel Exp $
+# $Id: lond,v 1.317 2006/02/07 05:08:27 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -61,7 +61,7 @@
 my $lastlog='';
 my $lond_max_wait_time = 13;
 
-my $VERSION='$Revision: 1.316 $'; #' stupid emacs
+my $VERSION='$Revision: 1.317 $'; #' stupid emacs
 my $remoteVERSION;
 my $currenthostid="default";
 my $currentdomainid;
@@ -4336,6 +4336,64 @@
 &register_handler("autoinstcodeformat",
 		  \&get_institutional_code_format_handler,0,1,0);
 
+# Get domain specific conditions for import of student photographs to a course
+#
+# Retrieves information from photo_permission subroutine in localenroll.
+# Returns outcome (ok) if no processing errors, and whether course owner is 
+# required to accept conditions of use (yes/no).
+#
+#    
+sub photo_permission_handler {
+    my ($cmd, $tail, $client)   = @_;
+    my $userinput               = "$cmd:$tail";
+    my $cdom = $tail;
+    my ($perm_reqd,$conditions);
+    my $outcome = &localenroll::photo_permission($cdom,\$perm_reqd,
+                                                                 \$conditions);
+    &Reply($client, &escape($outcome.':'.$perm_reqd.':'. $conditions)."\n",
+                                                                   $userinput);
+}
+&register_handler("autophotopermission",\&photo_permission_handler,0,1,0);
+
+#
+# Checks if student photo is available for a user in the domain, in the user's
+# directory (in /userfiles/internal/studentphoto.jpg).
+# Uses localstudentphoto:fetch() to ensure there is an up to date copy of
+# the student's photo.   
+
+sub photo_check_handler {
+    my ($cmd, $tail, $client)   = @_;
+    my $userinput               = "$cmd:$tail";
+    my ($udom,$uname,$pid) = split(/:/,$tail);
+    $udom = &unescape($udom);
+    $uname = &unescape($uname);
+    $pid = &unescape($pid);
+    my $path=&propath($udom,$uname).'/userfiles/internal/';
+    if (!-e $path) {
+        &mkpath($path);
+    }
+    my $response;
+    my $result = &localstudentphoto::fetch($udom,$uname,$pid,\$response);
+    $result .= ':'.$response;
+    &Reply($client, &escape($result)."\n",$userinput);
+}
+&register_handler("autophotocheck",\&photo_check_handler,0,1,0);
+
+#
+# Retrieve information from localenroll about whether to provide a button     
+# for users who have enbled import of student photos to initiate an 
+# update of photo files for registered students. Also include 
+# comment to display alongside button.  
+
+sub photo_choice_handler {
+    my ($cmd, $tail, $client) = @_;
+    my $userinput             = "$cmd:$tail";
+    my $cdom                  = &unescape($tail);
+    my ($update,$comment) = &localenroll::manager_photo_update($cdom);
+    &Reply($client,&escape($update).':'.&escape($comment)."\n",$userinput);
+}
+&register_handler("autophotochoice",\&photo_choice_handler,0,1,0);
+
 #
 # Gets a student's photo to exist (in the correct image type) in the user's 
 # directory.
@@ -4348,24 +4406,33 @@
 #    $client  - The socket open on the client.
 # Returns:
 #    1 - continue processing.
+
 sub student_photo_handler {
     my ($cmd, $tail, $client) = @_;
-    my ($domain,$uname,$type) = split(/:/, $tail);
+    my ($domain,$uname,$ext,$type) = split(/:/, $tail);
 
-    my $path=&propath($domain,$uname).
-	'/userfiles/internal/studentphoto.'.$type;
-    if (-e $path) {
+    my $path=&propath($domain,$uname). '/userfiles/internal/';
+    my $filename = 'studentphoto.'.$ext;
+    if ($type eq 'thumbnail') {
+        $filename = 'studentphoto_tn.'.$ext;
+    }
+    if (-e $path.$filename) {
 	&Reply($client,"ok\n","$cmd:$tail");
 	return 1;
     }
     &mkpath($path);
-    my $file=&localstudentphoto::fetch($domain,$uname);
+    my $file;
+    if ($type eq 'thumbnail') {
+        $file=&localstudentphoto::fetch_thumbnail($domain,$uname);
+    } else {
+        $file=&localstudentphoto::fetch($domain,$uname);
+    }
     if (!$file) {
 	&Failure($client,"unavailable\n","$cmd:$tail");
 	return 1;
     }
-    if (!-e $path) { &convert_photo($file,$path); }
-    if (-e $path) {
+    if (!-e $path.$filename) { &convert_photo($file,$path.$filename); }
+    if (-e $path.$filename) {
 	&Reply($client,"ok\n","$cmd:$tail");
 	return 1;
     }
Index: loncom/lonsql
diff -u loncom/lonsql:1.69 loncom/lonsql:1.70
--- loncom/lonsql:1.69	Thu Nov 24 15:03:49 2005
+++ loncom/lonsql	Tue Feb  7 00:08:27 2006
@@ -3,7 +3,7 @@
 # The LearningOnline Network
 # lonsql - LON TCP-MySQL-Server Daemon for handling database requests.
 #
-# $Id: lonsql,v 1.69 2005/11/24 20:03:49 www Exp $
+# $Id: lonsql,v 1.70 2006/02/07 05:08:27 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -423,7 +423,8 @@
                     $result='no_such_file';
                 }
                 # end of log query
-            } elsif ($query eq 'fetchenrollment') {
+            } elsif (($query eq 'fetchenrollment') || 
+                                           ($query eq 'institutionalphotos')) {
                 # retrieve institutional class lists
                 my $dom = &unescape($arg1);
                 my %affiliates = ();
@@ -435,7 +436,12 @@
                         @{$affiliates{$1}} = split/,/,$2;
                     }
                 }
-                $locresult = &localenroll::fetch_enrollment($dom,\%affiliates,\%replies);
+                if ($query eq 'fetchenrollment') { 
+                    $locresult = &localenroll::fetch_enrollment($dom,\%affiliates,\%replies);
+                } elsif ($query eq 'institutionalphotos') {
+                    my $crs = &unescape($arg2);
+                    $locresult = &localenroll::institutional_photos($dom,$crs,\%affiliates,\%replies,'update');
+                }
                 $result = &escape($locresult.':');
                 if ($locresult) {
                     $result .= &escape(join(':',map{$_.'='.$replies{$_}} keys %replies));
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.705 loncom/lonnet/perl/lonnet.pm:1.706
--- loncom/lonnet/perl/lonnet.pm:1.705	Tue Jan 31 16:57:59 2006
+++ loncom/lonnet/perl/lonnet.pm	Tue Feb  7 00:08:29 2006
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.705 2006/01/31 21:57:59 albertel Exp $
+# $Id: lonnet.pm,v 1.706 2006/02/07 05:08:29 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -947,13 +947,50 @@
 sub studentphoto {
     my ($udom,$unam,$ext) = @_;
     my $home=&Apache::lonnet::homeserver($unam,$udom);
-    my $ret=&Apache::lonnet::reply("studentphoto:$udom:$unam:$ext",$home);
-    my $url="/uploaded/$udom/$unam/internal/studentphoto.".$ext;
-    if ($ret ne 'ok') {
-	return '/adm/lonKaputt/lonlogo_broken.gif';
+    if (defined($env{'request.course.id'})) {
+        if ($env{'course.'.$env{'request.course.id'}.'.internal.showphotos'}) {
+            if ($udom eq $env{'course.'.$env{'request.course.id'}.'.domain'}) {
+                return(&retrievestudentphoto($udom,$unam,$ext)); 
+            } else {
+                my ($result,$perm_reqd)=
+                        &Apache::lonnet::auto_photo_permission($unam,$udom);
+                if ($result eq 'ok') {
+                    if (!($perm_reqd eq 'yes')) {
+                        return(&retrievestudentphoto($udom,$unam,$ext));
+                    }
+                }
+            }
+        }
+    } else {
+        my ($result,$perm_reqd) = 
+                           &Apache::lonnet::auto_photo_permission($unam,$udom);
+        if ($result eq 'ok') {
+            if (!($perm_reqd eq 'yes')) {
+                return(&retrievestudentphoto($udom,$unam,$ext));
+            }
+        }
+    }
+    return '/adm/lonKaputt/lonlogo_broken.gif';
+}
+
+sub retrievestudentphoto {
+    my ($udom,$unam,$ext,$type) = @_;
+    my $home=&Apache::lonnet::homeserver($unam,$udom);
+    my $ret=&Apache::lonnet::reply("studentphoto:$udom:$unam:$ext:$type",$home);
+    if ($ret eq 'ok') {
+        my $url="/uploaded/$udom/$unam/internal/studentphoto.$ext";
+        if ($type eq 'thumbnail') {
+            $url="/uploaded/$udom/$unam/internal/studentphoto_tn.$ext"; 
+        }
+        my $tokenurl=&Apache::lonnet::tokenwrapper($url);
+        return $tokenurl;
+    } else {
+        if ($type eq 'thumbnail') {
+            return '/adm/lonKaputt/genericstudent_tn.gif';
+        } else { 
+            return '/adm/lonKaputt/lonlogo_broken.gif';
+        }
     }
-    my $tokenurl=&Apache::lonnet::tokenwrapper($url);
-    return $tokenurl;
 }
 
 # -------------------------------------------------------------------- New chat
@@ -3695,6 +3732,71 @@
     return ($authparam,$create_passwd,$authchk);
 }
 
+sub auto_photo_permission {
+    my ($cnum,$cdom,$students) = @_;
+    my $homeserver = &homeserver($cnum,$cdom);
+    my ($outcome,$perm_reqd,$conditions) = split(/:/,&unescape(
+                          &reply('autophotopermission:'.$cdom,$homeserver)),3);
+    return ($outcome,$perm_reqd,$conditions);
+}
+
+sub auto_checkphotos {
+    my ($uname,$udom,$pid) = @_;
+    my $homeserver = &homeserver($uname,$udom);
+    my ($result,$resulttype);
+    my $outcome = &unescape(&reply('autophotocheck:'.&escape($udom).':'.
+                               &escape($uname).':'.&escape($pid),$homeserver));
+    if ($outcome) {
+        ($result,$resulttype) = split(/:/,$outcome);
+    } 
+    return ($result,$resulttype);
+}
+
+sub auto_photochoice {
+    my ($cnum,$cdom) = @_;
+    my $homeserver = &homeserver($cnum,$cdom);
+    my ($update,$comment) = split(/:/,&unescape(&reply('autophotochoice:'.
+                                                &escape($cdom),$homeserver)));
+    return ($update,$comment);
+}
+
+sub auto_photoupdate {
+    my ($affiliatesref,$dom,$cnum,$photo) = @_;
+    my $homeserver = &homeserver($cnum,$dom);
+    my $host=$hostname{$homeserver};
+    my $cmd = '';
+    my $maxtries = 1;
+    foreach (keys %{$affiliatesref}) {
+        $cmd .= $_.'='.join(",",@{$$affiliatesref{$_}}).'%%';
+    }
+    $cmd =~ s/%%$//;
+    $cmd = &escape($cmd);
+    my $query = 'institutionalphotos';
+    my $queryid=&reply("querysend:".$query.':'.$dom.':'.$cnum.':'.$cmd,$homeserver);
+    unless ($queryid=~/^\Q$host\E\_/) {
+        &logthis('institutionalphotos: invalid queryid: '.$queryid.' for host: '.$host.' and homeserver: '.$homeserver.' and course: '.$cnum);
+        return 'error: '.$queryid;
+    }
+    my $reply = &get_query_reply($queryid);
+    my $tries = 1;
+    while (($reply=~/^timeout/) && ($tries < $maxtries)) {
+        $reply = &get_query_reply($queryid);
+        $tries ++;
+    }
+    if ( ($reply =~/^timeout/) || ($reply =~/^error/) ) {
+        &logthis('institutionalphotos error: '.$reply.' for '.$dom.' '.$env{'user.name'}.' for '.$queryid.' course: '.$cnum.' maxtries: '.$maxtries.' tries: '.$tries);
+    } else {
+        my @responses = split(/:/,$reply);
+        my $outcome = shift(@responses); 
+        foreach my $item (@responses) {
+            my ($key,$value) = split(/=/,$item);
+            $$photo{$key} = $value;
+        }
+        return $outcome;
+    }
+    return 'error';
+}
+
 sub auto_instcode_format {
     my ($caller,$codedom,$instcodes,$codes,$codetitles,$cat_titles,$cat_order) = @_;
     my $courses = '';
Index: loncom/interface/lonpopulate.pm
diff -u loncom/interface/lonpopulate.pm:1.33 loncom/interface/lonpopulate.pm:1.34
--- loncom/interface/lonpopulate.pm:1.33	Mon Nov  7 10:43:31 2005
+++ loncom/interface/lonpopulate.pm	Tue Feb  7 00:08:32 2006
@@ -1,5 +1,5 @@
 # automated enrollment configuration handler
-# $Id: lonpopulate.pm,v 1.33 2005/11/07 15:43:31 raeburn Exp $
+# $Id: lonpopulate.pm,v 1.34 2006/02/07 05:08:32 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -312,7 +312,7 @@
               <td>Use <i>"Section settings"</i> to make changes to the choice of sections included for enrollment in your LON-CAPA course.</td>
             </tr>
               <td>&nbsp;</td>
-              <td>Use <i>"Student photos"</i> to enable or disable automatic upload of student photos to your course.</td>
+              <td>Use <i>"Student photos settings"</i> to enable or disable automatic import of photos for registered students in your course.</td>
             </tr>
             <tr>
               <td>&nbsp;</td>
@@ -320,6 +320,10 @@
             </tr>
             <tr>
               <td>&nbsp;</td>
+              <td>Use <i>"Update student photos"</i> to import your institution's <b>most current</b> digital photos for registered students in your course.</td>
+            </tr>
+            <tr>
+              <td>&nbsp;</td>
               <td>Use <i>"View students and change type"</i> to display the current course roster, and (optionally) change enrollment type for selected students from 'auto' to 'manual' and vice versa.</td>
             </tr>
             <tr>
@@ -883,29 +887,87 @@
                         <input type=\"radio\" name=\"showphotos\" value=\"0\" checked=\"true\" />&nbsp;No
           ");
       }
-      $r->print("
+      $r->print('
                      </td>
                     </tr>
+      ');
+      my ($result,$perm_reqd)=&Apache::lonnet::auto_photo_permission($crs,$dom);
+      my $can_enable = 1;
+      my $institution = $Apache::lonnet::domaindescription{$dom};
+      if ($result eq 'ok') {
+          if ($perm_reqd eq 'yes') {
+              if (!($enrollvar{'photopermission'} eq 'yes')) {
+                  $can_enable = 0;
+              } else {
+                  if ($env{'user.name'} eq $enrollvar{'courseowner'}) {
+                      $r->print('
+                    <tr>
+                     <td>'.
+&mt('Previously the owner of this course agreed to the conditions of use of digital student photos required by [_1].', $institution).'<br />'.&mt('As a result Course Coordinators can choose to automatically import student photos into this course.').'<br /><nobr><label>'.&mt('[_1] owner acceptance of these conditions of use?','<b>Cancel</b>').'&nbsp;<input type="checkbox" name="cancel_agreement" value="1" /></label></nobr>
+                     </td>
+                    </tr>
+                      ');
+                  }
+              }
+          }
+      } else {
+          $r->print('
+                    <tr>
+                     <td>'.
+&mt('There was a problem determining whether course owner permission is required in order for a course coordinator to have access to student photos in this domain.').' '.&mt('As a result you will not be able to configure access to student photos at this time').'<br /><br /><input type="button" name=mainmenu" value="Go back" onclick="javascript:history.go(-1);" />
+                    </td>
+                   </tr>
+                  </form>
+          ');
+          return;
+      }
+      if ($can_enable) {
+          $r->print('
                     <tr>
                      <td>
-                      <font color=\"#888888\">
-Note: if you enable automatic import of student photos, your course will automatically have access to photos stored by your institution for all officially registered students, via a conduit established by your LON-CAPA domain coordinator.  
+                      <font color="#888888">'.
+&mt('Note: if you enable automatic import of student photos, your course will automatically have access to photos stored by your institution for officially registered students, via a conduit established by your LON-CAPA domain coordinator.').'  
                       </font>
                      </td>
                     </tr>
+');
+      } else {
+          if ($env{'user.name'} eq $enrollvar{'courseowner'}) {
+              $r->print('
+                    <tr>
+                     <td>'.
+&mt('[_1] requires a course owner to indicate acceptance of conditions of use of digital student photos before enabling automatic import into a course. If you choose to enable import of photos you will be prompted for your agreement on the next page.',$institution).'
+                     </td>
+                    </tr>
+               ');
+          } else {
+              my ($ownername,$owneremail) = &get_ownerinfo($dom,
+                                                    $enrollvar{'courseowner'});
+              $r->print('
+                    <tr>
+                     <td>'.
+&mt('The policies of your institution [_1] require that the course owner [_2] must indicate acceptance of the conditions of use of digital photos of registered students, before they may be made available for use in a course.',$institution,$ownername).'<br /><br />'.&mt('Please direct the course owner (e-mail: [_1]) to visit the "Student photos" page in the Automated Enrollment Manager to indicate acceptance of these conditions of use',$owneremail).'<br /><br /><input type="button" name=mainmenu" value="Go back" onclick="javascript:history.go(-1);" />
+                    </td>
+                   </tr>
+                  </form>
+             ');
+             return;
+          }
+      }
+      $r->print('
                     <tr>
                      </td>&nbsp;</td>
                     </tr>
                     <tr>
-                     <td align=\"right\">
-                      <input type=\"button\" name=\"showphotos\" value=\"Go\" onClick=\"process('photos')\">
+                     <td align="right">
+                      <input type="button" name="showphotos" value="Go" onClick="process('."'photos'".')">
                      </td>
                     </tr>
                    </table>
-                   <input type=\"hidden\" name=\"action\" value=\"$action\">
-                   <input type=\"hidden\" name=\"state\" value=\"process\">
+                   <input type="hidden" name="action" value="'.$action.'">
+                   <input type="hidden" name="state" value="process">
                    </form>
-      ");
+      ');
   } elsif ($action eq "updatenow") {
       $r->print("
                    <form name=\"enter\" method=\"post\"><br/>
@@ -952,6 +1014,29 @@
                    <input type=\"hidden\" name=\"state\" value=\"process\" />
                   </form>
       ");
+  } elsif ($action eq 'updatephotos') {
+      $r->print("
+                   <table width=\"100%\" border=\"0\" cellpadding=\"2\" cellspacing=\"2\">
+                    <tr>
+                     <td align=\"left\"><b>$$tasktitleref{$action}</b>
+                     </td>
+                    </tr><tr><td>");
+      if ($enrollvar{'showphotos'}) {
+          my ($update,$commentary) = &Apache::lonnet::auto_photochoice(
+                                                                    $crs,$dom);
+          $r->print('<br />'.$commentary.'<br /><br />
+<form name="photoupdate" method="post">
+<input type ="button" name="retrieve" value="'.&mt('Update photo repository').'"
+onclick="javascript:document.photoupdate.submit()" />
+<input type ="hidden" name="action" value="'.$action.'" />
+<input type ="hidden" name="state" value="process" />
+</form>');
+      } else {
+          $r->print('Update of photos is unavailable, as import of student photos is currently disabled.<br />Enable this first via: <a href="/adm/populate?action=photos">'.$$tasktitleref{'photos'}.'</a>');
+      }
+      $r->print('</td></tr>
+                 <tr><td>&nbsp;</td></tr>
+                </table>');
   } elsif ($action eq 'viewclass') {
       $r->print("
                    <form name=\"studentform\" method=\"post\"><br/>
@@ -2024,39 +2109,268 @@
     return;
 }
 
-sub print_photos_response () {
+sub photo_permission {
     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
-    my %settings = &Apache::lonnet::get('environment',['internal.showphotos'],$dom,$crs);
-    my $currphotos = $settings{'internal.showphotos'};
-    my $showphotos = '';
-    if ( exists($env{'form.showphotos'}) ) {
-	$showphotos=$env{'form.showphotos'};
+    my %settings = &Apache::lonnet::get('environment',['internal.courseowner',
+                  'internal.photopermission','internal.showphotos'],$dom,$crs);
+    my ($showphotos,$response);
+    if (exists($env{'form.cancel_agreement'})) {
+        if ($env{'user.name'} eq $settings{'internal.courseowner'}) {
+            my %cenv = (
+                'internal.photopermission' => 'no',
+            );
+            my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
+            if ($reply !~ /^ok$/) {
+                $response = &mt('There was a problem processing the record of your agreement to the conditions of use. Settings for this course have been left unchanged.').'<br/>'."\n";
+                &print_reply($r,$response,$$tasktitleref{$action});
+            } else {
+                &print_photos_response($r,$realm,$dom,$crs,$action,
+                       $tasktitleref,$showphotos,'no',\%cenv);
+            }
+            return;            
+        }
+    } 
+    if (exists($env{'form.showphotos'})) {
+        $showphotos=$env{'form.showphotos'};
+    }
+    if ($showphotos) {
+        if ($env{'form.photopermission'}) {
+            my %cenv = (
+                'internal.photopermission' => $env{'form.photopermission'},
+            );
+            my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
+            if ($reply !~ /^ok$/) {
+                $response = &mt('There was a problem processing the record of your agreement to the conditions of use. Settings for this course have been left unchanged.').'<br/>'."\n";
+            } else {
+                &print_photos_response($r,$realm,$dom,$crs,$action,
+                $tasktitleref,$showphotos,$env{'form.photopermission'},\%cenv);
+            }
+        } else {
+            my ($result,$perm_reqd,$conditions) = 
+                             &Apache::lonnet::auto_photo_permission($crs,$dom);
+            my $permcheck;
+            if ($result eq 'ok') { 
+                if ($perm_reqd eq 'yes') {
+                    if ($settings{'internal.photopermission'} eq 'yes') {
+                        &print_photos_response($r,$realm,$dom,$crs,$action,
+                                                    $tasktitleref,$showphotos);
+                    } else {
+                        return(&print_photo_agreement($r,$realm,$dom,$crs,
+                                           $action,$tasktitleref,$conditions,
+                                           $settings{'internal.courseowner'}));
+                    }
+                } elsif ($perm_reqd eq 'no') {
+                    &print_photos_response($r,$realm,$dom,$crs,$action,
+                                                    $tasktitleref,$showphotos);
+                } else {
+                    $permcheck = 'fail';
+                }
+            } else {
+                $permcheck = 'fail';
+            }
+            if ($permcheck eq 'fail') {
+                my $response = &mt('There was a problem processing your requested change, because it could not be determined whether course owner permission is required in order for a course coordinator to have access to student photos in this domain.').' '.&mt('The student photo import setting for this course has been left unchanged.').'<br/>';
+                &print_reply($r,$response,$$tasktitleref{$action});
+            }
+        }
+    } else {
+        &print_photos_response($r,$realm,$dom,$crs,$action,$tasktitleref);
     }
-    
+    return;
+}
+
+sub print_photo_agreement {
+    my ($r,$realm,$dom,$crs,$action,$tasktitleref,$conditions,$courseowner)=@_;
+    my $response;
+    my $institution = $Apache::lonnet::domaindescription{$dom};
+    if ($env{'user.name'} eq $courseowner) {
+        $response = '
+<script type="text/javascript">
+function agreement_result(caller) {
+    document.permission.photopermission.value = caller;
+    if (caller == 0) {
+        document.location.href="/adm/populate";
+    } else {
+        document.permission.submit();
+    }
+    return;
+}
+</script>
+  <form name="permission" method="post">
+   <table width="100%" border="0" cellpadding="2" cellspacing="2">
+    <tr>
+     <td align="left"><b>Use of student photos</b><br/>'."\n".
+      &mt('Acceptance by the course owner of the conditions of use of photos is currently [_1] set.','<b>not</b>').'<br />'.&mt('Please indicate your acceptance of the conditions of use of digital photos of registered students in courses at [_1].',$institution).'
+     </td>
+    </tr>
+   </table>
+   <table border="0" cellpadding="3" cellspacing="3">
+    <tr>
+     <td colspan="2">
+      <textarea rows="20" cols="80">'.$conditions.'</textarea>
+     </td>
+     <tr>
+      <td align="left">  
+       <input type="button" name="disagree" value="I do not agree" onclick="javascript:agreement_result('."'no'".');" />
+      </td>
+      <td align="right">
+       <input type="button" name="agree" value="I agree" onclick="javscript:agreement_result('."'yes'".');" />
+      </td>
+    </tr>
+   </table>
+   <input type ="hidden" name="action" value="'.$action.'" />
+   <input type ="hidden" name="state" value="process" />
+   <input type ="hidden" name="showphotos" value="1" />
+   <input type= "hidden" name="photopermission" value="" />
+  </form>
+';
+    } else {
+        my ($ownername,$owneremail) = &get_oenerinfo($dom,$courseowner);
+        $response = &mt('The policies of your institution [_1] require that the course owner [_2] must indicate acceptance of the conditions of use of digital photos of registered students, before they may be made available for use in a course.',$institution,$ownername).'<br /><br />'.&mt('Please direct the course owner (e-mail: [_1]) to visit the "Student photos" page in the Automated Enrollment Manager to indicate acceptance of these conditions of use',$owneremail);
+    }
+    &print_reply($r,$response,$$tasktitleref{$action});
+}
+
+sub print_photos_response {
+    my ($r,$realm,$dom,$crs,$action,$tasktitleref,$showphotos,$photopermission,
+                                                            $permissionenv)=@_;
+    my %newenv;
+    if (defined($permissionenv)) {
+        foreach my $key (keys(%{$permissionenv})) {
+            if (exists($env{'request.course.id'})) {
+                $newenv{$env{'request.course.id'}.'.'.$key} =
+                                                         $$permissionenv{$key};
+            }
+        }
+    }
+    my %settings = &Apache::lonnet::get('environment',['internal.showphotos'],
+                                                                    $dom,$crs);
+    my $currphotos = $settings{'internal.showphotos'};
     my $response = "";
+    if (defined($photopermission)) {
+        if ($photopermission eq 'yes') {
+            $response = &mt('Acceptance of photo use policy recorded.').'<br />'."\n";
+        } else {
+            $response = &mt('Non-acceptance of photo use policy recorded.').'<br />'."\n";
+            $showphotos = 0;
+        }
+    }
     my %cenv = ('internal.showphotos' => $showphotos);
     my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
     if ($reply !~ /^ok$/) {
-	$response = "There was a problem processing your requested change. The student photo import setting for this course has been left unchanged.<br/>";
+	$response .= "There was a problem processing your requested change. The student photo retrieval setting for this course has been left unchanged.<br/>";
     } else {
 	if ($showphotos) {
 	    if ($currphotos) {
-		$response = "Retrieval of student photos is still <b>enabled</b><br/>";
+		$response .= "Retrieval of student photos is still <b>enabled</b>.<br/>";
 	    } else {
-		$response = "Retrieval of student photos in now <b>enabled</b><br/>";
+		$response .= "Retrieval of student photos in now <b>enabled</b>.<br/>";
+                my ($update,$commentary) = &Apache::lonnet::auto_photochoice(
+                                                                    $crs,$dom);
+                if ($update) {
+                    $response .= '<br />'.$commentary.'<br /><br />
+<form name="photoupdate" method="post">
+<input type ="button" name="retrieve" value="'.&mt('Update photo repository').'" 
+onclick="javascript:document.photoupdate.submit()" /> 
+<input type ="hidden" name="action" value="'.$action.'" />
+<input type ="hidden" name="state" value="photoupdate" />
+</form>';
+                }
 	    }
 	} else {
 	    if ($currphotos) {
-		$response = "Retrieval of student photos is now <b>disabled</b><br/>";
+		$response .= "Retrieval of student photos is now <b>disabled</b>.<br/>";
 	    } else {
-		$response = "Retrieval of student photos is still <b>disabled</b><br/>";
+		$response .= "Retrieval of student photos is still <b>disabled</b>.<br/>";
 	    }
 	}
+        foreach my $key (keys(%cenv)) {
+            if (exists($env{'request.course.id'})) {
+                $newenv{'course.'.$env{'request.course.id'}.'.'.$key} = 
+                                                                   $cenv{$key};
+            }
+        }
+    }
+    if (keys(%newenv) > 0) {
+        &Apache::lonnet::appenv(%newenv);
+    }
+    &print_reply($r,$response,$$tasktitleref{$action});
+    return;
+}
+
+sub print_photoupdate_response {
+    my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
+    my $response;
+    my %changes;
+    my %lt = &LONCAPA::Enrollment::photo_response_types();
+    my %settings = &Apache::lonnet::get('environment',['internal.coursecode',
+                   'internal.sectionnums','internal.crosslistings'],$dom,$crs);
+    my @allcourses = ();
+    my %LC_code;
+    my %affiliates;
+    my $outcome;
+    &get_institutional_codes(\%settings,,\@allcourses,\%LC_code);
+    if (@allcourses > 0) {
+        @{$affiliates{$crs}} = @allcourses;
+        $outcome = &Apache::lonnet::auto_photoupdate(\%affiliates,$dom,$crs,\%changes);
+        unless ($outcome eq 'ok') {
+            &Apache::lonnet::logthis("lonpopulate::print_photoupdate_response".
+                                         "failed to update student photos".
+                                 " for ".$crs."\@".$dom." by ".
+                                 $env{'user.name'}." \@ ".$env{'user.domain'}.
+                                 ": ".$outcome);
+        }
+        if ($outcome eq 'ok') {
+            if (keys(%changes) > 0) {
+                $response = &mt('Update of photos for registered students resulted in the following ').': <br /><script type="text/javascript">
+function photowindow(photolink) {
+    var title = "Photo_Viewer";
+    var options = "scrollbars=1,resizable=1,menubar=0";
+    options += ",width=240,height=240";
+    stdeditbrowser = open(photolink,title,options,"1");
+    stdeditbrowser.focus();
+}
+</script>
+';
+                foreach my $type (sort(keys(%changes))) {
+                    my @usernames = sort(split(/\&/,$changes{$type})); 
+                    my $count = @usernames; 
+                    $response .= '<b>'.&mt('For [_1] students, photos ',
+                                            $count).$lt{$type}.'</b><ul>';
+                    foreach my $username (@usernames) {
+                        $response .= '<li>'.$username;
+                        if (($type eq 'new') || ($type eq 'same') || ($type eq 'update')) {
+                            $response .= '&nbsp;<a href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($dom,$username,'jpg')."'".')">View</a></li>';  
+                        }
+                    }
+                    $response .= '</ul><br />';
+                }
+            } else {
+                $response = &mt('No updates of photos of registered students occurred').
+                         '<br />';
+            }    
+        } else {
+            $response = "There was a problem updating student photos for registered students in this course. <br/>";
+        }
+    } else {
+        $response = "No institutional course sections are currently associated with this course so there are no registered students for whom photos can be imported/updated";
     }
     &print_reply($r,$response,$$tasktitleref{$action});
     return;
 }
 
+sub get_ownerinfo {
+    my ($dom,$owner) = @_; 
+    my ($ownername,$owneremail);
+    if ($owner) {
+        $ownername=&Apache::loncommon::plainname($owner,$dom,'firstname');
+        my %ownerinfo = &Apache::lonnet::get('environment','permanentemail',
+                                                                  $dom,$owner);
+        $owneremail = $ownerinfo{'permanentemail'};
+    }
+    return ($ownername,$owneremail);
+}
+
 sub print_update_result () {
     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
     my $response = '';
@@ -2069,11 +2383,12 @@
     my %LC_code = ();
     my $logmsg = '';
     my $newusermsg = '';
-
-    my %settings = &Apache::lonnet::get('environment',['internal.coursecode','internal.sectionnums','internal.crosslistings','internal.authtype','internal.autharg'],$dom,$crs);
+    my %phototypes = ();
+    my %settings = &Apache::lonnet::get('environment',['internal.coursecode','internal.sectionnums','internal.crosslistings','internal.authtype','internal.autharg','internal.showphotos'],$dom,$crs);
     my $coursecode = $settings{'internal.coursecode'};
     my $authtype = $settings{'internal.authtype'};
     my $autharg = $settings{'internal.autharg'};
+    my $showphotos = $settings{'internal.showphotos'};
     my ($startaccess,$endaccess) = &get_dates_from_form();
     if ( exists($env{'form.updateadds'}) ) {
         $updateadds = $env{'form.updateadds'};
@@ -2090,42 +2405,7 @@
     } elsif ($coursecode eq '') {
 	$response = "There was a problem retrieving the course code for this LON-CAPA course.  An update of the class roster has not been carried out, and enrollment remains unchanged";
     } else {
-# Get complete list of course sections to update
-	my @currsections = ();
-	my @currxlists = ();
-	
-	if ($settings{'internal.sectionnums'} ne '') {
-	    @currsections = split(/,/,$settings{'internal.sectionnums'});
-	}
-	
-	if ($settings{'internal.crosslistings'} ne '') {
-	    @currxlists = split(/,/,$settings{'internal.crosslistings'});
-	}
-	
-	if (@currxlists > 0) {
-	    foreach (@currxlists) {
-		if (m/^([^:]+):(\w*)$/) {
-		    unless (grep/^$1$/,@allcourses) { 
-			push @allcourses,$1;
-			$LC_code{$1} = $2; 
-		    }
-		}
-	    }
-	}
-	
-	if (@currsections > 0) {
-	    foreach (@currsections) {
-		if (m/^(\w+):(\w*)$/) {
-		    my $sec = $coursecode.$1;
-		    my $gp = $2;
-		    unless (grep/^$sec$/,@allcourses) { 
-			push @allcourses,$sec;
-			$LC_code{$sec} = $gp; 
-		    }
-		}
-	    }
-	}
-
+        &get_institutional_codes(\%settings,\@allcourses,\%LC_code);
 	if (@allcourses > 0) {
 	    @{$affiliates{$crs}} = @allcourses;
 	    my $outcome = &Apache::lonnet::fetch_enrollment_query('updatenow',\%affiliates,\%reply,$dom,$crs);
@@ -2137,7 +2417,7 @@
                                  ": ".$outcome);
             }
 	    if ($reply{$crs} > 0) {
-		($changecount,$response) = &LONCAPA::Enrollment::update_LC($dom,$crs,$updateadds,$updatedrops,$startaccess,$endaccess,$authtype,$autharg,\@allcourses,\%LC_code,\$logmsg,\$newusermsg,"updatenow");
+		($changecount,$response) = &LONCAPA::Enrollment::update_LC($dom,$crs,$updateadds,$updatedrops,$startaccess,$endaccess,$authtype,$autharg,\@allcourses,\%LC_code,\$logmsg,\$newusermsg,"updatenow",\%phototypes);
 	    } else {
 		$response = "There was a problem retrieving institutional class list data for the course sections and crosslisted courses which contribute enrollment to this course. No updates have been carried out, and the roster remains unchanged.";
 	    }  
@@ -2159,6 +2439,48 @@
     return;
 }
 
+sub get_institutional_codes {
+    my ($settings,$allcourses,$LC_code) = @_;
+# Get complete list of course sections to update
+    my @currsections = ();
+    my @currxlists = ();
+    my $coursecode = $$settings{'internal.coursecode'};
+                                                                                       
+    if ($$settings{'internal.sectionnums'} ne '') {
+        @currsections = split(/,/,$$settings{'internal.sectionnums'});
+    }
+                                                                                      
+    if ($$settings{'internal.crosslistings'} ne '') {
+        @currxlists = split(/,/,$$settings{'internal.crosslistings'});
+    }
+                                                                                       
+    if (@currxlists > 0) {
+        foreach (@currxlists) {
+            if (m/^([^:]+):(\w*)$/) {
+                unless (grep/^$1$/,@{$allcourses}) {
+                    push @{$allcourses},$1;
+                    $$LC_code{$1} = $2;
+                }
+            }
+        }
+    }
+                                                                                       
+    if (@currsections > 0) {
+        foreach (@currsections) {
+            if (m/^(\w+):(\w*)$/) {
+                my $sec = $coursecode.$1;
+                my $gp = $2;
+                unless (grep/^$sec$/,@{$allcourses}) {
+                    push @{$allcourses},$sec;
+                    $$LC_code{$sec} = $gp;
+                }
+            }
+        }
+    }
+    return; 
+}
+
+
 sub print_viewclass_response {
     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
     my $response;
@@ -2478,13 +2800,13 @@
     if (! (($env{'request.course.fn'}) &&  (&Apache::lonnet::allowed('cst',$env{'request.course.id'})))) {
         # Not in a course, or not allowed to modify parms
         $env{'user.error.msg'}="/adm/populate:cst:0:0:Cannot drop or add students";
-        return HTTP_NOT_ACCEPTABLE; 
+        return HTTP_NOT_ACCEPTABLE;
     }
     # Start page
     &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;
 
-    my @tasks = ("information","chgsettings","setdates","setaccess","notify","crosslist","sections","photos","updatenow","viewclass");
+    my @tasks = ("information","chgsettings","setdates","setaccess","notify","crosslist","sections","photos","updatenow","updatephotos","viewclass");
                                                                                  
     my %tasklong = (
                information => "Task information",
@@ -2494,7 +2816,8 @@
                notify => "Notification of changes",
                crosslist => "Change crosslistings",
                sections => "Section settings",
-               photos => "Student photos",
+               photos => "Student photo settings",
+               updatephotos => "Update student photos",
                updatenow => "Update roster now",
                newcross => "Add crosslistings",
                newsections => "Add sections",
@@ -2508,7 +2831,8 @@
                notify => "Notification of enrollment changes",
                crosslist => "Changes to crosslistings",
                sections => "Changes to section settings",
-               photos => "Automatic import of student photos",
+               photos => "Student photo settings",
+               updatephotos => "Update student photos",
                updatenow => "Immediate course roster update",
                newcross => "Adding new crosslisted courses",
                newsections => "Adding new course sections",
@@ -2592,7 +2916,13 @@
     } elsif ($action eq "updatenow") {
         &print_update_result($r,$realm,$dom,$crs,$action,\%tasktitle);
     } elsif ($action eq "photos") {
-        &print_photos_response($r,$realm,$dom,$crs,$action,\%tasktitle);
+        if ($state eq "photoupdate") {
+            &print_photoupdate_response($r,$realm,$dom,$crs,$action,\%tasktitle);
+        } else { 
+            &photo_permission($r,$realm,$dom,$crs,$action,\%tasktitle);
+        }
+    } elsif ($action eq "updatephotos") {
+        &print_photoupdate_response($r,$realm,$dom,$crs,$action,\%tasktitle);
     } elsif ($action eq "newcross") {
         &print_crosslistings_response($r,$realm,$dom,$crs,$action,\%tasktitle);    
     } elsif ($action eq "newsections") {
Index: loncom/interface/londropadd.pm
diff -u loncom/interface/londropadd.pm:1.133 loncom/interface/londropadd.pm:1.134
--- loncom/interface/londropadd.pm:1.133	Mon Nov 21 14:44:14 2005
+++ loncom/interface/londropadd.pm	Tue Feb  7 00:08:32 2006
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to drop and add students in courses 
 #
-# $Id: londropadd.pm,v 1.133 2005/11/21 19:44:14 albertel Exp $
+# $Id: londropadd.pm,v 1.134 2006/02/07 05:08:32 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1258,6 +1258,11 @@
     if ($sortby !~ /^(username|domain|section|fullname|id|start|end|type)$/) {
         $sortby = 'username';
     }
+    if (! exists($env{'form.displayphotos'})) {
+        $env{'form.displayphotos'} = 'off';
+    }
+    my $displayphotos = $env{'form.displayphotos'};
+
     # Print out header 
     unless ($mode eq 'autoenroll') {
         $r->print(<<END);
@@ -1266,6 +1271,7 @@
     }
     $r->print(<<END);
 <input type="hidden" name="sortby" value="$sortby" />
+<input type="hidden" name="displayphotos" value="$displayphotos" />
 END
     if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll') {
         if ($linkto eq 'aboutme') {
@@ -1280,7 +1286,8 @@
                                            'sec'    => "section",
                                            'start'  => "start date",
                                            'end'    => "end date",
-                                           'type'   => "enroll type/action"
+                                           'type'   => "enroll type/action",
+                                           'photo'  => "photo",
 					   );
         unless ($mode eq 'autoenroll') {
             $r->print(<<END);
@@ -1288,6 +1295,19 @@
 <input type="hidden" name="sdom"   value="" />
 END
         }
+        if ($env{'course.'.$env{'request.course.id'}.'.internal.showphotos'}) {
+            $r->print('
+<script type="text/javascript">
+function photowindow(photolink) {
+    var title = "Photo_Viewer";
+    var options = "scrollbars=1,resizable=1,menubar=0";
+    options += ",width=240,height=240";
+    stdeditbrowser = open(photolink,title,options,"1");
+    stdeditbrowser.focus();
+}
+</script>
+           ');
+        }
         $r->print("
 <p>
 <table border=2>
@@ -1318,8 +1338,23 @@
     </th><th>
        <a href="javascript:document.studentform.sortby.value='end';document.studentform.submit();">$lt{'end'}</a>
     </th>
-  </tr>
 END
+        if ($env{'course.'.$env{'request.course.id'}.'.internal.showphotos'}) {
+            my %photo_options = &Apache::lonlocal::texthash (
+                                                            'on' => 'Show',
+                                                            'off' => 'Hide',
+                                                            );
+            my $photochg = 'on';
+            if ($displayphotos eq 'on') {
+                $photochg = 'off';
+            }
+            $r->print('    <th>'."\n".'     '. 
+            '<a href="javascript:document.studentform.displayphotos.value='.
+                      "'".$photochg."'".';document.studentform.submit();">'.
+                      $photo_options{$photochg}.'</a>&nbsp;'.$lt{'photo'}."\n".
+                      '    </th>'."\n");
+        }
+        $r->print("  </tr>\n");
     } elsif ($mode eq 'csv') {
 	#
 	# Open a file
@@ -1457,8 +1492,19 @@
     <td>$section</td>
     <td>$start</td>
     <td>$end</td>
-   </tr>
 END
+            if ($env{'course.'.$env{'request.course.id'}.
+                                                     '.internal.showphotos'}) {
+                if ($displayphotos eq 'on') {
+                    my $imgurl = &Apache::lonnet::retrievestudentphoto($domain,
+                                                  $username,'gif','thumbnail');
+                
+                    $r->print('    <td align="right"><a href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($domain,$username,'jpg')."'".')"><img src="'.$imgurl.'" border="1"></a></td>');
+                } else {
+                    $r->print('    <td>&nbsp;</td>  ');
+                }
+            }
+            $r->print('  </tr>  ');
         } elsif ($mode eq 'csv') {
             next if (! defined($CSVfile));
             # no need to bother with $linkto

--raeburn1139288913--