--- loncom/lonnet/perl/lonnet.pm 2011/10/31 13:44:37 1.1141 +++ loncom/lonnet/perl/lonnet.pm 2012/03/09 16:36:00 1.1157 @@ -1,7 +1,7 @@ # The LearningOnline Network # TCP networking package # -# $Id: lonnet.pm,v 1.1141 2011/10/31 13:44:37 raeburn Exp $ +# $Id: lonnet.pm,v 1.1157 2012/03/09 16:36:00 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -595,13 +595,21 @@ sub transfer_profile_to_env { # ---------------------------------------------------- Check for valid session sub check_for_valid_session { - my ($r) = @_; + my ($r,$name) = @_; my %cookies=CGI::Cookie->parse($r->header_in('Cookie')); - my $lonid=$cookies{'lonID'}; + if ($name eq '') { + $name = 'lonID'; + } + my $lonid=$cookies{$name}; return undef if (!$lonid); my $handle=&LONCAPA::clean_handle($lonid->value); - my $lonidsdir=$r->dir_config('lonIDsDir'); + my $lonidsdir; + if ($name eq 'lonDAV') { + $lonidsdir=$r->dir_config('lonDAVsessDir'); + } else { + $lonidsdir=$r->dir_config('lonIDsDir'); + } return undef if (!-e "$lonidsdir/$handle.id"); my $opened = open(my $idf,'+<',"$lonidsdir/$handle.id"); @@ -930,7 +938,7 @@ sub choose_server { my %domconfhash = &Apache::loncommon::get_domainconf($udom); my %servers = &get_servers($udom); my $lowest_load = 30000; - my ($login_host,$hostname,$portal_path); + my ($login_host,$hostname,$portal_path,$isredirect); foreach my $lonhost (keys(%servers)) { my $loginvia; if ($checkloginvia) { @@ -941,12 +949,14 @@ sub choose_server { &compare_server_load($server, $login_host, $lowest_load); if ($login_host eq $server) { $portal_path = $path; + $isredirect = 1; } } else { ($login_host, $lowest_load) = &compare_server_load($lonhost, $login_host, $lowest_load); if ($login_host eq $lonhost) { $portal_path = ''; + $isredirect = ''; } } } else { @@ -957,7 +967,7 @@ sub choose_server { if ($login_host ne '') { $hostname = &hostname($login_host); } - return ($login_host,$hostname,$portal_path); + return ($login_host,$hostname,$portal_path,$isredirect); } # --------------------------------------------- Try to change a user's password @@ -1920,6 +1930,7 @@ sub get_domain_defaults { $domdefaults{'auth_arg_def'} = $domconfig{'defaults'}{'auth_arg_def'}; $domdefaults{'timezone_def'} = $domconfig{'defaults'}{'timezone_def'}; $domdefaults{'datelocale_def'} = $domconfig{'defaults'}{'datelocale_def'}; + $domdefaults{'portal_def'} = $domconfig{'defaults'}{'portal_def'}; } else { $domdefaults{'lang_def'} = &domain($domain,'lang_def'); $domdefaults{'auth_def'} = &domain($domain,'auth_def'); @@ -2429,10 +2440,11 @@ sub subscribe { sub repcopy { my $filename=shift; $filename=~s/\/+/\//g; - if ($filename=~m|^/home/httpd/html/adm/|) { return 'ok'; } - if ($filename=~m|^/home/httpd/html/lonUsers/|) { return 'ok'; } - if ($filename=~m|^/home/httpd/html/userfiles/| or - $filename=~m -^/*(uploaded|editupload)/-) { + my $londocroot = $perlvar{'lonDocRoot'}; + if ($filename=~m{^\Q$londocroot/adm/\E}) { return 'ok'; } + if ($filename=~m{^\Q$londocroot/lonUsers/\E}) { return 'ok'; } + if ($filename=~m{^\Q$londocroot/userfiles/\E} or + $filename=~m{^/*(uploaded|editupload)/}) { return &repcopy_userfile($filename); } $filename=~s/[\n\r]//g; @@ -2459,7 +2471,7 @@ sub repcopy { unless ($home eq $perlvar{'lonHostID'}) { my @parts=split(/\//,$filename); my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]"; - if ($path ne "$perlvar{'lonDocRoot'}/res") { + if ($path ne "$londocroot/res") { &logthis("Malconfiguration for replication: $filename"); return 'bad_request'; } @@ -2797,7 +2809,7 @@ sub resizeImage { # $resizewidth - width (pixels) to which to resize uploaded image # $resizeheight - height (pixels) to which to resize uploaded image # $mimetype - reference to scalar to accommodate mime type determined -# from File::MMagic if $parser = parse. +# from File::MMagic. # # output: url of file in userspace, or error: # or /adm/notfound.html if failure to upload occurse @@ -2966,10 +2978,17 @@ sub finishuserfileupload { } } } + if (($context eq 'coursedoc') || ($parser eq 'parse')) { + if (ref($mimetype)) { + if ($$mimetype eq '') { + my $mm = new File::MMagic; + my $type = $mm->checktype_filename($filepath.'/'.$file); + $$mimetype = $type; + } + } + } if ($parser eq 'parse') { - my $mm = new File::MMagic; - my $type = $mm->checktype_filename($filepath.'/'.$file); - if ($type eq 'text/html') { + if ((ref($mimetype)) && ($$mimetype eq 'text/html')) { my $parse_result = &extract_embedded_items($filepath.'/'.$file, $allfiles,$codebase); unless ($parse_result eq 'ok') { @@ -2977,9 +2996,6 @@ sub finishuserfileupload { ' for embedded media: '.$parse_result); } } - if (ref($mimetype)) { - $$mimetype = $type; - } } if (($thumbwidth =~ /^\d+$/) && ($thumbheight =~ /^\d+$/)) { my $input = $filepath.'/'.$file; @@ -3250,12 +3266,6 @@ sub flushcourselogs { my $result = &inc('nohist_accesscount',\%temphash,$dom,$name); if ($result eq 'ok') { delete $accesshash{$entry}; - } elsif ($result eq 'unknown_cmd') { - # Target server has old code running on it. - my %temphash=($entry => $value); - if (&put('nohist_resevaldata',\%temphash,$dom,$name) eq 'ok') { - delete $accesshash{$entry}; - } } } else { my ($dom,$name) = ($entry=~m{___($match_domain)/($match_name)/(.*)___(\w+)$}); @@ -3337,7 +3347,7 @@ sub courseacclog { my $fnsymb=shift; unless ($env{'request.course.id'}) { return ''; } my $what=$fnsymb.':'.$env{'user.name'}.':'.$env{'user.domain'}; - if ($fnsymb=~/(problem|exam|quiz|assess|survey|form|task|page)$/) { + if ($fnsymb=~/$LONCAPA::assess_re/) { $what.=':POST'; # FIXME: Probably ought to escape things.... foreach my $key (keys(%env)) { @@ -3536,6 +3546,7 @@ sub get_my_roles { foreach my $entry (keys(%dumphash)) { my ($role,$tend,$tstart); if ($context eq 'userroles') { + next if ($entry =~ /^rolesdef/); ($role,$tend,$tstart)=split(/_/,$dumphash{$entry}); } else { ($tend,$tstart)=split(/\:/,$dumphash{$entry}); @@ -3849,6 +3860,28 @@ sub get_domain_roles { # ----------------------------------------------------------- Interval timing +{ +# Caches needed for speedup of navmaps +# We don't want to cache this for very long at all (5 seconds at most) +# +# The user for whom we cache +my $cachedkey=''; +# The cached times for this user +my %cachedtimes=(); +# When this was last done +my $cachedtime=(); + +sub load_all_first_access { + my ($uname,$udom)=@_; + if (($cachedkey eq $uname.':'.$udom) && + (abs($cachedtime-time)<5)) { + return; + } + $cachedtime=time; + $cachedkey=$uname.':'.$udom; + %cachedtimes=&dump('firstaccesstimes',$udom,$uname); +} + sub get_first_access { my ($type,$argsymb)=@_; my ($symb,$courseid,$udom,$uname)=&whichuser(); @@ -3861,8 +3894,8 @@ sub get_first_access { } else { $res=$symb; } - my %times=&get('firstaccesstimes',["$courseid\0$res"],$udom,$uname); - return $times{"$courseid\0$res"}; + &load_all_first_access($uname,$udom); + return $cachedtimes{"$courseid\0$res"}; } sub set_first_access { @@ -3876,13 +3909,14 @@ sub set_first_access { } else { $res=$symb; } + $cachedkey=''; my $firstaccess=&get_first_access($type,$symb); if (!$firstaccess) { return &put('firstaccesstimes',{"$courseid\0$res"=>time},$udom,$uname); } return 'already_set'; } - +} # --------------------------------------------- Set Expire Date for Spreadsheet sub expirespread { @@ -7513,14 +7547,16 @@ sub modify_student_enrollment { $uid = $tmp{'id'} if (!defined($uid) || $uid eq ''); } my $fullname = &format_name($first,$middle,$last,$gene,'lastname'); + my $user = "$uname:$udom"; + my %old_entry = &Apache::lonnet::get('classlist',[$user],$cdom,$cnum); my $reply=cput('classlist', - {"$uname:$udom" => + {$user => join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype) }, $cdom,$cnum); - unless (($reply eq 'ok') || ($reply eq 'delayed')) { + if (($reply eq 'ok') || ($reply eq 'delayed')) { + &devalidate_getsection_cache($udom,$uname,$cid); + } else { return 'error: '.$reply; - } else { - &devalidate_getsection_cache($udom,$uname,$cid); } # Add student role to user my $uurl='/'.$cid; @@ -7528,7 +7564,16 @@ sub modify_student_enrollment { if ($usec) { $uurl.='/'.$usec; } - return &assignrole($udom,$uname,$uurl,'st',$end,$start,undef,$selfenroll,$context); + my $result = &assignrole($udom,$uname,$uurl,'st',$end,$start,undef, + $selfenroll,$context); + if ($result ne 'ok') { + if ($old_entry{$user} ne '') { + $reply = &cput('classlist',\%old_entry,$cdom,$cnum); + } else { + $reply = &del('classlist',[$user],$cdom,$cnum); + } + } + return $result; } sub format_name { @@ -8708,15 +8753,7 @@ sub EXT { } elsif ($realm eq 'request') { # ------------------------------------------------------------- request.browser if ($space eq 'browser') { - if ($qualifier eq 'textremote') { - if (&Apache::lonlocal::mt('textual_remote_display') eq 'on') { - return 1; - } else { - return 0; - } - } else { - return $env{'browser.'.$qualifier}; - } + return $env{'browser.'.$qualifier}; # ------------------------------------------------------------ request.filename } else { return $env{'request.'.$spacequalifierrest}; @@ -9393,6 +9430,49 @@ sub get_slot { } return $slotinfo{$which}; } + +sub get_reservable_slots { + my ($cnum,$cdom,$uname,$udom) = @_; + my $now = time; + my $reservable_info; + my $key=join("\0",'reservableslots',$cdom,$cnum,$uname,$udom); + if (exists($remembered{$key})) { + $reservable_info = $remembered{$key}; + } else { + my %resv; + ($resv{'now_order'},$resv{'now'},$resv{'future_order'},$resv{'future'}) = + &Apache::loncommon::get_future_slots($cnum,$cdom,$now); + $reservable_info = \%resv; + $remembered{$key} = $reservable_info; + } + return $reservable_info; +} + +sub get_course_slots { + my ($cnum,$cdom) = @_; + my $hashid=$cnum.':'.$cdom; + my ($result,$cached) = &Apache::lonnet::is_cached_new('allslots',$hashid); + if (defined($cached)) { + if (ref($result) eq 'HASH') { + return %{$result}; + } + } else { + my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum); + my ($tmp) = keys(%slots); + if ($tmp !~ /^(con_lost|error|no_such_host)/i) { + &Apache::lonnet::do_cache_new('allslots',$hashid,\%slots,600); + return %slots; + } + } + return; +} + +sub devalidate_slots_cache { + my ($cnum,$cdom)=@_; + my $hashid=$cnum.':'.$cdom; + &devalidate_cache_new('allslots',$hashid); +} + # ------------------------------------------------- Update symbolic store links sub symblist { @@ -9758,9 +9838,11 @@ sub rndseed { if (!defined($symb)) { unless ($symb=$wsymb) { return time; } } - if (!$courseid) { $courseid=$wcourseid; } - if (!$domain) { $domain=$wdomain; } - if (!$username) { $username=$wusername } + if (!defined $courseid) { + $courseid=$wcourseid; + } + if (!defined $domain) { $domain=$wdomain; } + if (!defined $username) { $username=$wusername } my $which; if (defined($cenv->{'rndseed'})) { @@ -9768,7 +9850,6 @@ sub rndseed { } else { $which =&get_rand_alg($courseid); } - if (defined(&getCODE())) { if ($which eq '64bit5') { @@ -10094,8 +10175,9 @@ sub getfile { sub repcopy_userfile { my ($file)=@_; - if ($file =~ m -^/*(uploaded|editupload)/-) { $file=&filelocation("",$file); } - if ($file =~ m|^/home/httpd/html/lonUsers/|) { return 'ok'; } + my $londocroot = $perlvar{'lonDocRoot'}; + if ($file =~ m{^/*(uploaded|editupload)/}) { $file=&filelocation("",$file); } + if ($file =~ m{^\Q$londocroot/lonUsers/\E}) { return 'ok'; } my ($cdom,$cnum,$filename) = ($file=~m|^\Q$perlvar{'lonDocRoot'}\E/+userfiles/+($match_domain)/+($match_name)/+(.*)|); my $uri="/uploaded/$cdom/$cnum/$filename"; @@ -10248,7 +10330,7 @@ sub filelocation { if ( !( $file =~ m:^/:) ) { $location = $dir. '/'.$file; } else { - $location = '/home/httpd/html/'.$space.$file; + $location = $perlvar{'lonDocRoot'}.'/'.$space.$file; } } $location=~s://+:/:g; # remove duplicate / @@ -10274,8 +10356,8 @@ sub hreflocation { if ($file=~m-^\Q$perlvar{'lonDocRoot'}\E-) { $file=~s-^\Q$perlvar{'lonDocRoot'}\E--; } elsif ($file=~m-^\Q$perlvar{'lonUsersDir'}\E-) { - $file=~s-^/home/httpd/lonUsers/($match_domain)/./././($match_name)/userfiles/ - -/uploaded/$1/$2/-x; + $file=~s{^/home/httpd/lonUsers/($match_domain)/./././($match_name)/userfiles/} + {/uploaded/$1/$2/}x; } if ($file=~ m{^/userfiles/}) { $file =~ s{^/userfiles/}{/uploaded/};