version 1.2, 2012/04/26 19:51:40
|
version 1.5, 2013/07/24 18:21:52
|
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) = 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 = '.'; |
|
} |
|
my $unpack = 1; |
|
if ($description eq '.' && $instcodefilter eq '.' && $ownerfilter eq '.' && |
|
$typefilter eq '.') { |
|
$unpack = 0; |
|
} |
|
if (!defined($since)) { $since=0; } |
|
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); |
|
my $items = &Apache::lonnet::thaw_unescape($value); |
|
if (ref($items) eq 'HASH') { |
|
if ($hashref->{$lasttime_key} eq '') { |
|
next if ($since > 1); |
|
} |
|
$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; |
|
} |
|
} |
|
} |
|
} 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; |
|
} |
|
} |
|
} |
|
} |
|
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; |
|
} |
|
} |
|
} 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 776 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 828 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 |