--- loncom/interface/groupsort.pm 2005/06/09 22:06:09 1.33 +++ loncom/interface/groupsort.pm 2009/03/13 15:39:43 1.65 @@ -2,7 +2,7 @@ # The LON-CAPA group sort handler # Allows for sorting prior to import into RAT. # -# $Id: groupsort.pm,v 1.33 2005/06/09 22:06:09 www Exp $ +# $Id: groupsort.pm,v 1.65 2009/03/13 15:39:43 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -37,154 +37,96 @@ use GDBM_File; use Apache::loncommon; use Apache::lonlocal; use Apache::lonnet; +use LONCAPA; my $iconpath; # variable to be accessible to multiple subroutines my %hash; # variable to tie to user specific database -sub readfromdb { - my ($r,$shash,$thash)=@_; - - my $diropendb; -# ------------------------------ which file do we open? Easy if explictly given - if ($env{'form.catalogmode'} eq 'groupsearch') { - $diropendb = - "/home/httpd/perl/tmp/$env{'user.domain'}_$env{'user.name'}_searchcat.db"; - } elsif ($env{'form.catalogmode'} eq 'groupimport') { - $diropendb = - "/home/httpd/perl/tmp/$env{'user.domain'}_$env{'user.name'}_indexer.db"; - } elsif ($env{'form.catalogmode'} eq 'groupsec') { - $diropendb = - "/home/httpd/perl/tmp/$env{'user.domain'}_$env{'user.name'}_groupsec.db"; - } else { -# --------------------- not explicitly given, choose the one most recently used - my @dbfn; - my @dbst; - - $dbfn[0] = - "/home/httpd/perl/tmp/$env{'user.domain'}_$env{'user.name'}_searchcat.db"; - $dbst[0]=-1; - if (-e $dbfn[0]) { - $dbst[0]=(stat($dbfn[0]))[9]; +sub update_actions_hash { + my ($hash) = @_; + # be careful in here, there is also a global %hash + my $acts=$env{'form.acts'}; + my @Acts=split(/b/,$acts); + my %ahash; + my %achash; + # some initial hashes for working with data + my $ac=0; + foreach (@Acts) { + my ($state,$ref)=split(/a/); + $ahash{$ref}=$state; + $achash{$ref}=$ac; + $ac++; + } + # sorting through the actions and changing the global database hash + foreach my $key (sort {$achash{$a}<=>$achash{$b}} (keys %ahash)) { + if ($ahash{$key} eq '1') { + $hash->{'store_'.$hash->{'pre_'.$key.'_link'}}= + $hash->{'pre_'.$key.'_title'}; + $hash->{'storectr_'.$hash->{'pre_'.$key.'_link'}}= + $hash->{'storectr'}+0; + $hash->{'storectr'}++; } - $dbfn[1] = - "/home/httpd/perl/tmp/$env{'user.domain'}_$env{'user.name'}_indexer.db"; - $dbst[1]=-1; - if (-e $dbfn[1]) { - $dbst[1]=(stat($dbfn[1]))[9]; - } - $dbfn[2] = - "/home/httpd/perl/tmp/$env{'user.domain'}_$env{'user.name'}_groupsec.db"; - $dbst[2]=-1; - if (-e $dbfn[2]) { - $dbst[2]=(stat($dbfn[2]))[9]; - } -# Expand here for more modes -# .... + if ($ahash{$key} eq '0') { + if ($hash->{'store_'.$hash->{'pre_'.$key.'_link'}}) { + delete($hash->{'store_'.$hash->{'pre_'.$key.'_link'}}); + delete($hash->{'storectr_'.$hash->{'pre_'.$key.'_link'}}); + } + } + } + # deleting the previously cached listing + foreach my $key (keys(%{ $hash })) { + next if ($key !~ /^pre_(\d+)_link/); + my $which = $1; + delete($hash->{'pre_'.$which.'_title'}); + delete($hash->{'pre_'.$which.'_link'}); + } +} -# Okay, find most recent existing +sub readfromdb { + my ($r,$resources)=@_; - my $newest=0; - $diropendb=''; - for (my $i=0; $i<=$#dbfn; $i++) { - if ($dbst[$i]>$newest) { - $newest=$dbst[$i]; - $diropendb=$dbfn[$i]; - } - } + my $diropendb = + "/home/httpd/perl/tmp/$env{'user.domain'}_$env{'user.name'}_sel_res.db"; - } # ----------------------------- diropendb is now the filename of the db to open if (tie(%hash,'GDBM_File',$diropendb,&GDBM_WRCREAT(),0640)) { - my $acts = $env{'form.acts'}; - my @Acts = split(/b/,$acts); - my %ahash; - my %achash; - my $ac = 0; - foreach (@Acts) { - my ($state,$ref) = split(/a/); - $ahash{$ref} = $state; - $achash{$ref} = $ac; - $ac++; - } - foreach (sort {$achash{$a} <=> $achash{$b}} (keys %ahash)) { - my $key = $_; - if ($ahash{$key} eq '1') { -# my $keyz=join("
",keys %hash); -# print "
$key
$keyz".$hash{'pre_'.$key.'_link'}."
\n"; - $hash{'store_'.$hash{'pre_'.$key.'_link'}} = - $hash{'pre_'.$key.'_title'}; - $hash{'storectr_'.$hash{'pre_'.$key.'_link'}} = - $hash{'storectr'}+0; - $hash{'storectr'}++; - } - if ($ahash{$key} eq '0') { - if ($hash{'store_'.$hash{'pre_'.$key.'_link'}}) { - delete $hash{'store_'.$hash{'pre_'.$key.'_link'}}; - } - } + &update_actions_hash(\%hash); + + my %temp_resources; + foreach my $key (keys(%hash)) { + next if ($key !~ /^store_/); + my ($url) = ($key =~ /^store_(.*)/); + $temp_resources{$hash{'storectr_'.$url}}{'url'}=$url; + $temp_resources{$hash{'storectr_'.$url}}{'title'}= + &Apache::lonnet::gettitle($url); } - foreach (keys %hash) { - if ($_ =~ /^store_/) { - my $key = $_; - $key =~ s/^store_//; - $$shash{$key} = $hash{'storectr_'.$key}; - if (&Apache::lonnet::gettitle($key) eq '') { - $$thash{$key} = $hash{'store_'.$key}; - } else { - $$thash{$key} = &Apache::lonnet::gettitle($key); - } - } + + # use the temp, since there might be gaps in the counting + foreach my $item (sort {$a <=> $b} (keys(%temp_resources))) { + push(@{ $resources },$temp_resources{$item}); } + if ($env{'form.oldval'}) { - my $newctr = 0; - my %chash; - foreach (sort {$$shash{$a} <=> $$shash{$b}} (keys %{$shash})) { - my $key = $_; - $newctr++; - $$shash{$key} = $newctr; - $hash{'storectr_'.$key} = $newctr; - $chash{$newctr} = $key; - } - my $oldval = $env{'form.oldval'}; - my $newval = $env{'form.newval'}; - if ($oldval != $newval) { - # when newval==0, then push down and delete - if ($newval!=0) { - $$shash{$chash{$oldval}} = $newval; - $hash{'storectr_'.$chash{$oldval}} = $newval; - } else { - $$shash{$chash{$oldval}} = $newctr; - $hash{'storectr_'.$chash{$oldval}} = $newctr; - } - if ($newval==0) { # push down - my $newval2=$newctr; - for my $idx ($oldval..($newval2-1)) { - $$shash{$chash{$idx+1}} = $idx; - $hash{'storectr_'.$chash{$idx+1}} = $idx; - } - delete $$shash{$chash{$oldval}}; - delete $hash{'storectr_'.$chash{$oldval}}; - delete $hash{'store_'.$chash{$oldval}}; - } elsif ($oldval < $newval) { # push down - for my $idx ($oldval..($newval-1)) { - $$shash{$chash{$idx+1}} = $idx; - $hash{'storectr_'.$chash{$idx+1}} = $idx; - } - } elsif ($oldval > $newval) { # push up - for my $idx (reverse($newval..($oldval-1))) { - $$shash{$chash{$idx}} = $idx+1; - $hash{'storectr_'.$chash{$idx}} = $idx+1; - } - } + my $res = splice(@{$resources},$env{'form.oldval'}-1,1); + if ($env{'form.newval'} == 0) { + # picked 'discard' + my $url = $res->{'url'}; + delete($hash{'storectr_'.$url}); + delete($hash{'store_'.$url}); + } else { + splice(@{$resources},$env{'form.newval'}-1,0,$res); } } + # store out new order + foreach my $which (0..$#$resources) { + my $url = $resources->[$which]{'url'}; + $hash{'storectr_'.$url} = $which; + } } else { - $r->print('Unable to tie hash to db file'); - return OK; + $r->print('Unable to tie hash to db file'); } - untie %hash; - return ($shash,$thash); + untie(%hash); } @@ -196,6 +138,66 @@ sub cleanup { &Apache::lonnet::logthis('Failed cleanup groupsort: hash'); } } + return OK; +} + +# -------------------------------------------------------------- Read from file + +sub readfromfile { + my ($r,$resources)=@_; + my $cont=&Apache::lonnet::getfile + (&Apache::lonnet::filelocation('',$env{'form.readfile'})); + if ($cont==-1) { + $r->print('Unable to read file: '. + &Apache::lonnet::filelocation('',$env{'form.readfile'})); + } else { + my $parser = HTML::TokeParser->new(\$cont); + my $token; + while ($token = $parser->get_token) { + if ($token->[0] eq 'S') { + if ($token->[1] eq 'resource') { + if ($env{'form.recover'}) { + if ($token->[2]->{'type'} ne 'zombie') { next; } + } else { + if ($token->[2]->{'type'} eq 'zombie') { next; } + } + + my $name=$token->[2]->{'title'}; + $name=~s/ \[\((\d+)\,($LONCAPA::username_re)\,($LONCAPA::domain_re)\)\]$//; + my $note; + if ($1) { + $note = '
'.&mt('Removed by '). + &Apache::loncommon::plainname($2,$3).', '. + &Apache::lonlocal::locallocaltime($1); + } + $name=~s/\&colon\;/\:/g; + push(@{$resources}, {'url' => $token->[2]->{'src'}, + 'title' => $name, + 'note' => $note, + 'id' => $token->[2]->{'id'},}); + } + } + } + } +} + +# --------------------------------------------------------- Read from bookmarks + +sub readfrombookmarks { + my ($r,$resources)=@_; + my %bookmarks=&Apache::lonnet::dump('bookmarks'); +# the bookmark "hash" is just one entry +# it's a javascript program code with arguments like ('title','url'); + my @bookmarks=($bookmarks{'bookmarks'}=~/\((?:\'([^\']+)\'\,\'([^\']+)\'|\"([^\"]+)\"\,\"([^\"]+)\")\)\;/g); + for (my $index=0;$index<($#bookmarks+1)/2;$index++) { + if ($bookmarks[$index*2+1]) { + my $url = $bookmarks[$index*2+1]; + my $name = $bookmarks[$index*2]; + $name =~ s/^LON\-CAPA\s+//; + + push(@{$resources},{'url' => $url, 'title' => $name}); + } + } } # ---------------------------------------------------------------- Main Handler @@ -203,10 +205,7 @@ sub handler { my $r = shift; &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['acts','catalogmode','mode']); - # color scheme - my $fileclr = '#ffffe6'; - my $titleclr = '#ddffff'; + ['acts','mode','readfile','recover','bookmarks']); &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; @@ -214,14 +213,23 @@ sub handler { # finish_import looks different for graphical or "simple" RAT my $finishimport=''; + my $begincondition=''; + my $endcondition=''; + if (($env{'form.readfile'}) || ($env{'form.bookmarks'})) { + $begincondition='if (eval("document.forms.groupsort.include"+num+".checked")) {'; + $endcondition='}'; + } if ($env{'form.mode'} eq 'simple' || $env{'form.mode'} eq '') { $finishimport=(< + my $js = < function insertRowInLastRow() { opener.insertrow(opener.maxrow); opener.addobj(opener.maxrow,'e&2'); } -function placeResourceInLastRow (title,url,linkflag) { +function placeResourceInLastRow (title,url,id,linkflag) { opener.mostrecent=opener.newresource(opener.maxrow,2,opener.escape(title), - opener.escape(url),'false','normal'); + opener.escape(url),'false','normal',id); opener.save(); if (linkflag) { opener.joinres(opener.linkmode,opener.mostrecent,0); @@ -283,70 +290,116 @@ function orderchange(val,newval) { document.forms.groupsort.submit(); } - END # read pertinent machine configuration my $domain = $r->dir_config('lonDefDomain'); $iconpath = $r->dir_config('lonIconsURL') . "/"; - my %shash; # sort order (key is resource location, value is sort order) - my %thash; # title (key is resource location, value is title) + my @resources; - &readfromdb($r,\%shash,\%thash); + if ($env{'form.readfile'}) { + &readfromfile($r,\@resources); + } elsif ($env{'form.bookmarks'}) { + &readfrombookmarks($r,\@resources); + } else { + &readfromdb($r,\@resources); + } my $ctr = 0; - my $clen = scalar(keys %shash); - if ($clen > 1) { + my $clen = scalar(@resources); + if (($clen > 1) || ($env{'form.readfile'}) || ($env{'form.bookmarks'})) { my %lt=&Apache::lonlocal::texthash( 'fin'=> 'Finalize order of resources', - 'gb' => 'Go Back', - 'ns' => 'New Search', + 'ci' => 'Continue Import', + 'cs' => 'Continue Search', 'fi' => 'Finish Import', + 're' => 'Recover Checked', + 'ip' => 'Import Checked', 'ca' => 'Cancel', 'co' => 'Change Order', 'ti' => 'Title', - 'pa' => 'Path' + 'pa' => 'Path', + 'in' => 'Include' ); - $r->print(&Apache::loncommon::bodytag('Sort Imported Resources')); + my $title = ''; + if ($env{'form.recover'}) { + $title = 'Recover Removed Resources'; + } else { + $title = 'Sort Imported Resources'; + } + if ($env{'form.bookmarks'}) { + $title = 'Import Resources from Bookmarks'; + } + + $r->print(&Apache::loncommon::start_page($title, $js)); + $r->print(<$lt{'fin'}
+ + + END - # --- Expand here if "GO BACK" button desired - if ($env{'form.catalogmode'} eq 'groupimport') { - my $resurl = &Apache::loncommon::lastresurl(); - $r->print(<  -END + $r->print(&Apache::loncommon::inhibit_menu_check('input')); + # --- + + my $buttontext = $lt{'re'}; + if ($env{'form.bookmarks'}) { + $buttontext = $lt{'ip'} } - if ($env{'form.catalogmode'} eq 'groupsearch') { + if ($env{'form.recover'} || $env{'form.bookmarks'}) { $r->print(<  +  + END - } - # --- - - $r->print(<print(<$lt{'fin'} +
+  +    +
+
END - $r->print("
"); - $r->print("\n"); - $r->print("\n"); - $r->print("\n"); - $r->print("\n"); + } + + # Only display header if content exists + if ($clen > 0) { + $r->print(&Apache::loncommon::start_data_table() + .&Apache::loncommon::start_data_table_header_row()); + if (($env{'form.readfile'}) || ($env{'form.bookmarks'})) { + $r->print("\n"); + } else { + $r->print(''."\n"); + } + $r->print(''."\n"); + $r->print(""); + $r->print(&Apache::loncommon::end_data_table_header_row()."\n"); + } else { + $r->print('

'); + if ($env{'form.bookmarks'}) { + $r->print(&mt('There are no resources in your bookmarks to import.')); + } + $r->print('

'); + } } else { + $r->print(&Apache::loncommon::start_page(undef,$js, + {'only_body' => 1})); $r->print(< @@ -354,28 +407,44 @@ END END + $r->print(&Apache::loncommon::inhibit_menu_check('input')); + } - foreach (sort {$shash{$a}<=>$shash{$b}} (keys %shash)) { - my $key=$_; + foreach my $resource (@resources) { $ctr++; - my $iconname=&Apache::loncommon::icon($key); - if ($clen > 1) { - $r->print(""); + unless (($env{'form.readfile'}) || ($env{'form.bookmarks'})) { + $r->print(""); + } + $r->print("\n"); + $r->print("" + .&Apache::loncommon::end_data_table_row() + ."\n"); } } - if ($clen > 1) { - $r->print("
$lt{'co'}$lt{'ti'}$lt{'pa'}
$lt{'in'}'.$lt{'co'}.''.$lt{'ti'}.'$lt{'pa'}
"); - $r->print(&movers($clen,$ctr)); + my $iconname=&Apache::loncommon::icon($resource->{'url'}); + if (($clen > 1) || ($env{'form.readfile'}) || ($env{'form.bookmarks'})) { + $r->print(&Apache::loncommon::start_data_table_row() + .""); + if (($env{'form.readfile'}) || ($env{'form.bookmarks'})) { + $r->print(&checkbox($ctr-1)); + } else { + $r->print(&movers($clen,$ctr)); + } } - $r->print(&hidden($ctr-1,$thash{$key},$key)); - if ($clen > 1) { - $r->print(""); - $r->print(&select_box($clen,$ctr)); - $r->print(""); + $r->print(&hidden($ctr-1,$resource->{'title'},$resource->{'url'}, + $resource->{'id'})); + if (($clen > 1) || ($env{'form.readfile'}) || ($env{'form.bookmarks'})) { + $r->print("". + &select_box($clen,$ctr). + ""); $r->print(""); - $r->print(""); - $r->print("$thash{$key}\n"); - $r->print("$key
"); + $r->print($resource->{'title'}.$resource->{'notes'}."\n"); + $r->print($resource->{'url'}."
"); + if (($clen > 1) || ($env{'form.readfile'}) || ($env{'form.bookmarks'})) { + if ($clen > 0) { + $r->print(&Apache::loncommon::end_data_table()); + } + $r->print(''); } else { $r->print(< @@ -383,21 +452,21 @@ END END } - $r->print(< - -END + + $r->print(&Apache::loncommon::end_page()); return OK; } # --------------------------------------- Hidden values (returns scalar string) sub hidden { - my ($sel,$title,$filelink) = @_; - my $string = ''; + my ($sel,$title,$filelink,$id) = @_; + my $string = ''; + $filelink=~s|^/ext/|http://|; $string .= ''; + &escape($filelink).'" />'; + $string .= ''; return $string; } @@ -426,7 +495,7 @@ sub select_box { my $string; $string = ''.&mt('Include').''; +} + 1; __END__ + +=pod + +=head1 NAME + +Apache::groupsort.pm + +=head1 SYNOPSIS + +Implements a second phase of importing +multiple resources into the RAT. Allows for +reordering the sequence of resources + +This is part of the LearningOnline Network with CAPA project +described at http://www.lon-capa.org. + + +=head1 NOTABLE SUBROUTINES + +=over + +=item + +=back + +=cut + 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.