Diff for /loncom/Lond.pm between versions 1.2 and 1.8

version 1.2, 2012/04/26 19:51:40 version 1.8, 2015/05/22 21:14:59
Line 27 Line 27
 ###  ###
   
 #NOTE perldoc at the end of file  #NOTE perldoc at the end of file
   #TODO move remaining lond functions into this
   
 package LONCAPA::Lond;  package LONCAPA::Lond;
   
Line 39  use GDBM_File; Line 40  use GDBM_File;
   
   
 sub dump_with_regexp {  sub dump_with_regexp {
     my ( $tail, $clientname, $clientversion ) = @_;      my ( $tail, $clientversion ) = @_;
     my ( $udom, $uname, $namespace, $regexp, $range ) =       my ( $udom, $uname, $namespace, $regexp, $range ) = 
         split /:/, $tail;          split /:/, $tail;
   
     $regexp = defined $regexp ? unescape($regexp) : '.';      $regexp = $regexp ? unescape($regexp) : '.';
   
     my ($start,$end);      my ($start,$end);
   
Line 79  sub dump_with_regexp { Line 80  sub dump_with_regexp {
         if ($clientversion =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?/) {          if ($clientversion =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?/) {
             $major = $1;              $major = $1;
             $minor = $2;              $minor = $2;
   
         }          }
         if (($major > 2) || (($major == 2) && ($minor > 9))) {          if (($major > 2) || (($major == 2) && ($minor > 9))) {
             $skipcheck = 1;              $skipcheck = 1;
Line 300  sub useable_role { Line 302  sub useable_role {
 }  }
   
   
   sub get_courseinfo_hash {
       my ($cnum,$cdom,$home) = @_;
       my %info;
       eval {
           local($SIG{ALRM}) = sub { die "timeout\n"; };
           local($SIG{__DIE__})='DEFAULT';
           alarm(3);
           %info = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',$cnum,1,[$home],'.');
           alarm(0);
       };
       if ($@) {
           if ($@ eq "timeout\n") {
               &logthis("<font color='blue'>WARNING courseiddump for $cnum:$cdom from $home timedout</font>");
           } else {
               &logthis("<font color='yellow'>WARNING unexpected error during eval of call for courseiddump from $home</font>");
           }
       } else {
           if (ref($info{$cdom.'_'.$cnum}) eq 'HASH') {
               my $hashid = $cdom.':'.$cnum;
               return &Apache::lonnet::do_cache_new('courseinfo',$hashid,$info{$cdom.'_'.$cnum},600);
           }
       }
       return;
   }
   
   sub dump_course_id_handler {
       my ($tail) = @_;
   
       my ($udom,$since,$description,$instcodefilter,$ownerfilter,$coursefilter,
           $typefilter,$regexp_ok,$rtn_as_hash,$selfenrollonly,$catfilter,$showhidden,
           $caller,$cloner,$cc_clone_list,$cloneonly,$createdbefore,$createdafter,
           $creationcontext,$domcloner,$hasuniquecode,$reqcrsdom,$reqinstcode) = split(/:/,$tail);
       my $now = time;
       my ($cloneruname,$clonerudom,%cc_clone);
       if (defined($description)) {
    $description=&unescape($description);
       } else {
    $description='.';
       }
       if (defined($instcodefilter)) {
           $instcodefilter=&unescape($instcodefilter);
       } else {
           $instcodefilter='.';
       }
       my ($ownerunamefilter,$ownerdomfilter);
       if (defined($ownerfilter)) {
           $ownerfilter=&unescape($ownerfilter);
           if ($ownerfilter ne '.' && defined($ownerfilter)) {
               if ($ownerfilter =~ /^([^:]*):([^:]*)$/) {
                    $ownerunamefilter = $1;
                    $ownerdomfilter = $2;
               } else {
                   $ownerunamefilter = $ownerfilter;
                   $ownerdomfilter = '';
               }
           }
       } else {
           $ownerfilter='.';
       }
   
       if (defined($coursefilter)) {
           $coursefilter=&unescape($coursefilter);
       } else {
           $coursefilter='.';
       }
       if (defined($typefilter)) {
           $typefilter=&unescape($typefilter);
       } else {
           $typefilter='.';
       }
       if (defined($regexp_ok)) {
           $regexp_ok=&unescape($regexp_ok);
       }
       if (defined($catfilter)) {
           $catfilter=&unescape($catfilter);
       }
       if (defined($cloner)) {
           $cloner = &unescape($cloner);
           ($cloneruname,$clonerudom) = ($cloner =~ /^($LONCAPA::match_username):($LONCAPA::match_domain)$/); 
       }
       if (defined($cc_clone_list)) {
           $cc_clone_list = &unescape($cc_clone_list);
           my @cc_cloners = split('&',$cc_clone_list);
           foreach my $cid (@cc_cloners) {
               my ($clonedom,$clonenum) = split(':',$cid);
               next if ($clonedom ne $udom); 
               $cc_clone{$clonedom.'_'.$clonenum} = 1;
           } 
       }
       if ($createdbefore ne '') {
           $createdbefore = &unescape($createdbefore);
       } else {
          $createdbefore = 0;
       }
       if ($createdafter ne '') {
           $createdafter = &unescape($createdafter);
       } else {
           $createdafter = 0;
       }
       if ($creationcontext ne '') {
           $creationcontext = &unescape($creationcontext);
       } else {
           $creationcontext = '.';
       }
       unless ($hasuniquecode) {
           $hasuniquecode = '.';
       }
       if ($reqinstcode ne '') {
           $reqinstcode = &unescape($reqinstcode);
       }
       my $unpack = 1;
       if ($description eq '.' && $instcodefilter eq '.' && $ownerfilter eq '.' && 
           $typefilter eq '.') {
           $unpack = 0;
       }
       if (!defined($since)) { $since=0; }
       my (%gotcodedefaults,%otcodedefaults);
       my $qresult='';
   
       my $hashref = &tie_domain_hash($udom, "nohist_courseids", &GDBM_WRCREAT())
           or return "error: ".($!+0)." tie(GDBM) Failed while attempting courseiddump";
   
    while (my ($key,$value) = each(%$hashref)) {
               my ($unesc_key,$lasttime_key,$lasttime,$is_hash,%val,
                   %unesc_val,$selfenroll_end,$selfenroll_types,$created,
                   $context);
               $unesc_key = &unescape($key);
               if ($unesc_key =~ /^lasttime:/) {
                   next;
               } else {
                   $lasttime_key = &escape('lasttime:'.$unesc_key);
               }
               if ($hashref->{$lasttime_key} ne '') {
                   $lasttime = $hashref->{$lasttime_key};
                   next if ($lasttime<$since);
               }
               my ($canclone,$valchange,$clonefromcode);
               my $items = &Apache::lonnet::thaw_unescape($value);
               if (ref($items) eq 'HASH') {
                   if ($hashref->{$lasttime_key} eq '') {
                       next if ($since > 1);
                   }
                   if ($items->{'inst_code'}) {
                       $clonefromcode = $items->{'inst_code'};
                   }
                   $is_hash =  1;
                   if ($domcloner) {
                       $canclone = 1;
                   } elsif (defined($clonerudom)) {
                       if ($items->{'cloners'}) {
                           my @cloneable = split(',',$items->{'cloners'});
                           if (@cloneable) {
                               if (grep(/^\*$/,@cloneable))  {
                                   $canclone = 1;
                               } elsif (grep(/^\*:\Q$clonerudom\E$/,@cloneable)) {
                                   $canclone = 1;
                               } elsif (grep(/^\Q$cloneruname\E:\Q$clonerudom\E$/,@cloneable)) {
                                   $canclone = 1;
                               }
                           }
                           unless ($canclone) {
                               if ($cloneruname ne '' && $clonerudom ne '') {
                                   if ($cc_clone{$unesc_key}) {
                                       $canclone = 1;
                                       $items->{'cloners'} .= ','.$cloneruname.':'.
                                                              $clonerudom;
                                       $valchange = 1;
                                   }
                               }
                           }
                           unless ($canclone) {
                               if (($reqcrsdom eq $udom) && ($reqinstcode) && ($clonefromcode)) {
                                   if (grep(/\=/,@cloneable))  {
                                       foreach my $cloner (@cloneable) {
                                           if (($cloner ne '*') && ($cloner !~ /^\*\:$LONCAPA::match_domain$/) &&
                                               ($cloner !~ /^$LONCAPA::match_username\:$LONCAPA::match_domain$/) && ($cloner ne '')) {
                                               if ($cloner =~ /=/) {
                                                   my (%codedefaults,@code_order);
                                                   if (ref($gotcodedefaults{$udom}) eq 'HASH') {
                                                       if (ref($gotcodedefaults{$udom}{'defaults'}) eq 'HASH') {
                                                           %codedefaults = %{$gotcodedefaults{$udom}{'defaults'}};
                                                       }
                                                       if (ref($gotcodedefaults{$udom}{'order'}) eq 'ARRAY') {
                                                           @code_order = @{$gotcodedefaults{$udom}{'order'}};
                                                       }
                                                   } else {
                                                       &Apache::lonnet::auto_instcode_defaults($udom,
                                                                                               \%codedefaults,
                                                                                               \@code_order);
                                                       $gotcodedefaults{$udom}{'defaults'} = \%codedefaults;
                                                       $gotcodedefaults{$udom}{'order'} = \@code_order;
                                                   }
                                                   if (@code_order > 0) {
                                                       if (&Apache::lonnet::check_instcode_cloning(\%codedefaults,\@code_order,
                                                                                                   $cloner,$clonefromcode,$reqinstcode)) {
                                                           $canclone = 1;
                                                           last;
                                                       }
                                                   }
                                               }
                                           }
                                       }
                                   }
                               }
                           }
                       } elsif (defined($cloneruname)) {
                           if ($cc_clone{$unesc_key}) {
                               $canclone = 1;
                               $items->{'cloners'} = $cloneruname.':'.$clonerudom;
                               $valchange = 1;
                           }
                           unless ($canclone) {
                               if ($items->{'owner'} =~ /:/) {
                                   if ($items->{'owner'} eq $cloner) {
                                       $canclone = 1;
                                   }
                               } elsif ($cloner eq $items->{'owner'}.':'.$udom) {
                                   $canclone = 1;
                               }
                               if ($canclone) {
                                   $items->{'cloners'} = $cloneruname.':'.$clonerudom;
                                   $valchange = 1;
                               }
                           }
                       }
                       unless (($canclone) || ($items->{'cloners'})) {
                           my %domdefs = &Apache::lonnet::get_domain_defaults($udom);
                           if ($domdefs{'canclone'}) {
                               unless ($domdefs{'canclone'} eq 'none') {
                                   if ($domdefs{'canclone'} eq 'domain') {
                                       if ($clonerudom eq $udom) {
                                           $canclone = 1;
                                       }
                                   } elsif (($clonefromcode) && ($reqinstcode) &&
                                            ($udom eq $reqcrsdom)) {
                                       if (&Apache::lonnet::default_instcode_cloning($udom,$domdefs{'canclone'},
                                                                                     $clonefromcode,$reqinstcode)) {
                                           $canclone = 1;
                                       }
                                   }
                               }
                           }
                       }
                   }
                   if ($unpack || !$rtn_as_hash) {
                       $unesc_val{'descr'} = $items->{'description'};
                       $unesc_val{'inst_code'} = $items->{'inst_code'};
                       $unesc_val{'owner'} = $items->{'owner'};
                       $unesc_val{'type'} = $items->{'type'};
                       $unesc_val{'cloners'} = $items->{'cloners'};
                       $unesc_val{'created'} = $items->{'created'};
                       $unesc_val{'context'} = $items->{'context'};
                   }
                   $selfenroll_types = $items->{'selfenroll_types'};
                   $selfenroll_end = $items->{'selfenroll_end_date'};
                   $created = $items->{'created'};
                   $context = $items->{'context'};
                   if ($selfenrollonly) {
                       next if (!$selfenroll_types);
                       if (($selfenroll_end > 0) && ($selfenroll_end <= $now)) {
                           next;
                       }
                   }
                   if ($creationcontext ne '.') {
                       next if (($context ne '') && ($context ne $creationcontext));  
                   }
                   if ($createdbefore > 0) {
                       next if (($created eq '') || ($created > $createdbefore));   
                   }
                   if ($createdafter > 0) {
                       next if (($created eq '') || ($created <= $createdafter)); 
                   }
                   if ($catfilter ne '') {
                       next if ($items->{'categories'} eq '');
                       my @categories = split('&',$items->{'categories'}); 
                       next if (@categories == 0);
                       my @subcats = split('&',$catfilter);
                       my $matchcat = 0;
                       foreach my $cat (@categories) {
                           if (grep(/^\Q$cat\E$/,@subcats)) {
                               $matchcat = 1;
                               last;
                           }
                       }
                       next if (!$matchcat);
                   }
                   if ($caller eq 'coursecatalog') {
                       if ($items->{'hidefromcat'} eq 'yes') {
                           next if !$showhidden;
                       }
                   }
                   if ($hasuniquecode ne '.') {
                       next unless ($items->{'uniquecode'});
                   }
               } else {
                   next if ($catfilter ne '');
                   next if ($selfenrollonly);
                   next if ($createdbefore || $createdafter);
                   next if ($creationcontext ne '.');
                   if ((defined($clonerudom)) && (defined($cloneruname)))  {
                       if ($cc_clone{$unesc_key}) {
                           $canclone = 1;
                           $val{'cloners'} = &escape($cloneruname.':'.$clonerudom);
                       }
                   }
                   $is_hash =  0;
                   my @courseitems = split(/:/,$value);
                   $lasttime = pop(@courseitems);
                   if ($hashref->{$lasttime_key} eq '') {
                       next if ($lasttime<$since);
                   }
           ($val{'descr'},$val{'inst_code'},$val{'owner'},$val{'type'}) = @courseitems;
               }
               if ($cloneonly) {
                  next unless ($canclone);
               }
               my $match = 1;
       if ($description ne '.') {
                   if (!$is_hash) {
                       $unesc_val{'descr'} = &unescape($val{'descr'});
                   }
                   if (eval{$unesc_val{'descr'} !~ /\Q$description\E/i}) {
                       $match = 0;
                   }
               }
               if ($instcodefilter ne '.') {
                   if (!$is_hash) {
                       $unesc_val{'inst_code'} = &unescape($val{'inst_code'});
                   }
                   if ($regexp_ok == 1) {
                       if (eval{$unesc_val{'inst_code'} !~ /$instcodefilter/}) {
                           $match = 0;
                       }
                   } elsif ($regexp_ok == -1) {
                       if (eval{$unesc_val{'inst_code'} =~ /$instcodefilter/}) {
                           $match = 0;
                       }
                   } else {
                       if (eval{$unesc_val{'inst_code'} !~ /\Q$instcodefilter\E/i}) {
                           $match = 0;
                       }
                   }
       }
               if ($ownerfilter ne '.') {
                   if (!$is_hash) {
                       $unesc_val{'owner'} = &unescape($val{'owner'});
                   }
                   if (($ownerunamefilter ne '') && ($ownerdomfilter ne '')) {
                       if ($unesc_val{'owner'} =~ /:/) {
                           if (eval{$unesc_val{'owner'} !~ 
                                /\Q$ownerunamefilter\E:\Q$ownerdomfilter\E$/i}) {
                               $match = 0;
                           } 
                       } else {
                           if (eval{$unesc_val{'owner'} !~ /\Q$ownerunamefilter\E/i}) {
                               $match = 0;
                           }
                       }
                   } elsif ($ownerunamefilter ne '') {
                       if ($unesc_val{'owner'} =~ /:/) {
                           if (eval{$unesc_val{'owner'} !~ /\Q$ownerunamefilter\E:[^:]+$/i}) {
                                $match = 0;
                           }
                       } else {
                           if (eval{$unesc_val{'owner'} !~ /\Q$ownerunamefilter\E/i}) {
                               $match = 0;
                           }
                       }
                   } elsif ($ownerdomfilter ne '') {
                       if ($unesc_val{'owner'} =~ /:/) {
                           if (eval{$unesc_val{'owner'} !~ /^[^:]+:\Q$ownerdomfilter\E/}) {
                                $match = 0;
                           }
                       } else {
                           if ($ownerdomfilter ne $udom) {
                               $match = 0;
                           }
                       }
                   }
               }
               if ($coursefilter ne '.') {
                   if (eval{$unesc_key !~ /^$udom(_)\Q$coursefilter\E$/}) {
                       $match = 0;
                   }
               }
               if ($typefilter ne '.') {
                   if (!$is_hash) {
                       $unesc_val{'type'} = &unescape($val{'type'});
                   }
                   if ($unesc_val{'type'} eq '') {
                       if ($typefilter ne 'Course') {
                           $match = 0;
                       }
                   } else {
                       if (eval{$unesc_val{'type'} !~ /^\Q$typefilter\E$/}) {
                           $match = 0;
                       }
                   }
               }
               if ($match == 1) {
                   if ($rtn_as_hash) {
                       if ($is_hash) {
                           if ($valchange) {
                               my $newvalue = &Apache::lonnet::freeze_escape($items);
                               $qresult.=$key.'='.$newvalue.'&';
                           } else {
                               $qresult.=$key.'='.$value.'&';
                           }
                       } else {
                           my %rtnhash = ( 'description' => &unescape($val{'descr'}),
                                           'inst_code' => &unescape($val{'inst_code'}),
                                           'owner'     => &unescape($val{'owner'}),
                                           'type'      => &unescape($val{'type'}),
                                           'cloners'   => &unescape($val{'cloners'}),
                                         );
                           my $items = &Apache::lonnet::freeze_escape(\%rtnhash);
                           $qresult.=$key.'='.$items.'&';
                       }
                   } else {
                       if ($is_hash) {
                           $qresult .= $key.'='.&escape($unesc_val{'descr'}).':'.
                                       &escape($unesc_val{'inst_code'}).':'.
                                       &escape($unesc_val{'owner'}).'&';
                       } else {
                           $qresult .= $key.'='.$val{'descr'}.':'.$val{'inst_code'}.
                                       ':'.$val{'owner'}.'&';
                       }
                   }
               }
    }
       &untie_domain_hash($hashref) or 
           return "error: ".($!+0)." untie(GDBM) Failed while attempting courseiddump";
   
       chop($qresult);
       return $qresult;
   }
   
   sub dump_profile_database {
       my ($tail) = @_;
   
       my ($udom,$uname,$namespace) = split(/:/,$tail);
   
       my $hashref = &tie_user_hash($udom, $uname, $namespace, &GDBM_READER()) or
           return "error: ".($!+0)." tie(GDBM) Failed while attempting currentdump";
   
    # Structure of %data:
    # $data{$symb}->{$parameter}=$value;
    # $data{$symb}->{'v.'.$parameter}=$version;
    # since $parameter will be unescaped, we do not
     # have to worry about silly parameter names...
   
           my $qresult='';
    my %data = ();                     # A hash of anonymous hashes..
    while (my ($key,$value) = each(%$hashref)) {
       my ($v,$symb,$param) = split(/:/,$key);
       next if ($v eq 'version' || $symb eq 'keys');
       next if (exists($data{$symb}) && 
        exists($data{$symb}->{$param}) &&
        $data{$symb}->{'v.'.$param} > $v);
       $data{$symb}->{$param}=$value;
       $data{$symb}->{'v.'.$param}=$v;
    }
   
       &untie_user_hash($hashref) or
           return "error: ".($!+0)." untie(GDBM) Failed while attempting currentdump";
   
       while (my ($symb,$param_hash) = each(%data)) {
       while(my ($param,$value) = each (%$param_hash)){
           next if ($param =~ /^v\./);       # Ignore versions...
           #
           #   Just dump the symb=value pairs separated by &
           #
           $qresult.=$symb.':'.$param.'='.$value.'&';
       }
       }
   
       chop($qresult);
       return $qresult;
   }
   
   
 1;  1;
Line 363  Returns: 1 (Continue processing). Line 842  Returns: 1 (Continue processing).
   
 Side effects: response is written to $client.    Side effects: response is written to $client.  
   
   =item dump_course_id_handler
   
   #TODO copy from lond
   
   =item dump_profile_database
   
   #TODO copy from lond  
   
 =item releasereqd_check( $cnum, $cdom, $key, $value, $major, $minor,   =item releasereqd_check( $cnum, $cdom, $key, $value, $major, $minor, 
         $homecourses, $ids )          $homecourses, $ids )
Line 408  the version available on the client serv Line 894  the version available on the client serv
 is compatible, 1 will be returned.  is compatible, 1 will be returned.
   
   
   =item get_courseinfo_hash( $cnum, $cdom, $home )
   
   get_courseinfo_hash() is used to retrieve course information from the db
   file: nohist_courseids.db for a course for which the current server is *not*
   the home server.
   
   A hash of a hash will be retrieved. The outer hash contains a single key --
   courseID -- for the course for which the data are being requested.
   The contents of the inner hash, for that single item in the outer hash
   are returned (and cached in memcache for 10 minutes).
   
   
   
 =back  =back
   
 =head1 BUGS  =head1 BUGS

Removed from v.1.2  
changed lines
  Added in v.1.8


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>