--- loncom/metadata_database/searchcat.pl 2016/01/27 22:22:59 1.83 +++ loncom/metadata_database/searchcat.pl 2016/01/31 21:25:49 1.84 @@ -2,7 +2,7 @@ # The LearningOnline Network # searchcat.pl "Search Catalog" batch script # -# $Id: searchcat.pl,v 1.83 2016/01/27 22:22:59 raeburn Exp $ +# $Id: searchcat.pl,v 1.84 2016/01/31 21:25:49 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -273,19 +273,51 @@ foreach my $dom (@domains) { &portfolio_logging(%portmetalog); } } - my (%names_by_id,,%ids_by_name,%idstodelete,%idstoadd,%duplicates); + my %duplicates; + my %names_by_id = ( + id => {}, + clickers => {}, + ); + my %ids_by_name = ( + id => {}, + clickers => {}, + ); + my %idstodelete = ( + id => {}, + clickers => {}, + ); + my %idstoadd = ( + id => {}, + clickers => {}, + ); + my %namespace = ( + id => 'ids', + clickers => 'clickers', + ); + my %idtext = ( + id => 'employee/student IDs', + clickers => 'clicker IDs', + ); unless ($simulate || $oneuser) { - my $idshashref; - $idshashref = &tie_domain_hash($dom, "ids", &GDBM_WRCREAT()); - if (ref($idshashref) eq 'HASH') { - %names_by_id = %{$idshashref}; - while (my ($id,$uname) = each(%{$idshashref}) ) { - $id = &unescape($id); - $uname = &unescape($uname); - $names_by_id{$id} = $uname; - push(@{$ids_by_name{$uname}},$id); + foreach my $key ('id','clickers') { + my $hashref = &tie_domain_hash($dom,$namespace{$key},&GDBM_WRCREAT()); + if (ref($hashref) eq 'HASH') { + while (my ($id,$unamestr) = each(%{$hashref}) ) { + $id = &unescape($id); + $unamestr = &unescape($unamestr); + if ($key eq 'clickers') { + my @unames = split(/,/,$unamestr); + foreach my $uname (@unames) { + push(@{$ids_by_name{$key}{$uname}},$id); + } + $names_by_id{$key}{$id} = $unamestr; + } else { + $names_by_id{$key}{$id} = $unamestr; + push(@{$ids_by_name{$key}{$unamestr}},$id); + } + } + &untie_domain_hash($hashref); } - &untie_domain_hash($idshashref); } } # Update allusers @@ -293,36 +325,55 @@ foreach my $dom (@domains) { next if (exists($courses{$dom.'_'.$uname})); my %userdata = &Apache::lonnet::get('environment',['firstname','lastname', - 'middlename','generation','id','permanentemail'],$dom,$uname); + 'middlename','generation','id','permanentemail','clickers'], + $dom,$uname); unless ($simulate || $oneuser) { - my $addid; - if ($userdata{'id'} ne '') { - $addid = $userdata{'id'}; - $addid=~tr/A-Z/a-z/; - } - if (exists($ids_by_name{$uname})) { - if (ref($ids_by_name{$uname}) eq 'ARRAY') { - if (scalar(@{$ids_by_name{$uname}}) > 1) { - &log(0,"Multiple employee/student IDs found in ids.db for $uname:$dom -- ".join(', ',@{$ids_by_name{$uname}})); - } - foreach my $id (@{$ids_by_name{$uname}}) { - if ($id eq $userdata{'id'}) { - undef($addid); - } else { - $idstodelete{$id} = $uname; + foreach my $key ('id','clickers') { + my %addid = (); + if ($userdata{$key} ne '') { + my $idfromenv = $userdata{$key}; + if ($key eq 'id') { + $idfromenv=~tr/A-Z/a-z/; + $addid{$idfromenv} = 1; + } else { + $idfromenv =~ s/^\s+//; + $idfromenv =~ s/\s+$//; + map { $addid{$_} = 1; } split(/,/,$idfromenv); + } + } + if (ref($ids_by_name{$key}{$uname}) eq 'ARRAY') { + if (scalar(@{$ids_by_name{$key}{$uname}}) > 1) { + &log(0,"Multiple $idtext{$key} found in $namespace{$key}.db for $uname:$dom -- ". + join(', ',@{$ids_by_name{$key}{$uname}})); + } + foreach my $id (@{$ids_by_name{$key}{$uname}}) { + if ($addid{$id}) { + delete($addid{$id}); + } else { + if ($key eq 'id') { + $idstodelete{$key}{$id} = $uname; + } else { + $idstodelete{$key}{$id} .= $uname.','; + } } } } - } - if ($addid ne '') { - if (exists($idstoadd{$addid})) { - push(@{$duplicates{$addid}},$uname); - } else { - $idstoadd{$addid} = $uname; + if (keys(%addid)) { + foreach my $id (keys(%addid)) { + if ($key eq 'id') { + if (exists($idstoadd{$key}{$id})) { + push(@{$duplicates{$id}},$uname); + } else { + $idstoadd{$key}{$id} = $uname; + } + } else { + $idstoadd{$key}{$id} .= $uname.','; + } + } } } } - + $userdata{'username'} = $uname; $userdata{'domain'} = $dom; my %alluserslog = @@ -333,63 +384,87 @@ foreach my $dom (@domains) { } } unless ($simulate || $oneuser) { - if (keys(%idstodelete) > 0) { - my %resulthash = &Apache::lonnet::iddel($dom,\%idstodelete,$hostid); - if ($resulthash{$hostid} eq 'ok') { - foreach my $id (sort(keys(%idstodelete))) { - &log(0,"Record deleted from ids.db for $dom -- $id => ".$idstodelete{$id}); + foreach my $key ('id','clickers') { + if (keys(%{$idstodelete{$key}}) > 0) { + my %resulthash; + if ($key eq 'id') { + %resulthash = &Apache::lonnet::iddel($dom,$idstodelete{$key},$hostid,$namespace{$key}); + } else { + foreach my $delid (sort(keys(%{$idstodelete{$key}}))) { + $idstodelete{$key}{$delid} =~ s/,$//; + } + %resulthash = &Apache::lonnet::iddel($dom,$idstodelete{$key},$hostid,$namespace{$key}); } - } else { - &log(0,"Error: '$resulthash{$hostid}' occurred when attempting to delete records from ids.db for $dom"); - } - } - if (keys(%idstoadd) > 0) { - my $idmessage = ''; - my %newids; - foreach my $addid (sort(keys(%idstoadd))) { - if ((exists($names_by_id{$addid})) && ($names_by_id{$addid} ne $idstoadd{$addid}) && !($idstodelete{$addid})) { - &log(0,"Two usernames associated with a single ID $addid in domain: $dom: $names_by_id{$addid} (current) and $idstoadd{$addid}\n"); - $idmessage .= "$addid,$names_by_id{$addid},$idstoadd{$addid}\n"; + if ($resulthash{$hostid} eq 'ok') { + foreach my $id (sort(keys(%{$idstodelete{$key}}))) { + &log(0,"Record deleted from $namespace{$key}.db for $dom -- $id => ".$idstodelete{$key}{$id}); + } } else { - $newids{$addid} = $idstoadd{$addid}; + &log(0,"Error: '$resulthash{$hostid}' occurred when attempting to delete records from $namespace{$key}.db for $dom"); } } - if (keys(%newids) > 0) { - my $putresult = &Apache::lonnet::put_dom('ids',\%idstoadd,$dom,$hostid); - if ($putresult eq 'ok') { - foreach my $id (sort(keys(%idstoadd))) { - &log(0,"Record added to ids.db for $dom -- $id => ".$idstoadd{$id}); + if (keys(%{$idstoadd{$key}}) > 0) { + my $idmessage = ''; + my %newids; + if ($key eq 'id') { + foreach my $addid (sort(keys(%{$idstoadd{$key}}))) { + if ((exists($names_by_id{$key}{$addid})) && ($names_by_id{$key}{$addid} ne $idstoadd{$key}{$addid}) && !($idstodelete{$key}{$addid})) { + &log(0,"Two usernames associated with a single ID $addid in domain: $dom: $names_by_id{$key}{$addid} (current) and $idstoadd{$key}{$addid}\n"); + $idmessage .= "$addid,$names_by_id{$key}{$addid},$idstoadd{$key}{$addid}\n"; + } else { + $newids{$addid} = $idstoadd{$key}{$addid}; + } } } else { - &log(0,"Error: '$putresult' occurred when attempting to add records to ids.db for $dom"); + foreach my $addid (sort(keys(%{$idstoadd{$key}}))) { + $idstoadd{$key}{$addid} =~ s/,$//; + $newids{$addid} = $idstoadd{$key}{$addid}; + } } - } - if ($idmessage) { - my $to = &Apache::loncommon::build_recipient_list(undef,'idconflictsmail',$dom); - if ($to ne '') { - my $msg = new Mail::Send; - $msg->to($to); - $msg->subject('LON-CAPA studentIDs conflict'); - my $lonhost = $Apache::lonnet::perlvar{'lonHostID'}; - my $hostname = &Apache::lonnet::hostname($lonhost); - my $replytoaddress = 'do-not-reply@'.$hostname; - $msg->add('Reply-to',$replytoaddress); - $msg->add('From','www@'.$hostname); - $msg->add('Content-type','text/plain; charset=UTF-8'); - if (my $fh = $msg->open()) { - print $fh - 'The following IDs are used for more than one user in your domain:'."\n". - 'Each row contains: Student/Employee ID, Current username in ids.db file, '. - 'Additional username'."\n\n". - $idmessage; - $fh->close; + if (keys(%newids) > 0) { + my $putresult; + if ($key eq 'clickers') { + $putresult = &Apache::lonnet::updateclickers($dom,'add',\%newids,$hostid); + } else { + $putresult = &Apache::lonnet::put_dom($namespace{$key},\%newids,$dom,$hostid); + } + if ($putresult eq 'ok') { + foreach my $id (sort(keys(%newids))) { + &log(0,"Record added to $namespace{$key}.db for $dom -- $id => ".$newids{$id}); + } + } else { + &log(0,"Error: '$putresult' occurred when attempting to add records to $namespace{$key}.db for $dom"); + } + } + if ($idmessage) { + my $to = &Apache::loncommon::build_recipient_list(undef,'idconflictsmail',$dom); + if ($to ne '') { + my $msg = new Mail::Send; + $msg->to($to); + $msg->subject('LON-CAPA studentIDs conflict'); + my $lonhost = $Apache::lonnet::perlvar{'lonHostID'}; + my $hostname = &Apache::lonnet::hostname($lonhost); + my $replytoaddress = 'do-not-reply@'.$hostname; + $msg->add('Reply-to',$replytoaddress); + $msg->add('From','www@'.$hostname); + $msg->add('Content-type','text/plain; charset=UTF-8'); + if (my $fh = $msg->open()) { + print $fh + 'The following IDs are used for more than one user in your domain:'."\n". + 'Each row contains: Student/Employee ID, Current username in ids.db file, '. + 'Additional username'."\n\n". + $idmessage; + $fh->close; + } } } } } if (keys(%duplicates) > 0) { foreach my $id (sort(keys(%duplicates))) { - &log(0,"Duplicate IDs found for entries to add to ids.db in $dom -- $id => $idstodelete{$id}"); + if (ref($duplicates{$id}) eq 'ARRAY') { + &log(0,"Duplicate IDs found for entries to add to ids.db in $dom -- $id => ".join(',',@{$duplicates{$id}})); + } } } }