--- loncom/lonnet/perl/lonnet.pm 2003/03/24 19:57:35 1.350 +++ loncom/lonnet/perl/lonnet.pm 2003/04/18 13:47:55 1.363 @@ -1,7 +1,7 @@ # The LearningOnline Network # TCP networking package # -# $Id: lonnet.pm,v 1.350 2003/03/24 19:57:35 www Exp $ +# $Id: lonnet.pm,v 1.363 2003/04/18 13:47:55 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -75,7 +75,7 @@ use vars qw(%perlvar %hostname %homecache %badServerCache %hostip %iphost %spareid %hostdom %libserv %pr %prp %metacache %packagetab %titlecache %courselogs %accesshash %userrolehash $processmarker $dumpcount - %coursedombuf %coursehombuf %courseresdatacache + %coursedombuf %coursenumbuf %coursehombuf %coursedescrbuf %courseresdatacache %domaindescription %domain_auth_def %domain_auth_arg_def $tmpdir); use IO::Socket; use GDBM_File; @@ -634,7 +634,7 @@ sub generate_access_keys { $ENV{'course.'.$ENV{'request.course.id'}.'.domain'} unless (defined($cdom)); $cnum= $ENV{'course.'.$ENV{'request.course.id'}.'.num'} unless (defined($cnum)); - unless (&allowed('ccc',$cdom)) { return 0; } + unless (&allowed('mky',$cdom)) { return 0; } unless (($cdom) && ($cnum)) { return 0; } if ($number>10000) { return 0; } sleep(2); # make sure don't get same seed twice @@ -1027,12 +1027,24 @@ sub log { } # ------------------------------------------------------------------ Course Log +# +# This routine flushes several buffers of non-mission-critical nature +# sub flushcourselogs { - &logthis('Flushing course log buffers'); + &logthis('Flushing log buffers'); +# +# course logs +# This is a log of all transactions in a course, which can be used +# for data mining purposes +# +# It also collects the courseid database, which lists last transaction +# times and course titles for all courseids +# + my %courseidbuffer=(); foreach (keys %courselogs) { my $crsid=$_; - if (&reply('log:'.$coursedombuf{$crsid}.':'. + if (&reply('log:'.$coursedombuf{$crsid}.':'.$coursenumbuf{$crsid}.':'. &escape($courselogs{$crsid}), $coursehombuf{$crsid}) eq 'ok') { delete $courselogs{$crsid}; @@ -1043,9 +1055,26 @@ sub flushcourselogs { " exceeded maximum size, deleting."); delete $courselogs{$crsid}; } - } + } + if ($courseidbuffer{$coursehombuf{$crsid}}) { + $courseidbuffer{$coursehombuf{$crsid}}.='&'. + &escape($crsid).'='.&escape($coursedescrbuf{$crsid}); + } else { + $courseidbuffer{$coursehombuf{$crsid}}= + &escape($crsid).'='.&escape($coursedescrbuf{$crsid}); + } + } +# +# Write course id database (reverse lookup) to homeserver of courses +# Is used in pickcourse +# + foreach (keys %courseidbuffer) { + &courseidput($hostdom{$_},$courseidbuffer{$_},$_); } - &logthis('Flushing access logs'); +# +# File accesses +# Writes to the dynamic metadata of resources to get hit counts, etc. +# foreach (keys %accesshash) { my $entry=$_; $entry=~/\_\_\_(\w+)\/(\w+)\/(.*)\_\_\_(\w+)$/; @@ -1054,13 +1083,16 @@ sub flushcourselogs { delete $accesshash{$entry}; } } - &logthis('Flushing role logs'); +# +# Roles +# Reverse lookup of user roles for course faculty/staff and co-authorship +# foreach (keys %userrolehash) { my $entry=$_; - my ($role,$uname,$udom,$runame,$rudom)= + my ($role,$uname,$udom,$runame,$rudom,$rsec)= split(/\:/,$entry); if (&Apache::lonnet::put('nohist_userroles', - { $role.':'.$uname.':'.$udom => $userrolehash{$entry} }, + { $role.':'.$uname.':'.$udom.':'.$rsec => $userrolehash{$entry} }, $rudom,$runame) eq 'ok') { delete $userrolehash{$entry}; } @@ -1073,10 +1105,13 @@ sub courselog { $what=time.':'.$what; unless ($ENV{'request.course.id'}) { return ''; } $coursedombuf{$ENV{'request.course.id'}}= - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}.':'. + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; + $coursenumbuf{$ENV{'request.course.id'}}= $ENV{'course.'.$ENV{'request.course.id'}.'.num'}; $coursehombuf{$ENV{'request.course.id'}}= $ENV{'course.'.$ENV{'request.course.id'}.'.home'}; + $coursedescrbuf{$ENV{'request.course.id'}}= + $ENV{'course.'.$ENV{'request.course.id'}.'.description'}; if (defined $courselogs{$ENV{'request.course.id'}}) { $courselogs{$ENV{'request.course.id'}}.='&'.$what; } else { @@ -1114,6 +1149,14 @@ sub countacc { } } +sub linklog { + my ($from,$to)=@_; + $from=&declutter($from); + $to=&declutter($to); + $accesshash{$from.'___'.$to.'___comefrom'}=1; + $accesshash{$to.'___'.$from.'___goto'}=1; +} + sub userrolelog { my ($trole,$username,$domain,$area,$tstart,$tend)=@_; if (($trole=~/^ca/) || ($trole=~/^in/) || @@ -1124,7 +1167,64 @@ sub userrolelog { {$trole.':'.$username.':'.$domain.':'.$runame.':'.$rudom.':'.$rsec} =$tend.':'.$tstart; } -} +} + +sub get_course_adv_roles { + my $cid=shift; + $cid=$ENV{'request.course.id'} unless (defined($cid)); + my %coursehash=&coursedescription($cid); + my %returnhash=(); + my %dumphash= + &dump('nohist_userroles',$coursehash{'domain'},$coursehash{'num'}); + my $now=time; + foreach (keys %dumphash) { + my ($tend,$tstart)=split(/\:/,$dumphash{$_}); + if (($tstart) && ($tstart<0)) { next; } + if (($tend) && ($tend<$now)) { next; } + if (($tstart) && ($now<$tstart)) { next; } + my ($role,$username,$domain,$section)=split(/\:/,$_); + my $key=&plaintext($role); + if ($section) { $key.=' (Sec/Grp '.$section.')'; } + if ($returnhash{$key}) { + $returnhash{$key}.=','.$username.':'.$domain; + } else { + $returnhash{$key}=$username.':'.$domain; + } + } + return sort %returnhash; +} + +# ---------------------------------------------------------- Course ID routines +# Deal with domain's nohist_courseid.db files +# + +sub courseidput { + my ($domain,$what,$coursehome)=@_; + return &reply('courseidput:'.$domain.':'.$what,$coursehome); +} + +sub courseiddump { + my ($domfilter,$descfilter,$sincefilter)=@_; + my %returnhash=(); + unless ($domfilter) { $domfilter=''; } + foreach my $tryserver (keys %libserv) { + if ((!$domfilter) || ($hostdom{$tryserver} eq $domfilter)) { + foreach ( + split(/\&/,&reply('courseiddump:'.$hostdom{$tryserver}.':'. + $sincefilter.':'.&escape($descfilter), + $tryserver))) { + my ($key,$value)=split(/\=/,$_); + if (($key) && ($value)) { + $returnhash{&unescape($key)}=&unescape($value); + } + } + + } + } + return %returnhash; +} + +# # ----------------------------------------------------------- Check out an item sub checkout { @@ -2458,7 +2558,7 @@ sub plaintext { # ----------------------------------------------------------------- Assign Role sub assignrole { - my ($udom,$uname,$url,$role,$end,$start)=@_; + my ($udom,$uname,$url,$role,$end,$start,$deleteflag)=@_; my $mrole; if ($role =~ /^cr\//) { unless (&allowed('ccr',$url)) { @@ -2489,7 +2589,20 @@ sub assignrole { $command.='_0_'.$start; } } +# actually delete + if ($deleteflag) { + if (&allowed('dro',$udom)) { +# modify command to delete the role + $command="encrypt:rolesdel:$ENV{'user.domain'}:$ENV{'user.name'}:". + "$udom:$uname:$url".'_'."$mrole"; +# set start and finish to negative values for userrolelog + $start=-1; + $end=-1; + } + } +# send command my $answer=&reply($command,&homeserver($uname,$udom)); +# log new user role if status is ok if ($answer eq 'ok') { &userrolelog($mrole,$uname,$udom,$url,$start,$end); } @@ -2739,6 +2852,11 @@ sub createcourse { return 'error: no such course'; } # ----------------------------------------------------------------- Course made +# log existance + &courseidput($udom,&escape($udom.'_'.$uname).'='.&escape($description), + $uhome); + &flushcourselogs(); +# set toplevel url my $topurl=$url; unless ($nonstandard) { # ------------------------------------------ For standard courses, make top url @@ -2767,25 +2885,26 @@ ENDINITMAP # ---------------------------------------------------------- Assign Custom Role sub assigncustomrole { - my ($udom,$uname,$url,$rdom,$rnam,$rolename,$end,$start)=@_; + my ($udom,$uname,$url,$rdom,$rnam,$rolename,$end,$start,$deleteflag)=@_; return &assignrole($udom,$uname,$url,'cr/'.$rdom.'/'.$rnam.'/'.$rolename, - $end,$start); + $end,$start,$deleteflag); } # ----------------------------------------------------------------- Revoke Role sub revokerole { - my ($udom,$uname,$url,$role)=@_; + my ($udom,$uname,$url,$role,$deleteflag)=@_; my $now=time; - return &assignrole($udom,$uname,$url,$role,$now); + return &assignrole($udom,$uname,$url,$role,$now,$deleteflag); } # ---------------------------------------------------------- Revoke Custom Role sub revokecustomrole { - my ($udom,$uname,$url,$rdom,$rnam,$rolename)=@_; + my ($udom,$uname,$url,$rdom,$rnam,$rolename,$deleteflag)=@_; my $now=time; - return &assigncustomrole($udom,$uname,$url,$rdom,$rnam,$rolename,$now); + return &assigncustomrole($udom,$uname,$url,$rdom,$rnam,$rolename,$now, + $deleteflag); } # ------------------------------------------------------------ Directory lister @@ -2983,8 +3102,10 @@ sub EXT { unless ($varname) { return ''; } #get real user name/domain, courseid and symb my $courseid; + my $publicuser; if (!($uname && $udom)) { - (my $cursymb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser(); + (my $cursymb,$courseid,$udom,$uname,$publicuser)= + &Apache::lonxml::whichuser(); if (!$symbparm) { $symbparm=$cursymb; } } else { $courseid=$ENV{'request.course.id'}; @@ -3007,7 +3128,12 @@ sub EXT { if (defined($Apache::lonhomework::parsing_a_problem)) { return $Apache::lonhomework::history{$qualifierrest}; } else { - my %restored=&restore($symbparm,$courseid,$udom,$uname); + my %restored; + if ($publicuser || $ENV{'request.state'} eq 'construct') { + %restored=&tmprestore($symbparm,$courseid,$udom,$uname); + } else { + %restored=&restore($symbparm,$courseid,$udom,$uname); + } return $restored{$qualifierrest}; } # ----------------------------------------------------------------- user.access @@ -3020,7 +3146,11 @@ sub EXT { ($udom eq $ENV{'user.domain'})) { return $ENV{join('.',('environment',$qualifierrest))}; } else { - my %returnhash=&userenvironment($udom,$uname,$qualifierrest); + my %returnhash; + if (!$publicuser) { + %returnhash=&userenvironment($udom,$uname, + $qualifierrest); + } return $returnhash{$qualifierrest}; } # ----------------------------------------------------------------- user.course @@ -3044,8 +3174,11 @@ sub EXT { return $uname; # ---------------------------------------------------- Any other user namespace } else { - my %reply=&get($space,[$qualifierrest],$udom,$uname); - return $reply{$qualifierrest}; + my %reply; + if (!$publicuser) { + %reply=&get($space,[$qualifierrest],$udom,$uname); + } + return $reply{$qualifierrest}; } } elsif ($realm eq 'query') { # ---------------------------------------------- pull stuff out of query string @@ -3064,7 +3197,7 @@ sub EXT { return $ENV{'course.'.$courseid.'.'.$spacequalifierrest}; } elsif ($realm eq 'resource') { - if ($courseid eq $ENV{'request.course.id'}) { + if (defined($courseid) && $courseid eq $ENV{'request.course.id'}) { #print '
'.$space.' - '.$qualifier.' - '.$spacequalifierrest; @@ -3264,16 +3397,20 @@ sub metadata { $value.=' [Part: '.$part.']'; } my $unikey='parameter'.$keyroot.'_'.$name; - if ($subp eq 'default') { $unikey='parameter_0_'.$name; } - $metathesekeys{$unikey}=1; - $metacache{$uri.':'.$unikey.'.part'}=$part; + if ($subp eq 'default') { + $unikey='parameter_0_'.$name; + $metacache{$uri.':'.$unikey.'.part'}='0'; + } else { + $metacache{$uri.':'.$unikey.'.part'}=$part; + $metathesekeys{$unikey}=1; + } unless (defined($metacache{$uri.':'.$unikey.'.'.$subp})) { $metacache{$uri.':'.$unikey.'.'.$subp}=$value; } if (defined($metacache{$uri.':'.$unikey.'.default'})) { $metacache{$uri.':'.$unikey}= - $metacache{$uri.':'.$unikey.'.default'} - } + $metacache{$uri.':'.$unikey.'.default'}; + } } } } else { @@ -3369,7 +3506,7 @@ sub metadata_generate_part0 { if ($metakey=~/^parameter\_(.*)/) { my $part=$$metacache{$uri.':'.$metakey.'.part'}; my $name=$$metacache{$uri.':'.$metakey.'.name'}; - if (! exists($$metadata{'parameter_0_'.$name})) { + if (! exists($$metadata{'parameter_0_'.$name.'.name'})) { $allnames{$name}=$part; } } @@ -3409,6 +3546,7 @@ sub gettitle { $title=$bighash{'title_'.$mapid.'.'.$resid}; untie %bighash; } + $title=~s/\&colon\;/\:/gs; if ($title) { $titlecache{$symb}=$title; return $title; @@ -3730,6 +3868,7 @@ sub goodbye { &logthis("Starting Shut down"); &flushcourselogs(); &logthis("Shutting down"); + return DONE; } BEGIN {