--- loncom/interface/loncommon.pm 2020/07/17 22:17:17 1.1075.2.127.2.11
+++ loncom/interface/loncommon.pm 2018/09/02 21:21:17 1.1075.2.128
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.1075.2.127.2.11 2020/07/17 22:17:17 raeburn Exp $
+# $Id: loncommon.pm,v 1.1075.2.128 2018/09/02 21:21:17 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -82,8 +82,6 @@ use Crypt::DES;
use DynaLoader; # for Crypt::DES version
use File::Copy();
use File::Path();
-use String::CRC32();
-use Short::URL();
# ---------------------------------------------- Designs
use vars qw(%defaultdesign);
@@ -4616,8 +4614,7 @@ sub blockcheck {
# boards, chat or groups, check for blocking in current course only.
if (($activity eq 'boards' || $activity eq 'chat' ||
- $activity eq 'groups' || $activity eq 'printout' ||
- $activity eq 'reinit' || $activity eq 'alert') &&
+ $activity eq 'groups' || $activity eq 'printout') &&
($env{'request.course.id'})) {
foreach my $key (keys(%live_courses)) {
if ($key ne $env{'request.course.id'}) {
@@ -4723,7 +4720,7 @@ sub blockcheck {
($env{'request.role'} !~ m{^st\./\Q$cdom\E/\Q$cnum\E}));
next if ($no_userblock);
- # Retrieve blocking times and identity of locker for course
+ # Retrieve blocking times and identity of blocker for course
# of specified user, unless user has 'evb' privilege.
my ($start,$end,$trigger) =
@@ -4928,10 +4925,6 @@ END_MYBLOCK
$text = &mt('Printing Blocked');
} elsif ($activity eq 'passwd') {
$text = &mt('Password Changing Blocked');
- } elsif ($activity eq 'alert') {
- $text = &mt('Checking Critical Messages Blocked');
- } elsif ($activity eq 'reinit') {
- $text = &mt('Checking Course Update Blocked');
}
$output .= <<"END_BLOCK";
@@ -5001,87 +4994,6 @@ sub check_ip_acc {
return $allowed;
}
-sub check_slotip_acc {
- my ($acc,$clientip)=@_;
- &Apache::lonxml::debug("acc is $acc");
- if (!defined($acc) || $acc =~ /^\s*$/ || $acc =~/^\s*no\s*$/i) {
- return 1;
- }
- my $allowed;
- my $ip=$ENV{'REMOTE_ADDR'} || $clientip || $env{'request.host'};
-
- my $name;
- my %access = (
- allowfrom => 1,
- denyfrom => 0,
- );
- my @allows;
- my @denies;
- foreach my $item (split(',',$acc)) {
- $item =~ s/^\s*//;
- $item =~ s/\s*$//;
- my $pattern;
- if ($item =~ /^\!(.+)$/) {
- push(@denies,$1);
- } else {
- push(@allows,$item);
- }
- }
- my $numdenies = scalar(@denies);
- my $numallows = scalar(@allows);
- my $count = 0;
- foreach my $pattern (@denies,@allows) {
- $count ++;
- my $acctype = 'allowfrom';
- if ($count <= $numdenies) {
- $acctype = 'denyfrom';
- }
- if ($pattern =~ /\*$/) {
- #35.8.*
- $pattern=~s/\*//;
- if ($ip =~ /^\Q$pattern\E/) { $allowed=$access{$acctype}; }
- } elsif ($pattern =~ /(\d+\.\d+\.\d+)\.\[(\d+)-(\d+)\]$/) {
- #35.8.3.[34-56]
- my $low=$2;
- my $high=$3;
- $pattern=$1;
- if ($ip =~ /^\Q$pattern\E/) {
- my $last=(split(/\./,$ip))[3];
- if ($last <=$high && $last >=$low) { $allowed=$access{$acctype}; }
- }
- } elsif ($pattern =~ /^\*/) {
- #*.msu.edu
- $pattern=~s/\*//;
- if (!defined($name)) {
- use Socket;
- my $netaddr=inet_aton($ip);
- ($name)=gethostbyaddr($netaddr,AF_INET);
- }
- if ($name =~ /\Q$pattern\E$/i) { $allowed=$access{$acctype}; }
- } elsif ($pattern =~ /\d+\.\d+\.\d+\.\d+/) {
- #127.0.0.1
- if ($ip =~ /^\Q$pattern\E/) { $allowed=$access{$acctype}; }
- } else {
- #some.name.com
- if (!defined($name)) {
- use Socket;
- my $netaddr=inet_aton($ip);
- ($name)=gethostbyaddr($netaddr,AF_INET);
- }
- if ($name =~ /\Q$pattern\E$/i) { $allowed=$access{$acctype}; }
- }
- if ($allowed =~ /^(0|1)$/) { last; }
- }
- if ($allowed eq '') {
- if ($numdenies && !$numallows) {
- $allowed = 1;
- } else {
- $allowed = 0;
- }
- }
- return $allowed;
-}
-
###############################################
=pod
@@ -12193,8 +12105,7 @@ sub process_decompression {
if (ref($newdirlistref) eq 'ARRAY') {
foreach my $dir_line (@{$newdirlistref}) {
my ($item,undef,undef,$testdir)=split(/\&/,$dir_line,5);
- unless (($item =~ /^\.+$/) || ($item eq $file) ||
- ((@to_skip > 0) && (grep(/^\Q$item\E$/,@to_skip)))) {
+ unless (($item =~ /^\.+$/) || ($item eq $file)) {
push(@newitems,$item);
if ($dirptr&$testdir) {
$is_dir{$item} = 1;
@@ -12782,7 +12693,7 @@ sub process_extracted_files {
$newseqid{$i} = $newidx;
unless ($errtext) {
$result .= '
'.&mt('Folder: [_1] added to course',
- &HTML::Entities::encode($docstitle,'<>&"')).
+ &HTML::Entities::encode($docstitle,'<>&"'))..
''."\n";
}
}
@@ -12807,7 +12718,7 @@ sub process_extracted_files {
$fetch =~ s/^\Q$prefix$dir\E//;
$prompttofetch{$fetch} = 1;
}
- }
+ }
}
$LONCAPA::map::resources[$newidx]=
$docstitle.':'.$url.':false:normal:res';
@@ -12907,11 +12818,11 @@ sub process_extracted_files {
$result .= ''.&mt('[_1] included as a dependency',
&HTML::Entities::encode($showpath,'<>&"')).
''."\n";
- }
- unless ($ishome) {
- my $fetch = "$fullpath/$title";
- $fetch =~ s/^\Q$prefix$dir\E//;
- $prompttofetch{$fetch} = 1;
+ unless ($ishome) {
+ my $fetch = "$fullpath/$title";
+ $fetch =~ s/^\Q$prefix$dir\E//;
+ $prompttofetch{$fetch} = 1;
+ }
}
}
}
@@ -13198,9 +13109,10 @@ sub upfile_store {
$env{'form.upfile'}=~s/\n+$//gs;
my $datatoken = &valid_datatoken($env{'user.name'}.'_'.$env{'user.domain'}.
- '_enroll_'.$env{'request.course.id'}.'_'.
+ '_enroll_'.$env{'request.course.id'}.'_'.
time.'_'.$$);
return if ($datatoken eq '');
+
{
my $datafile = $r->dir_config('lonDaemons').
'/tmp/'.$datatoken.'.tmp';
@@ -13239,7 +13151,7 @@ sub load_tmp_file {
sub valid_datatoken {
my ($datatoken) = @_;
- if ($datatoken =~ /^$match_username\_$match_domain\_enroll_(|$match_domain\_$match_courseid)\_\d+_\d+$/) {
+ if ($datatoken =~ /^$match_username\_$match_domain\_enroll_$match_domain\_$match_courseid\_\d+_\d+$/) {
return $datatoken;
}
return;
@@ -14133,13 +14045,6 @@ defdom (domain for which to retrieve con
origmail (scalar - email address of recipient from loncapa.conf,
i.e., predates configuration by DC via domainprefs.pm
-$requname username of requester (if mailing type is helpdeskmail)
-
-$requdom domain of requester (if mailing type is helpdeskmail)
-
-$reqemail e-mail address of requester (if mailing type is helpdeskmail)
-
-
Returns: comma separated list of addresses to which to send e-mail.
=back
@@ -14149,7 +14054,7 @@ Returns: comma separated list of address
############################################################
############################################################
sub build_recipient_list {
- my ($defmail,$mailing,$defdom,$origmail,$requname,$requdom,$reqemail) = @_;
+ my ($defmail,$mailing,$defdom,$origmail) = @_;
my @recipients;
my ($otheremails,$lastresort,$allbcc,$addtext);
my %domconfig =
@@ -14190,94 +14095,6 @@ sub build_recipient_list {
} elsif ($origmail ne '') {
$lastresort = $origmail;
}
- if ($mailing eq 'helpdeskmail') {
- if ((ref($domconfig{'contacts'}{'overrides'}) eq 'HASH') &&
- (keys(%{$domconfig{'contacts'}{'overrides'}}))) {
- my ($inststatus,$inststatus_checked);
- if (($env{'user.name'} ne '') && ($env{'user.domain'} ne '') &&
- ($env{'user.domain'} ne 'public')) {
- $inststatus_checked = 1;
- $inststatus = $env{'environment.inststatus'};
- }
- unless ($inststatus_checked) {
- if (($requname ne '') && ($requdom ne '')) {
- if (($requname =~ /^$match_username$/) &&
- ($requdom =~ /^$match_domain$/) &&
- (&Apache::lonnet::domain($requdom))) {
- my $requhome = &Apache::lonnet::homeserver($requname,
- $requdom);
- unless ($requhome eq 'no_host') {
- my %userenv = &Apache::lonnet::userenvironment($requdom,$requname,'inststatus');
- $inststatus = $userenv{'inststatus'};
- $inststatus_checked = 1;
- }
- }
- }
- }
- unless ($inststatus_checked) {
- if ($reqemail =~ /^[^\@]+\@[^\@]+$/) {
- my %srch = (srchby => 'email',
- srchdomain => $defdom,
- srchterm => $reqemail,
- srchtype => 'exact');
- my %srch_results = &Apache::lonnet::usersearch(\%srch);
- foreach my $uname (keys(%srch_results)) {
- if (ref($srch_results{$uname}{'inststatus'}) eq 'ARRAY') {
- $inststatus = join(',',@{$srch_results{$uname}{'inststatus'}});
- $inststatus_checked = 1;
- last;
- }
- }
- unless ($inststatus_checked) {
- my ($dirsrchres,%srch_results) = &Apache::lonnet::inst_directory_query(\%srch);
- if ($dirsrchres eq 'ok') {
- foreach my $uname (keys(%srch_results)) {
- if (ref($srch_results{$uname}{'inststatus'}) eq 'ARRAY') {
- $inststatus = join(',',@{$srch_results{$uname}{'inststatus'}});
- $inststatus_checked = 1;
- last;
- }
- }
- }
- }
- }
- }
- if ($inststatus ne '') {
- foreach my $status (split(/\:/,$inststatus)) {
- if (ref($domconfig{'contacts'}{'overrides'}{$status}) eq 'HASH') {
- my @contacts = ('adminemail','supportemail');
- foreach my $item (@contacts) {
- if ($domconfig{'contacts'}{'overrides'}{$status}{$item}) {
- my $addr = $domconfig{'contacts'}{'overrides'}{$status};
- if (!grep(/^\Q$addr\E$/,@recipients)) {
- push(@recipients,$addr);
- }
- }
- }
- $otheremails = $domconfig{'contacts'}{'overrides'}{$status}{'others'};
- if ($domconfig{'contacts'}{'overrides'}{$status}{'bcc'}) {
- my @bccs = split(/,/,$domconfig{'contacts'}{'overrides'}{$status}{'bcc'});
- my @ok_bccs;
- foreach my $bcc (@bccs) {
- $bcc =~ s/^\s+//g;
- $bcc =~ s/\s+$//g;
- if ($bcc =~ m/^[^\@]+\@[^\@]+$/) {
- if (!(grep(/^\Q$bcc\E$/,@ok_bccs))) {
- push(@ok_bccs,$bcc);
- }
- }
- }
- if (@ok_bccs > 0) {
- $allbcc = join(', ',@ok_bccs);
- }
- }
- $addtext = $domconfig{'contacts'}{'overrides'}{$status}{'include'};
- last;
- }
- }
- }
- }
- }
} elsif ($origmail ne '') {
$lastresort = $origmail;
}
@@ -14934,8 +14751,7 @@ sub check_clone {
my $cloneid='/'.$args->{'clonedomain'}.'/'.$args->{'clonecourse'};
my ($clonecrsudom,$clonecrsunum)= &LONCAPA::split_courseid($cloneid);
my $clonehome=&Apache::lonnet::homeserver($clonecrsunum,$clonecrsudom);
- my $clonetitle;
- my @clonemsg;
+ my $clonemsg;
my $can_clone = 0;
my $lctype = lc($args->{'crstype'});
if ($lctype ne 'community') {
@@ -14943,38 +14759,16 @@ sub check_clone {
}
if ($clonehome eq 'no_host') {
if ($args->{'crstype'} eq 'Community') {
- push(@clonemsg,({
- mt => 'No new community created.',
- args => [],
- },
- {
- mt => 'A new community could not be cloned from the specified original - [_1] - because it is a non-existent community.',
- args => [$args->{'clonedomain'}.':'.$args->{'clonedomain'}],
- }));
+ $clonemsg = &mt('No new community created.').$linefeed.&mt('A new community could not be cloned from the specified original - [_1] - because it is a non-existent community.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
} else {
- push(@clonemsg,({
- mt => 'No new course created.',
- args => [],
- },
- {
- mt => 'A new course could not be cloned from the specified original - [_1] - because it is a non-existent course.',
- args => [$args->{'clonecourse'}.':'.$args->{'clonedomain'}],
- }));
- }
+ $clonemsg = &mt('No new course created.').$linefeed.&mt('A new course could not be cloned from the specified original - [_1] - because it is a non-existent course.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
+ }
} else {
my %clonedesc = &Apache::lonnet::coursedescription($cloneid,{'one_time' => 1});
- $clonetitle = $clonedesc{'description'};
if ($args->{'crstype'} eq 'Community') {
if ($clonedesc{'type'} ne 'Community') {
- push(@clonemsg,({
- mt => 'No new community created.',
- args => [],
- },
- {
- mt => 'A new community could not be cloned from the specified original - [_1] - because it is a course not a community.',
- args => [$args->{'clonecourse'}.':'.$args->{'clonedomain'}],
- }));
- return ($can_clone,\@clonemsg,$cloneid,$clonehome);
+ $clonemsg = &mt('No new community created.').$linefeed.&mt('A new community could not be cloned from the specified original - [_1] - because it is a course not a community.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
+ return ($can_clone, $clonemsg, $cloneid, $clonehome);
}
}
if (($env{'request.role.domain'} eq $args->{'clonedomain'}) &&
@@ -15063,34 +14857,20 @@ sub check_clone {
}
unless ($can_clone) {
if ($args->{'crstype'} eq 'Community') {
- push(@clonemsg,({
- mt => 'No new community created.',
- args => [],
- },
- {
- mt => 'The new community could not be cloned from the existing community because the new community owner ([_1]) does not have cloning rights in the existing community ([_2]).',
- args => [$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'}],
- }));
+ $clonemsg = &mt('No new community created.').$linefeed.&mt('The new community could not be cloned from the existing community because the new community owner ([_1]) does not have cloning rights in the existing community ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
} else {
- push(@clonemsg,({
- mt => 'No new course created.',
- args => [],
- },
- {
- mt => 'The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).',
- args => [$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'}],
- }));
- }
+ $clonemsg = &mt('No new course created.').$linefeed.&mt('The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
+ }
}
}
}
- return ($can_clone,\@clonemsg,$cloneid,$clonehome,$clonetitle);
+ return ($can_clone, $clonemsg, $cloneid, $clonehome);
}
sub construct_course {
my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname,$context,
- $cnum,$category,$coderef,$callercontext,$user_lh) = @_;
- my ($outcome,$msgref,$clonemsgref);
+ $cnum,$category,$coderef) = @_;
+ my $outcome;
my $linefeed = '
'."\n";
if ($context eq 'auto') {
$linefeed = "\n";
@@ -15099,11 +14879,18 @@ sub construct_course {
#
# Are we cloning?
#
- my ($can_clone,$cloneid,$clonehome,$clonetitle);
+ my ($can_clone, $clonemsg, $cloneid, $clonehome);
if (($args->{'clonecourse'}) && ($args->{'clonedomain'})) {
- ($can_clone,$clonemsgref,$cloneid,$clonehome,$clonetitle) = &check_clone($args,$linefeed);
+ ($can_clone, $clonemsg, $cloneid, $clonehome) = &check_clone($args,$linefeed);
+ if ($context ne 'auto') {
+ if ($clonemsg ne '') {
+ $clonemsg = ''.$clonemsg.'';
+ }
+ }
+ $outcome .= $clonemsg.$linefeed;
+
if (!$can_clone) {
- return (0,$outcome,$clonemsgref);
+ return (0,$outcome);
}
}
@@ -15121,20 +14908,15 @@ sub construct_course {
$args->{'ccuname'}.':'.
$args->{'ccdomain'},
$args->{'crstype'},
- $cnum,$context,$category,
- $callercontext);
+ $cnum,$context,$category);
# Note: The testing routines depend on this being output; see
# Utils::Course. This needs to at least be output as a comment
# if anyone ever decides to not show this, and Utils::Course::new
# will need to be suitably modified.
- if (($callercontext eq 'auto') && ($user_lh ne '')) {
- $outcome .= &mt_user($user_lh,'New LON-CAPA [_1] ID: [_2]',$crstype,$$courseid).$linefeed;
- } else {
- $outcome .= &mt('New LON-CAPA [_1] ID: [_2]',$crstype,$$courseid).$linefeed;
- }
+ $outcome .= &mt('New LON-CAPA [_1] ID: [_2]',$crstype,$$courseid).$linefeed;
if ($$courseid =~ /^error:/) {
- return (0,$outcome,$clonemsgref);
+ return (0,$outcome);
}
#
@@ -15143,37 +14925,23 @@ sub construct_course {
($$crsudom,$$crsunum)= &LONCAPA::split_courseid($$courseid);
my $crsuhome=&Apache::lonnet::homeserver($$crsunum,$$crsudom);
if ($crsuhome eq 'no_host') {
- if (($callercontext eq 'auto') && ($user_lh ne '')) {
- $outcome .= &mt_user($user_lh,
- 'Course creation failed, unrecognized course home server.');
- } else {
- $outcome .= &mt('Course creation failed, unrecognized course home server.');
- }
- $outcome .= $linefeed;
- return (0,$outcome,$clonemsgref);
+ $outcome .= &mt('Course creation failed, unrecognized course home server.').$linefeed;
+ return (0,$outcome);
}
$outcome .= &mt('Created on').': '.$crsuhome.$linefeed;
#
# Do the cloning
#
- my @clonemsg;
if ($can_clone && $cloneid) {
- push(@clonemsg,
- {
- mt => 'Created [_1] by cloning from [_2]',
- args => [$crstype,$clonetitle],
- });
+ $clonemsg = &mt('Cloning [_1] from [_2]',$crstype,$clonehome);
+ if ($context ne 'auto') {
+ $clonemsg = ''.$clonemsg.'';
+ }
+ $outcome .= $clonemsg.$linefeed;
my %oldcenv=&Apache::lonnet::dump('environment',$$crsudom,$$crsunum);
# Copy all files
- my @info =
- &Apache::lonclonecourse::copycoursefiles($cloneid,$$courseid,$args->{'datemode'},
- $args->{'dateshift'},$args->{'crscode'},
- $args->{'ccuname'}.':'.$args->{'ccdomain'},
- $args->{'tinyurls'});
- if (@info) {
- push(@clonemsg,@info);
- }
+ &Apache::lonclonecourse::copycoursefiles($cloneid,$$courseid,$args->{'datemode'},$args->{'dateshift'});
# Restore URL
$cenv{'url'}=$oldcenv{'url'};
# Restore title
@@ -15475,7 +15243,7 @@ sub construct_course {
$outcome .= ($fatal?$errtext:'write ok').$linefeed;
}
- return (1,$outcome,\@clonemsg);
+ return (1,$outcome);
}
sub make_unique_code {
@@ -15714,7 +15482,8 @@ sub init_user_environment {
my %userenv = &Apache::lonnet::dump('environment',$domain,$username);
my ($tmp) = keys(%userenv);
- if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
+ if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
+ } else {
undef(%userenv);
}
if (($userenv{'interface'}) && (!$form->{'interface'})) {
@@ -16607,12 +16376,8 @@ sub needs_coursereinit {
$interval = 600;
}
if (($now-$env{'request.course.timechecked'})>$interval) {
- &Apache::lonnet::appenv({'request.course.timechecked'=>$now});
- my $blocked = &blocking_status('reinit',$cnum,$cdom,undef,1);
- if ($blocked) {
- return ();
- }
my $lastchange = &Apache::lonnet::get_coursechange($cdom,$cnum);
+ &Apache::lonnet::appenv({'request.course.timechecked'=>$now});
if ($lastchange > $env{'request.course.tied'}) {
my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired');
if ($curr_reqd_hash{'internal.releaserequired'} ne '') {
@@ -17047,25 +16812,9 @@ sub cleanup_html {
# Checks for critical messages and returns a redirect url if one exists.
# $interval indicates how often to check for messages.
-# $context is the calling context -- roles, grades, contents, menu or flip.
sub critical_redirect {
- my ($interval,$context) = @_;
+ my ($interval) = @_;
if ((time-$env{'user.criticalcheck.time'})>$interval) {
- if (($env{'request.course.id'}) && (($context eq 'flip') || ($context eq 'contents'))) {
- my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
- my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- my $blocked = &blocking_status('alert',$cnum,$cdom,undef,1);
- if ($blocked) {
- my $checkrole = "cm./$cdom/$cnum";
- if ($env{'request.course.sec'} ne '') {
- $checkrole .= "/$env{'request.course.sec'}";
- }
- unless ((&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) &&
- ($env{'request.role'} !~ m{^st\./$cdom/$cnum})) {
- return;
- }
- }
- }
my @what=&Apache::lonnet::dump('critical', $env{'user.domain'},
$env{'user.name'});
&Apache::lonnet::appenv({'user.criticalcheck.time'=>time});
@@ -17131,157 +16880,6 @@ sub des_decrypt {
return $plaintext;
}
-sub get_requested_shorturls {
- my ($cdom,$cnum,$navmap) = @_;
- return unless (ref($navmap));
- my ($numnew,$errors);
- my @toshorten = &Apache::loncommon::get_env_multiple('form.addtiny');
- if (@toshorten) {
- my (%maps,%resources,%titles);
- &Apache::loncourserespicker::enumerate_course_contents($navmap,\%maps,\%resources,\%titles,
- 'shorturls',$cdom,$cnum);
- if (keys(%resources)) {
- my %tocreate;
- foreach my $item (sort {$a <=> $b} (@toshorten)) {
- my $symb = $resources{$item};
- if ($symb) {
- $tocreate{$cnum.'&'.$symb} = 1;
- }
- }
- if (keys(%tocreate)) {
- ($numnew,$errors) = &make_short_symbs($cdom,$cnum,
- \%tocreate);
- }
- }
- }
- return ($numnew,$errors);
-}
-
-sub make_short_symbs {
- my ($cdom,$cnum,$tocreateref,$lockuser) = @_;
- my ($numnew,@errors);
- if (ref($tocreateref) eq 'HASH') {
- my %tocreate = %{$tocreateref};
- if (keys(%tocreate)) {
- my %coursetiny = &Apache::lonnet::dump('tiny',$cdom,$cnum);
- my $su = Short::URL->new(no_vowels => 1);
- my $init = '';
- my (%newunique,%addcourse,%courseonly,%failed);
- # get lock on tiny db
- my $now = time;
- if ($lockuser eq '') {
- $lockuser = $env{'user.name'}.':'.$env{'user.domain'};
- }
- my $lockhash = {
- "lock\0$now" => $lockuser,
- };
- my $tries = 0;
- my $gotlock = &Apache::lonnet::newput_dom('tiny',$lockhash,$cdom);
- my ($code,$error);
- while (($gotlock ne 'ok') && ($tries<3)) {
- $tries ++;
- sleep 1;
- $gotlock = &Apache::lonnet::newput_dom('tiny',$lockhash,$cdom);
- }
- if ($gotlock eq 'ok') {
- $init = &shorten_symbs($cdom,$init,$su,\%coursetiny,\%tocreate,\%newunique,
- \%addcourse,\%courseonly,\%failed);
- if (keys(%failed)) {
- my $numfailed = scalar(keys(%failed));
- push(@errors,&mt('error: could not obtain unique six character URL for [quant,_1,resource]',$numfailed));
- }
- if (keys(%newunique)) {
- my $putres = &Apache::lonnet::newput_dom('tiny',\%newunique,$cdom);
- if ($putres eq 'ok') {
- $numnew = scalar(keys(%newunique));
- my $newputres = &Apache::lonnet::newput('tiny',\%addcourse,$cdom,$cnum);
- unless ($newputres eq 'ok') {
- push(@errors,&mt('error: could not store course look-up of short URLs'));
- }
- } else {
- push(@errors,&mt('error: could not store unique six character URLs'));
- }
- }
- my $dellockres = &Apache::lonnet::del_dom('tiny',["lock\0$now"],$cdom);
- unless ($dellockres eq 'ok') {
- push(@errors,&mt('error: could not release lockfile'));
- }
- } else {
- push(@errors,&mt('error: could not obtain lockfile'));
- }
- if (keys(%courseonly)) {
- my $result = &Apache::lonnet::newput('tiny',\%courseonly,$cdom,$cnum);
- if ($result ne 'ok') {
- push(@errors,&mt('error: could not update course look-up of short URLs'));
- }
- }
- }
- }
- return ($numnew,\@errors);
-}
-
-sub shorten_symbs {
- my ($cdom,$init,$su,$coursetiny,$tocreate,$newunique,$addcourse,$courseonly,$failed) = @_;
- return unless ((ref($su)) && (ref($coursetiny) eq 'HASH') && (ref($tocreate) eq 'HASH') &&
- (ref($newunique) eq 'HASH') && (ref($addcourse) eq 'HASH') &&
- (ref($courseonly) eq 'HASH') && (ref($failed) eq 'HASH'));
- my (%possibles,%collisions);
- foreach my $key (keys(%{$tocreate})) {
- my $num = String::CRC32::crc32($key);
- my $tiny = $su->encode($num,$init);
- if ($tiny) {
- $possibles{$tiny} = $key;
- }
- }
- if (!$init) {
- $init = 1;
- } else {
- $init ++;
- }
- if (keys(%possibles)) {
- my @posstiny = keys(%possibles);
- my $configuname = &Apache::lonnet::get_domainconfiguser($cdom);
- my %currtiny = &Apache::lonnet::get('tiny',\@posstiny,$cdom,$configuname);
- if (keys(%currtiny)) {
- foreach my $key (keys(%currtiny)) {
- next if ($currtiny{$key} eq '');
- if ($currtiny{$key} eq $possibles{$key}) {
- my ($tcnum,$tsymb) = split(/\&/,$currtiny{$key});
- unless (($coursetiny->{$tsymb} eq $key) || ($addcourse->{$tsymb} eq $key) || ($courseonly->{$tsymb} eq $key)) {
- $courseonly->{$tsymb} = $key;
- }
- } else {
- $collisions{$possibles{$key}} = 1;
- }
- delete($possibles{$key});
- }
- }
- foreach my $key (keys(%possibles)) {
- $newunique->{$key} = $possibles{$key};
- my ($tcnum,$tsymb) = split(/\&/,$possibles{$key});
- unless (($coursetiny->{$tsymb} eq $key) || ($addcourse->{$tsymb} eq $key) || ($courseonly->{$tsymb} eq $key)) {
- $addcourse->{$tsymb} = $key;
- }
- }
- }
- if (keys(%collisions)) {
- if ($init <5) {
- if (!$init) {
- $init = 1;
- } else {
- $init ++;
- }
- $init = &shorten_symbs($cdom,$init,$su,$coursetiny,\%collisions,
- $newunique,$addcourse,$courseonly,$failed);
- } else {
- foreach my $key (keys(%collisions)) {
- $failed->{$key} = 1;
- }
- }
- }
- return $init;
-}
-
1;
__END__;