--- loncom/misc/refresh_courseids_db.pl 2010/07/30 17:46:12 1.6 +++ loncom/misc/refresh_courseids_db.pl 2021/03/31 02:19:59 1.23 @@ -1,7 +1,7 @@ #!/usr/bin/perl # The LearningOnline Network # -# $Id: refresh_courseids_db.pl,v 1.6 2010/07/30 17:46:12 raeburn Exp $ +# $Id: refresh_courseids_db.pl,v 1.23 2021/03/31 02:19:59 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -57,12 +57,11 @@ use Apache::loncommon; use Apache::lonuserstate; use Apache::loncoursedata; use Apache::lonnavmaps; +use Apache::lonrelrequtils; use LONCAPA qw(:DEFAULT :match); exit if ($Apache::lonnet::perlvar{'lonRole'} ne 'library'); -use vars qw( %checkparms %checkresponsetypes %checkcrstypes %anonsurvey ); - # Make sure this process is running from user=www my $wwwid=getpwnam('www'); if ($wwwid!=$<) { @@ -78,18 +77,23 @@ open(my $fh,'>>'.$Apache::lonnet::perlva print $fh "==== refresh_courseids_db.pl Run ".localtime()."====\n"; my @domains = sort(&Apache::lonnet::current_machine_domains()); +my @ids=&Apache::lonnet::current_machine_ids(); + +&Apache::lonrelrequtils::init_global_hashes(); +my $globals_set = 1; -&build_release_hashes(); $env{'allowed.bre'} = 'F'; foreach my $dom (@domains) { + $env{'user.domain'} = $dom; + $env{'user.name'} = &Apache::lonnet::get_domainconfiguser($dom); my %courseshash; - my @ids=&Apache::lonnet::current_machine_ids(); my %currhash = &Apache::lonnet::courseiddump($dom,'.',1,'.','.','.',1,\@ids,'.'); + my %lastaccess = &Apache::lonnet::courselastaccess($dom,undef,\@ids); my $dir = $Apache::lonnet::perlvar{lonUsersDir}.'/'.$dom; my %domdesign = &Apache::loncommon::get_domainconf($dom); my $autoassign = $domdesign{$dom.'.autoassign.co-owners'}; - &recurse_courses($dom,$dir,0,\%courseshash,\%currhash,$autoassign,$fh); + &recurse_courses($dom,$dir,0,\%courseshash,\%currhash,\%lastaccess,$autoassign,$fh); foreach my $lonhost (keys(%courseshash)) { if (ref($courseshash{$lonhost}) eq 'HASH') { if (&Apache::lonnet::courseidput($dom,$courseshash{$lonhost},$lonhost,'notime') eq 'ok') { @@ -99,6 +103,8 @@ foreach my $dom (@domains) { } } } + delete($env{'user.name'}); + delete($env{'user.domain'}); } delete($env{'allowed.bre'}); @@ -108,7 +114,7 @@ print $fh "==== refresh_courseids.db com close($fh); sub recurse_courses { - my ($cdom,$dir,$depth,$courseshash,$currhash,$autoassign,$fh) = @_; + my ($cdom,$dir,$depth,$courseshash,$currhash,$lastaccess,$autoassign,$fh) = @_; next unless (ref($currhash) eq 'HASH'); if (-d $dir) { opendir(DIR,$dir); @@ -116,9 +122,9 @@ sub recurse_courses { closedir(DIR); $depth ++; foreach my $item (@contents) { - if ($depth < 4) { + if (($depth < 4) && (length($item) == 1)) { &recurse_courses($cdom,$dir.'/'.$item,$depth,$courseshash, - $currhash,$autoassign,$fh); + $currhash,$lastaccess,$autoassign,$fh); } elsif ($item =~ /^$match_courseid$/) { my $cnum = $item; my $cid = $cdom.'_'.$cnum; @@ -151,6 +157,7 @@ sub recurse_courses { } my $chome = &Apache::lonnet::homeserver($cnum,$cdom); my $owner = $courseinfo{'internal.courseowner'}; + my $twodaysago = time - 172800; my (%roleshash,$gotcc,$reqdmajor,$reqdminor); if ($owner eq '') { %roleshash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef,undef,['cc'],undef,undef,1); @@ -176,8 +183,12 @@ sub recurse_courses { my $creator = $courseinfo{'internal.creator'}; my $creationcontext = $courseinfo{'internal.creationcontext'}; my $inst_code = $courseinfo{'internal.coursecode'}; + my $xlists = $courseinfo{'internal.crosslistings'}; + my $releaserequired = $courseinfo{'internal.releaserequired'}; + my $uniquecode = $courseinfo{'internal.uniquecode'}; $inst_code = '' if (!defined($inst_code)); $owner = '' if (!defined($owner)); + $uniquecode = '' if (!defined($uniquecode)); if ($created eq '') { if (ref($currhash->{$cid}) eq 'HASH') { $created = $currhash->{$cid}{'created'}; @@ -198,13 +209,11 @@ sub recurse_courses { my @stats = stat("$dir/$cnum/passwd"); $created = $stats[9]; } - my %lastaccess = - &Apache::lonnet::courselastaccess($cdom,$cnum); - if ($lastaccess{$cid}) { + if ($lastaccess->{$cid}) { if ($created eq '') { - $created = $lastaccess{$cid}; - } elsif ($lastaccess{$cid} < $created) { - $created = $lastaccess{$cid}; + $created = $lastaccess->{$cid}; + } elsif ($lastaccess->{$cid} < $created) { + $created = $lastaccess->{$cid}; } } unless ($created eq '') { @@ -212,26 +221,38 @@ sub recurse_courses { } } } - - $env{'request.course.id'} = $cdom.'_'.$cnum; - $env{'request.role'} = 'cc./'.$cdom.'/'.$cnum; - &Apache::lonuserstate::readmap($cdom.'/'.$cnum); - - # check all parameters - ($reqdmajor,$reqdminor) = ¶meter_constraints($cnum,$cdom); - - # check course type - ($reqdmajor,$reqdminor) = &coursetype_constraints($cnum,$cdom,$crstype, - $reqdmajor, - $reqdminor); - # check course contents - ($reqdmajor,$reqdminor) = &coursecontent_constraints($cnum,$cdom, - $reqdmajor, - $reqdminor); - delete($env{'request.course.id'}); - delete($env{'request.role'}); + + if (($chome ne '') && ($lastaccess->{$cid} > $twodaysago)) { + $env{'request.course.id'} = $cdom.'_'.$cnum; + $env{'request.role'} = 'cc./'.$cdom.'/'.$cnum; + $env{'request.role.adv'} = 1; + + my $readmap = 1; + ($reqdmajor,$reqdminor) = &Apache::lonrelrequtils::get_release_req($cnum,$cdom, + $crstype,$readmap, + $globals_set); + delete($env{'request.role.adv'}); + delete($env{'request.course.id'}); + delete($env{'request.role'}); + } elsif ($releaserequired) { + ($reqdmajor,$reqdminor) = split(/\./,$releaserequired); + } unless ($chome eq 'no_host') { + if (($lastaccess->{$cid} eq '') || + ($lastaccess->{$cid} > $twodaysago)) { + my $contentchange; + if ($courseinfo{'internal.created'} eq '') { + $contentchange = &last_map_update($cnum,$cdom); + } else { + unless ($courseinfo{'internal.created'} > $lastaccess->{$cid}) { + $contentchange = &last_map_update($cnum,$cdom); + } + } + if (($contentchange) && ($contentchange > $courseinfo{'internal.contentchange'})) { + $changes{'internal.contentchange'} = $contentchange; + } + } $courseshash->{$chome}{$cid} = { description => $courseinfo{'description'}, inst_code => $inst_code, @@ -261,9 +282,20 @@ sub recurse_courses { my $cc = $1; unless ($cc eq $owner) { my ($result,$desc) = &Apache::lonnet::auto_validate_instcode($cnum,$cdom,$inst_code,$cc); + unless ($result eq 'valid') { + if ($xlists ne '') { + foreach my $xlist (split(',',$xlists)) { + my ($inst_crosslist,$lcsec) = split(':',$xlist); + $result = + &Apache::lonnet::auto_validate_inst_crosslist($cnum,$cdom,$inst_code, + $inst_crosslist,$cc); + last if ($result eq 'valid'); + } + } + } if ($result eq 'valid') { if (@newcoowners > 0) { - unless (grep(/^\Q$cc\E$/,@newcoowners)) { + unless (grep(/^\Q$cc\E$/,@newcoowners)) { push(@newcoowners,$cc); } } else { @@ -298,7 +330,7 @@ sub recurse_courses { $courseshash->{$chome}{$cid}{$item} = $courseinfo{$item}; } } - foreach my $item ('selfenroll_types','selfenroll_start_date','selfenroll_end_date') { + foreach my $item ('selfenroll_types','selfenroll_start_date','selfenroll_end_date','uniquecode') { if ($courseinfo{'internal.'.$item} ne '') { $courseshash->{$chome}{$cid}{$item} = $courseinfo{'internal.'.$item}; @@ -315,7 +347,6 @@ sub recurse_courses { $changes{'internal.releaserequired'} = $releasereq; } else { if ($courseinfo{'internal.releaserequired'} ne $releasereq) { - $changes{'internal.releaserequired'} = $releasereq; } } @@ -338,130 +369,21 @@ sub recurse_courses { return; } -sub parameter_constraints { +sub last_map_update { my ($cnum,$cdom) = @_; - my ($reqdmajor,$reqdminor); - my $resourcedata=&read_paramdata($cnum,$cdom); - if (ref($resourcedata) eq 'HASH') { - foreach my $key (keys(%{$resourcedata})) { - foreach my $item (keys(%checkparms)) { - if ($key =~ /(\Q$item\E)$/) { - if (ref($checkparms{$item}) eq 'ARRAY') { - my $value = $resourcedata->{$key}; - if (grep(/^\Q$value\E$/,@{$checkparms{$item}})) { - my ($major,$minor) = split(/\./,$Apache::lonnet::needsrelease{'parameter:'.$item.':'.$value}); - ($reqdmajor,$reqdminor) = - &update_reqd_loncaparev($major,$minor,$reqdmajor,$reqdminor); - } - } - } - } - } - } - return ($reqdmajor,$reqdminor); -} - -sub coursetype_constraints { - my ($cnum,$cdom,$crstype,$reqdmajor,$reqdminor) = @_; - if (defined($checkcrstypes{$crstype})) { - my ($major,$minor) = split(/\./,$checkcrstypes{$crstype}); - ($reqdmajor,$reqdminor) = - &update_reqd_loncaparev($major,$minor,$reqdmajor,$reqdminor); - } - return ($reqdmajor,$reqdminor); -} - -sub coursecontent_constraints { - my ($cnum,$cdom,$reqdmajor,$reqdminor) = @_; - my $navmap = Apache::lonnavmaps::navmap->new(); - if (defined($navmap)) { - my %resourcetracker = &Apache::lonnet::dump('nohist_resourcetracker', - $cdom,$cnum); - my %allresponses; - my $anonsurv_subm; - foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_problem() },1,0)) { - my %responses = $res->responseTypes(); - foreach my $key (keys(%responses)) { - next unless(exists($checkresponsetypes{$key})); - $allresponses{$key} += $responses{$key}; - } - my @parts = @{$res->parts()}; - my $symb = $res->symb(); - foreach my $part (@parts) { - if (exists($resourcetracker{$symb."\0".$part."\0anonymous"})) { - $anonsurv_subm = 1; - } - } - } - foreach my $key (keys(%allresponses)) { - my ($major,$minor) = split(/\./,$checkresponsetypes{$key}); - ($reqdmajor,$reqdminor) = &update_reqd_loncaparev($major,$minor,$reqdmajor,$reqdminor); - } - if ($anonsurv_subm) { - ($reqdmajor,$reqdminor) = &update_reqd_loncaparev($anonsurvey{major}, - $anonsurvey{minor},$reqdmajor,$reqdminor); - } - } - return ($reqdmajor,$reqdminor); -} - -sub update_reqd_loncaparev { - my ($major,$minor,$reqdmajor,$reqdminor) = @_; - if (($major ne '' && $major !~ /\D/) & ($minor ne '' && $minor !~ /\D/)) { - if ($reqdmajor eq '' || $reqdminor eq '') { - $reqdmajor = $major; - $reqdminor = $minor; - } elsif (($major > $reqdmajor) || - ($major == $reqdmajor && $minor > $reqdminor)) { - $reqdmajor = $major; - $reqdminor = $minor; - } - } - return ($reqdmajor,$reqdminor); -} - -sub read_paramdata { - my ($cnum,$dom)=@_; - my $resourcedata=&Apache::lonnet::get_courseresdata($cnum,$dom); - my $classlist=&Apache::loncoursedata::get_classlist(); - foreach my $student (keys(%{$classlist})) { - if ($student =~/^($LONCAPA::match_username)\:($LONCAPA::match_domain)$/) { - my ($tuname,$tudom)=($1,$2); - my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom); - foreach my $userkey (keys(%{$useropt})) { - if ($userkey=~/^$env{'request.course.id'}/) { - my $newkey=$userkey; - $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./; - $$resourcedata{$newkey}=$$useropt{$userkey}; + my $lastupdate = 0; + my $path = &LONCAPA::propath($cdom,$cnum); + if (-d "$path/userfiles") { + if (opendir(my $dirh, "$path/userfiles")) { + my @maps = grep(/^default_?\d*\.(?:sequence|page)$/,readdir($dirh)); + foreach my $map (@maps) { + my $mtime = (stat("$path/userfiles/$map"))[9]; + if ($mtime > $lastupdate) { + $lastupdate = $mtime; } } - } - } - return $resourcedata; -} - -sub build_release_hashes { - foreach my $key (keys(%Apache::lonnet::needsrelease)) { - my ($item,$name,$value) = split(/:/,$key); - if ($item eq 'parameter') { - if (ref($checkparms{$name}) eq 'ARRAY') { - unless(grep(/^\Q$name\E$/,@{$checkparms{$name}})) { - push(@{$checkparms{$name}},$value); - } - } else { - push(@{$checkparms{$name}},$value); - } - } elsif ($item eq 'resourcetag') { - if ($name eq 'responsetype') { - $checkresponsetypes{$value} = $Apache::lonnet::needsrelease{$key} - } - } elsif ($item eq 'course') { - if ($name eq 'crstype') { - $checkcrstypes{$value} = $Apache::lonnet::needsrelease{$key}; - } } } - ($anonsurvey{major},$anonsurvey{minor}) = split(/\./,$Apache::lonnet::needsrelease{'parameter:type:anonsurvey'}); - return; + return $lastupdate; }