--- loncom/lonnet/perl/lonnet.pm	2005/11/21 15:41:29	1.681
+++ loncom/lonnet/perl/lonnet.pm	2005/12/28 19:26:19	1.688
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.681 2005/11/21 15:41:29 raeburn Exp $
+# $Id: lonnet.pm,v 1.688 2005/12/28 19:26:19 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -40,8 +40,8 @@ qw(%perlvar %hostname %badServerCache %i
    %courselogs %accesshash %userrolehash %domainrolehash $processmarker $dumpcount 
    %coursedombuf %coursenumbuf %coursehombuf %coursedescrbuf %courseinstcodebuf %courseownerbuf
    %domaindescription %domain_auth_def %domain_auth_arg_def 
-   %domain_lang_def %domain_city %domain_longi %domain_lati $tmpdir $_64bit
-   %env);
+   %domain_lang_def %domain_city %domain_longi %domain_lati %domain_primary
+   $tmpdir $_64bit %env);
 
 use IO::Socket;
 use GDBM_File;
@@ -1280,8 +1280,15 @@ sub clean_filename {
 }
 
 # --------------- Take an uploaded file and put it into the userfiles directory
-# input: name of form element, coursedoc=1 means this is for the course
-# output: url of file in userspace
+# input: $formname - the contents of the file are in $env{"form.$formname"}
+#                    the desired filenam is in $env{"form.$formname"}
+#        $coursedoc - if true up to the current course
+#                     if false
+#        $subdir - directory in userfile to store the file into
+#        $parser, $allfiles, $codebase - unknown
+#
+# output: url of file in userspace, or error: <message> 
+#             or /adm/notfound.html if failure to upload occurse
 
 
 sub userfileupload {
@@ -1853,28 +1860,25 @@ sub courseiddump {
 # ---------------------------------------------------------- DC e-mail
 
 sub dcmailput {
-    my ($domain,$msgid,$contents,$server)=@_;
+    my ($domain,$msgid,$message,$server)=@_;
     my $status = &Apache::lonnet::critical(
        'dcmailput:'.$domain.':'.&Apache::lonnet::escape($msgid).'='.
-       &Apache::lonnet::escape($$contents{$server}),$server);
+       &Apache::lonnet::escape($message),$server);
     return $status;
 }
 
 sub dcmaildump {
     my ($dom,$startdate,$enddate,$senders) = @_;
-    my %returnhash=(); 
-    foreach my $tryserver (keys(%libserv)) {
-        if ($hostdom{$tryserver} eq $dom) {
-            %{$returnhash{$tryserver}}=();
-	    my $cmd='dcmaildump:'.$dom.':'.
-		&escape($startdate).':'.&escape($enddate).':';
-	    my @esc_senders=map { &escape($_)} @$senders;
-	    $cmd.=&escape(join('&',@esc_senders));
-	    foreach (split(/\&/,&reply($cmd,$tryserver))) {
-                my ($key,$value) = split(/\=/,$_);
-                if (($key) && ($value)) {
-                    $returnhash{$tryserver}{&unescape($key)} = &unescape($value);
-                }
+    my %returnhash=();
+    if (exists($domain_primary{$dom})) {
+        my $cmd='dcmaildump:'.$dom.':'.&escape($startdate).':'.
+                                                         &escape($enddate).':';
+	my @esc_senders=map { &escape($_)} @$senders;
+	$cmd.=&escape(join('&',@esc_senders));
+	foreach (split(/\&/,&reply($cmd,$domain_primary{$dom}))) {
+            my ($key,$value) = split(/\=/,$_);
+            if (($key) && ($value)) {
+                $returnhash{&unescape($key)} = &unescape($value);
             }
         }
     }
@@ -3013,8 +3017,9 @@ sub tmpput {
 
 # ------------------------------------------------------------ tmpget interface
 sub tmpget {
-    my ($token)=@_;
-    my $rep=&reply("tmpget:$token",$perlvar{'lonHostID'});
+    my ($token,$server)=@_;
+    if (!defined($server)) { $server = $perlvar{'lonHostID'}; }
+    my $rep=&reply("tmpget:$token",$server);
     my %returnhash;
     foreach my $item (split(/\&/,$rep)) {
 	my ($key,$value)=split(/=/,$item);
@@ -3023,6 +3028,13 @@ sub tmpget {
     return %returnhash;
 }
 
+# ------------------------------------------------------------ tmpget interface
+sub tmpdel {
+    my ($token,$server)=@_;
+    if (!defined($server)) { $server = $perlvar{'lonHostID'}; }
+    return &reply("tmpdel:$token",$server);
+}
+
 # ---------------------------------------------- Custom access rule evaluation
 
 sub customaccess {
@@ -3703,24 +3715,8 @@ sub auto_instcode_format {
 # ------------------------------------------------------- Course Group routines
 
 sub get_coursegroups {
-    my ($cdom,$cnum,$curr_groups,$group) = @_;
-    my $numgroups = 0;
-    %{$curr_groups} = &dump('coursegroups',$cdom,$cnum,$group);
-    my ($tmp)=keys(%{$curr_groups});
-    if ($tmp eq 'error: 2 tie(GDBM) Failed while attempting dump') {
-        my %emptyhash = ();
-        if (&put('coursegroups',\%emptyhash,$cdom,$cnum) eq 'ok') {
-            %{$curr_groups} = &dump('coursegroups',$cdom,$cnum,$group);
-            $tmp=keys(%{$curr_groups});
-        }
-    }
-    if ($tmp=~/^error:/) {
-        &logthis('Error retrieving groups: '.$tmp.' in '.$cnum.':'.$cdom);
-    } else {
-        my @groups = keys(%{$curr_groups});
-        $numgroups = @groups;
-    }
-    return $numgroups;
+    my ($cdom,$cnum,$group) = @_;
+    return(&dump('coursegroups',$cdom,$cnum,$group));
 }
 
 sub modify_coursegroup {
@@ -3734,6 +3730,10 @@ sub modify_group_roles {
     my $role = 'gr/'.&escape($userprivs);
     my ($uname,$udom) = split(/:/,$user);
     my $result = &assignrole($udom,$uname,$url,$role,$end,$start);
+    if ($result eq 'ok') {
+        &devalidate_getgroups_cache($udom,$uname,$cdom,$cnum);
+    }
+
     return $result;
 }
 
@@ -3743,6 +3743,66 @@ sub modify_coursegroup_membership {
     return $result;
 }
 
+sub get_active_groups {
+    my ($udom,$uname,$cdom,$cnum) = @_;
+    my $now = time;
+    my %groups = ();
+    foreach my $key (keys(%env)) {
+        if ($key =~ m-user\.role\.gr\./([^/]+)/([^/]+)/(\w+)$-) {
+            my ($start,$end) = split(/\./,$env{$key});
+            if (($end!=0) && ($end<$now)) { next; }
+            if (($start!=0) && ($start>$now)) { next; }
+            if ($1 eq $cdom && $2 eq $cnum) {
+                $groups{$3} = $env{$key} ;
+            }
+        }
+    }
+    return %groups;
+}
+
+sub get_group_membership {
+    my ($cdom,$cnum,$group) = @_;
+    return(&dump('groupmembership',$cdom,$cnum,$group));
+}
+
+sub get_users_groups {
+    my ($udom,$uname,$courseid) = @_;
+    my $cachetime=1800;
+    $courseid=~s/\_/\//g;
+    $courseid=~s/^(\w)/\/$1/;
+
+    my $hashid="$udom:$uname:$courseid";
+    my ($result,$cached)=&is_cached_new('getgroups',$hashid);
+    if (defined($cached)) { return $result; }
+
+    my %roleshash = &dump('roles',$udom,$uname,$courseid);
+    my ($tmp) = keys(%roleshash);
+    if ($tmp=~/^error:/) {
+        &logthis('Error retrieving roles: '.$tmp.' for '.$uname.':'.$udom);
+        return '';
+    } else {
+        my $grouplist;
+        foreach my $key (keys %roleshash) {
+            if ($key =~ /^\Q$courseid\E\/(\w+)\_gr$/) {
+                unless ($roleshash{$key} =~ /_1_1$/) {   # deleted membership
+                    $grouplist .= $1.':';
+                }
+            }
+        }
+        $grouplist =~ s/:$//;
+        return &do_cache_new('getgroups',$hashid,$grouplist,$cachetime);
+    }
+}
+
+sub devalidate_getgroups_cache {
+    my ($udom,$uname,$cdom,$cnum)=@_;
+    my $courseid = $cdom.'_'.$cnum;
+    $courseid=~s/\_/\//g;
+    $courseid=~s/^(\w)/\/$1/;
+    my $hashid="$udom:$uname:$courseid";
+    &devalidate_cache_new('getgroups',$hashid);
+}
+
 # ------------------------------------------------------------------ Plain Text
 
 sub plaintext {
@@ -4757,7 +4817,8 @@ sub EXT {
         return $env{'course.'.$courseid.'.'.$spacequalifierrest};
     } elsif ($realm eq 'resource') {
 
-	my $section;
+	my ($section,$group);
+        my @groups = ();
 	if (defined($courseid) && $courseid eq $env{'request.course.id'}) {
 	    if (!$symbparm) { $symbparm=&symbread(); }
 	}
@@ -4777,14 +4838,29 @@ sub EXT {
 	    if (($env{'user.name'} eq $uname) &&
 		($env{'user.domain'} eq $udom)) {
 		$section=$env{'request.course.sec'};
+                @groups=split(/:/,$env{'request.course.groups'});
+                if (@groups > 0) {
+                    @groups = sort(@groups);
+                    $group = $groups[0];
+                }
 	    } else {
 		if (! defined($usection)) {
 		    $section=&getsection($udom,$uname,$courseid);
 		} else {
 		    $section = $usection;
 		}
+                my $grouplist = &get_users_groups($udom,$uname,$courseid);
+                if ($grouplist) {
+                    @groups = split(/:/,$grouplist);
+                    @groups = sort(@groups);
+                    $group = $groups[0];
+                }
 	    }
 
+            my $grplevel=$courseid.'.['.$group.'].'.$spacequalifierrest;
+            my $grplevelr=$courseid.'.['.$group.'].'.$symbparm;
+            my $grplevelm=$courseid.'.['.$group.'].'.$mapparm;
+
 	    my $seclevel=$courseid.'.['.$section.'].'.$spacequalifierrest;
 	    my $seclevelr=$courseid.'.['.$section.'].'.$symbparm;
 	    my $seclevelm=$courseid.'.['.$section.'].'.$mapparm;
@@ -4802,8 +4878,17 @@ sub EXT {
 	    if (defined($userreply)) { return $userreply; }
 
 # ------------------------------------------------ second, check some of course
+            my $coursereply;
+            if (defined($group)) {
+                $coursereply = &resdata($env{'course.'.$courseid.'.num'},
+                                     $env{'course.'.$courseid.'.domain'},
+                                     'course',
+                                     ($grplevelr,$grplevelm,$grplevel,
+                                      $courselevelr));
+                if (defined($coursereply)) { return $coursereply; }
+            }
 
-	    my $coursereply=&resdata($env{'course.'.$courseid.'.num'},
+	    $coursereply=&resdata($env{'course.'.$courseid.'.num'},
 				     $env{'course.'.$courseid.'.domain'},
 				     'course',
 				     ($seclevelr,$seclevelm,$seclevel,
@@ -5368,6 +5453,9 @@ sub symbread {
         if ( ($thisfn =~ m/^(uploaded|editupload)\//) && ($thisfn !~ m/\.(page|sequence)$/) ) {
             $targetfn = 'adm/wrapper/'.$thisfn;
         }
+	if ($targetfn =~ m|^adm/wrapper/(ext/.*)|) {
+	    $targetfn=$1;
+	}
         if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',
                       &GDBM_READER(),0640)) {
 	    $syval=$hash{$targetfn};
@@ -6141,7 +6229,7 @@ BEGIN {
 #           next if /^\#/;
            chomp;
            my ($domain, $domain_description, $def_auth, $def_auth_arg,
-	       $def_lang, $city, $longi, $lati) = split(/:/,$_);
+	       $def_lang, $city, $longi, $lati, $primary) = split(/:/,$_);
 	   $domain_auth_def{$domain}=$def_auth;
            $domain_auth_arg_def{$domain}=$def_auth_arg;
 	   $domaindescription{$domain}=$domain_description;
@@ -6149,6 +6237,7 @@ BEGIN {
 	   $domain_city{$domain}=$city;
 	   $domain_longi{$domain}=$longi;
 	   $domain_lati{$domain}=$lati;
+           $domain_primary{$domain}=$primary;
 
  #         &logthis("Domain.tab: $domain, $domain_auth_def{$domain}, $domain_auth_arg_def{$domain},$domaindescription{$domain}");
 #          &logthis("Domain.tab: $domain ".$domaindescription{$domain} );