Diff for /loncom/interface/loncommon.pm between versions 1.8 and 1.32

version 1.8, 2001/10/26 17:29:28 version 1.32, 2002/04/22 15:26:46
Line 1 Line 1
 # The LearningOnline Network  # The LearningOnline Network with CAPA
 # a pile of common routines  # a pile of common routines
 # 2/13 Guy Albertelli  #
   # $Id$
   #
   # Copyright Michigan State University Board of Trustees
   #
   # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
   #
   # LON-CAPA is free software; you can redistribute it and/or modify
   # it under the terms of the GNU General Public License as published by
   # the Free Software Foundation; either version 2 of the License, or
   # (at your option) any later version.
   #
   # LON-CAPA is distributed in the hope that it will be useful,
   # but WITHOUT ANY WARRANTY; without even the implied warranty of
   # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   # GNU General Public License for more details.
   #
   # You should have received a copy of the GNU General Public License
   # along with LON-CAPA; if not, write to the Free Software
   # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   #
   # /home/httpd/html/adm/gpl.txt
   #
   # http://www.lon-capa.org/
   #
   # YEAR=2001
   # 2/13-12/7 Guy Albertelli
   # 12/11,12/12,12/17 Scott Harrison
   # 12/21 Gerd Kortemeyer
   # 12/21 Scott Harrison
   # 12/25,12/28 Gerd Kortemeyer
   # YEAR=2002
   # 1/4 Gerd Kortemeyer
   
 # Makes a table out of the previous attempts  # Makes a table out of the previous attempts
 # Inputs result_from_symbread, user, domain, course_id  # Inputs result_from_symbread, user, domain, course_id
   # Reads in non-network-related .tab files
   
 package Apache::loncommon;  package Apache::loncommon;
   
 use strict;  use strict;
   use Apache::lonnet();
 use POSIX qw(strftime);  use POSIX qw(strftime);
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
 use Apache::lonmsg();  use Apache::lonmsg();
   
   my $readit;
   
   # ----------------------------------------------- Filetypes/Languages/Copyright
   my %language;
   my %cprtag;
   my %fe; my %fd;
   my %fc;
   
   # -------------------------------------------------------------- Thesaurus data
   my @therelated;
   my @theword;
   my @thecount;
   my %theindex;
   my $thetotalcount;
   my $thefuzzy=2;
   my $thethreshold=0.1/$thefuzzy;
   my $theavecount;
   
   # ----------------------------------------------------------------------- BEGIN
   BEGIN {
   
       unless ($readit) {
   # ------------------------------------------------------------------- languages
       {
    my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}.
    '/language.tab');
    if ($fh) {
       while (<$fh>) {
    next if /^\#/;
    chomp;
    my ($key,$val)=(split(/\s+/,$_,2));
    $language{$key}=$val;
       }
    }
       }
   # ------------------------------------------------------------------ copyrights
       {
    my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonIncludes'}.
     '/copyright.tab');
    if ($fh) {
       while (<$fh>) {
    next if /^\#/;
    chomp;
    my ($key,$val)=(split(/\s+/,$_,2));
    $cprtag{$key}=$val;
       }
    }
       }
   # ------------------------------------------------------------- file categories
       {
    my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}.
     '/filecategories.tab');
    if ($fh) {
       while (<$fh>) {
    next if /^\#/;
    chomp;
    my ($key,$val)=(split(/\s+/,$_,2));
    push @{$fc{$key}},$val;
       }
    }
       }
   # ------------------------------------------------------------------ file types
       {
    my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}.
          '/filetypes.tab');
    if ($fh) {
               while (<$fh>) {
    next if (/^\#/);
    chomp;
    my ($ending,$emb,$descr)=split(/\s+/,$_,3);
    if ($descr ne '') { 
       $fe{$ending}=lc($emb);
       $fd{$ending}=$descr;
    }
       }
    }
       }
   # -------------------------------------------------------------- Thesaurus data
       {
    my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}.
          '/thesaurus.dat');
    if ($fh) {
               while (<$fh>) {
                  my ($tword,$tindex,$tcount,$trelated)=split(/\@/,$_);
                  $theindex{$tword}=$tindex;
                  $theword[$tindex]=$tword;
                  $thecount[$tindex]=$tcount;
                  $thetotalcount+=$tcount;
                  $therelated[$tindex]=$trelated;
      }
           }
           $theavecount=$thetotalcount/$#thecount;
       }
       &Apache::lonnet::logthis(
                 "<font color=yellow>INFO: Read file types and thesaurus</font>");
       $readit=1;
   }
       
   }
   # ============================================================= END BEGIN BLOCK
   
   ###############################################################
   ##    Authentication changing form generation subroutines    ##
   ###############################################################
   ##
   ## All of the authform_xxxxxxx subroutines take their inputs in a
   ## hash, and have reasonable default values.
   ##
   ##    formname = the name given in the <form> tag.
   sub authform_header{  
       my %in = (
           formname => 'cu',
           kerb_def_dom => 'MSU.EDU',
           @_,
       );
       $in{'formname'} = 'document.' . $in{'formname'};
       my $result='';
       $result.=<<"END";
   var current = new Object();
   current.radiovalue = 'nochange';
   current.argfield = null;
   
   function changed_radio(choice,currentform) {
       var choicearg = choice + 'arg';
       // If a radio button in changed, we need to change the argfield
       if (current.radiovalue != choice) {
           current.radiovalue = choice;
           if (current.argfield != null) {
               currentform.elements[current.argfield].value = '';
           }
           if (choice == 'nochange') {
               current.argfield = null;
           } else {
               current.argfield = choicearg;
               switch(choice) {
                   case 'krb': 
                       currentform.elements[current.argfield].value = 
                           "$in{'kerb_def_dom'}";
                   break;
                 default:
                   break;
               }
           }
       }
       return;
   }
   
   function changed_text(choice,currentform) {
       var choicearg = choice + 'arg';
       if (currentform.elements[choicearg].value !='') {
           switch (choice) {
               case 'krb': currentform.elements[choicearg].value =
                   currentform.elements[choicearg].value.toUpperCase();
                   break;
               default:
           }
           // clear old field
           if ((current.argfield != choicearg) && (current.argfield != null)) {
               currentform.elements[current.argfield].value = '';
           }
           current.argfield = choicearg;
       }
       set_auth_radio_buttons(choice,currentform);
       return;
   }
   
   function set_auth_radio_buttons(newvalue,currentform) {
       var i=0;
       while (i < currentform.login.length) {
           if (currentform.login[i].value == newvalue) { break; }
           i++;
       }
       if (i == currentform.login.length) {
           return;
       }
       current.radiovalue = newvalue;
       currentform.login[i].checked = true;
       return;
   }
   END
       return $result;
   }
   
   sub authform_authorwarning{
       my $result='';
       $result=<<"END";
   <i>As a general rule, only authors or co-authors should be filesystem
   authenticated (which allows access to the server filesystem).</i>
   END
       return $result;
   }
   
   sub authform_nochange{  
       my %in = (
                 formname => 'document.cu',
                 kerb_def_dom => 'MSU.EDU',
                 @_,
             );
       my $result='';
       $result.=<<"END";
   <input type="radio" name="login" value="nochange" checked="checked"
          onclick="javascript:changed_radio('nochange',$in{'formname'});">
   Do not change login data
   END
       return $result;
   }
   
   sub authform_kerberos{  
       my %in = (
                 formname => 'document.cu',
                 kerb_def_dom => 'MSU.EDU',
                 @_,
                 );
       my $result='';
       $result.=<<"END";
   <input type="radio" name="login" value="krb" 
          onclick="javascript:changed_radio('krb',$in{'formname'});"
          onchange="javascript:changed_radio('krb',$in{'formname'});">
   Kerberos authenticated with domain
   <input type="text" size="10" name="krbarg" value=""
          onchange="javascript:changed_text('krb',$in{'formname'});">
   END
       return $result;
   }
   
   sub authform_internal{  
       my %args = (
                   formname => 'document.cu',
                   kerb_def_dom => 'MSU.EDU',
                   @_,
                   );
       my $result='';
       $result.=<<"END";
   <input type="radio" name="login" value="int"
          onchange="javascript:changed_radio('int',$args{'formname'});"
          onclick="javascript:changed_radio('int',$args{'formname'});">
   Internally authenticated (with initial password 
   <input type="text" size="10" name="intarg" value=""
          onchange="javascript:changed_text('int',$args{'formname'});">
   END
       return $result;
   }
   
   sub authform_local{  
       my %in = (
                 formname => 'document.cu',
                 kerb_def_dom => 'MSU.EDU',
                 @_,
                 );
       my $result='';
       $result.=<<"END";
   <input type="radio" name="login" value="loc"
          onchange="javascript:changed_radio('loc',$in{'formname'});"
          onclick="javascript:changed_radio('loc',$in{'formname'});"> 
   Local Authentication with argument
   <input type="text" size="10" name="locarg" value=""
          onchange="javascript:changed_text('loc',$in{'formname'});">
   END
       return $result;
   }
   
   sub authform_filesystem{  
       my %in = (
                 formname => 'document.cu',
                 kerb_def_dom => 'MSU.EDU',
                 @_,
                 );
       my $result='';
       $result.=<<"END";
   <input type="radio" name="login" value="fsys" 
          onchange="javascript:changed_radio('fsys',$in{'formname'});"
          onclick="javascript:changed_radio('fsys',$in{'formname'});"> 
   Filesystem authenticated (with initial password 
   <input type="text" size="10" name="fsysarg" value=""
          onchange="javascript:changed_text('fsys',$in{'formname'});">
   END
       return $result;
   }
   
   ###############################################################
   ##   End Authentication changing form generation functions   ##
   ###############################################################
   
   
   
   # ---------------------------------------------------------- Is this a keyword?
   
   sub keyword {
       my $newword=shift;
       $newword=~s/\W//g;
       $newword=~tr/A-Z/a-z/;
       my $tindex=$theindex{$newword};
       if ($tindex) {
           if ($thecount[$tindex]>$theavecount) {
              return 1;
           }
       }
       return 0;
   }
   # -------------------------------------------------------- Return related words
   
   sub related {
       my $newword=shift;
       $newword=~s/\W//g;
       $newword=~tr/A-Z/a-z/;
       my $tindex=$theindex{$newword};
       if ($tindex) {
           my %found=();
           foreach (split(/\,/,$therelated[$tindex])) {
   # - Related word found
               my ($ridx,$rcount)=split(/\:/,$_);
   # - Direct relation index
               my $directrel=$rcount/$thecount[$tindex];
               if ($directrel>$thethreshold) {
                  foreach (split(/\,/,$therelated[$ridx])) {
                     my ($rridx,$rrcount)=split(/\:/,$_);
                     if ($rridx==$tindex) {
   # - Determine reverse relation index
                        my $revrel=$rrcount/$thecount[$ridx];
   # - Calculate full index
                        $found{$ridx}=$directrel*$revrel;
                        if ($found{$ridx}>$thethreshold) {
                           foreach (split(/\,/,$therelated[$ridx])) {
                               my ($rrridx,$rrrcount)=split(/\:/,$_);
                               unless ($found{$rrridx}) {
                                  my $revrevrel=$rrrcount/$thecount[$ridx];
                                  if (
                             $directrel*$revrel*$revrevrel>$thethreshold
                                  ) {
                                     $found{$rrridx}=
                                          $directrel*$revrel*$revrevrel;
                                  }
                               }
                           }
                        }
                     }
                  }
               }
           }
       }
       return ();
   }
   
   # ---------------------------------------------------------------- Language IDs
   sub languageids {
       return sort(keys(%language));
   }
   
   # -------------------------------------------------------- Language Description
   sub languagedescription {
       return $language{shift(@_)};
   }
   
   # --------------------------------------------------------------- Copyright IDs
   sub copyrightids {
       return sort(keys(%cprtag));
   }
   
   # ------------------------------------------------------- Copyright Description
   sub copyrightdescription {
       return $cprtag{shift(@_)};
   }
   
   # ------------------------------------------------------------- File Categories
   sub filecategories {
       return sort(keys(%fc));
   }
   
   # -------------------------------------- File Types within a specified category
   sub filecategorytypes {
       return @{$fc{lc(shift(@_))}};
   }
   
   # ------------------------------------------------------------------ File Types
   sub fileextensions {
       return sort(keys(%fe));
   }
   
   # ------------------------------------------------------------- Embedding Style
   sub fileembstyle {
       return $fe{lc(shift(@_))};
   }
   
   # ------------------------------------------------------------ Description Text
   sub filedescription {
       return $fd{lc(shift(@_))};
   }
   
   # ------------------------------------------------------------ Description Text
   sub filedescriptionex {
       my $ex=shift;
       return '.'.$ex.' '.$fd{lc($ex)};
   }
   
 sub get_previous_attempt {  sub get_previous_attempt {
   my ($symb,$username,$domain,$course)=@_;    my ($symb,$username,$domain,$course)=@_;
   my $prevattempts='';    my $prevattempts='';
Line 22  sub get_previous_attempt { Line 450  sub get_previous_attempt {
       my %lasthash=();        my %lasthash=();
       my $version;        my $version;
       for ($version=1;$version<=$returnhash{'version'};$version++) {        for ($version=1;$version<=$returnhash{'version'};$version++) {
         map {          foreach (sort(split(/\:/,$returnhash{$version.':keys'}))) {
   $lasthash{$_}=$returnhash{$version.':'.$_};    $lasthash{$_}=$returnhash{$version.':'.$_};
         } sort(split(/\:/,$returnhash{$version.':keys'}));          }
       }        }
       $prevattempts='<table border=2></tr><th>History</th>';        $prevattempts='<table border=2></tr><th>History</th>';
       map {        foreach (sort(keys %lasthash)) {
         $prevattempts.='<th>'.$_.'</th>';   my ($ign,@parts) = split(/\./,$_);
       } sort(keys %lasthash);   if (@parts) {
     my $data=$parts[-1];
     pop(@parts);
     $prevattempts.='<th>Part '.join('.',@parts).'<br />'.$data.'</th>';
    } else {
     $prevattempts.='<th>'.$ign.'</th>';
    }
         }
       for ($version=1;$version<=$returnhash{'version'};$version++) {        for ($version=1;$version<=$returnhash{'version'};$version++) {
         $prevattempts.='</tr><tr><th>Attempt '.$version.'</th>';          $prevattempts.='</tr><tr><th>Attempt '.$version.'</th>';
         map {          foreach (sort(keys %lasthash)) {
   my $value;    my $value;
   if ($_ =~ /timestamp/) {    if ($_ =~ /timestamp/) {
     $value=scalar(localtime($returnhash{$version.':'.$_}));      $value=scalar(localtime($returnhash{$version.':'.$_}));
Line 40  sub get_previous_attempt { Line 475  sub get_previous_attempt {
     $value=$returnhash{$version.':'.$_};      $value=$returnhash{$version.':'.$_};
   }    }
   $prevattempts.='<td>'.$value.'</td>';       $prevattempts.='<td>'.$value.'</td>';   
         } sort(keys %lasthash);          }
       }        }
       $prevattempts.='</tr><tr><th>Current</th>';        $prevattempts.='</tr><tr><th>Current</th>';
       map {        foreach (sort(keys %lasthash)) {
  my $value;   my $value;
  if ($_ =~ /timestamp/) {   if ($_ =~ /timestamp/) {
   $value=scalar(localtime($lasthash{$_}));    $value=scalar(localtime($lasthash{$_}));
Line 51  sub get_previous_attempt { Line 486  sub get_previous_attempt {
   $value=$lasthash{$_};    $value=$lasthash{$_};
  }   }
  $prevattempts.='<td>'.$value.'</td>';   $prevattempts.='<td>'.$value.'</td>';
       } sort(keys %lasthash);        }
       $prevattempts.='</tr></table>';        $prevattempts.='</tr></table>';
     } else {      } else {
       $prevattempts='Nothing submitted - no attempts.';        $prevattempts='Nothing submitted - no attempts.';
Line 61  sub get_previous_attempt { Line 496  sub get_previous_attempt {
   }    }
 }  }
   
   sub get_student_view {
     my ($symb,$username,$domain,$courseid) = @_;
     my ($map,$id,$feedurl) = split(/___/,$symb);
     my (%old,%moreenv);
     my @elements=('symb','courseid','domain','username');
     foreach my $element (@elements) {
       $old{$element}=$ENV{'form.grade_'.$element};
       $moreenv{'form.grade_'.$element}=eval '$'.$element #'
     }
     &Apache::lonnet::appenv(%moreenv);
     my $userview=&Apache::lonnet::ssi('/res/'.$feedurl);
     &Apache::lonnet::delenv('form.grade_');
     foreach my $element (@elements) {
       $ENV{'form.grade_'.$element}=$old{$element};
     }
     $userview=~s/\<body[^\>]*\>//gi;
     $userview=~s/\<\/body\>//gi;
     $userview=~s/\<html\>//gi;
     $userview=~s/\<\/html\>//gi;
     $userview=~s/\<head\>//gi;
     $userview=~s/\<\/head\>//gi;
     $userview=~s/action\s*\=/would_be_action\=/gi;
     return $userview;
   }
   
   sub get_student_answers {
     my ($symb,$username,$domain,$courseid) = @_;
     my ($map,$id,$feedurl) = split(/___/,$symb);
     my (%old,%moreenv);
     my @elements=('symb','courseid','domain','username');
     foreach my $element (@elements) {
       $old{$element}=$ENV{'form.grade_'.$element};
       $moreenv{'form.grade_'.$element}=eval '$'.$element #'
     }
     $moreenv{'form.grade_target'}='answer';
     &Apache::lonnet::appenv(%moreenv);
     my $userview=&Apache::lonnet::ssi('/res/'.$feedurl);
     &Apache::lonnet::delenv('form.grade_');
     foreach my $element (@elements) {
       $ENV{'form.grade_'.$element}=$old{$element};
     }
     $userview=~s/\<body[^\>]*\>//gi;
     $userview=~s/\<\/body\>//gi;
     $userview=~s/\<html\>//gi;
     $userview=~s/\<\/html\>//gi;
     $userview=~s/\<head\>//gi;
     $userview=~s/\<\/head\>//gi;
     $userview=~s/action\s*\=/would_be_action\=/gi;
     return $userview;
   }
   
 sub get_unprocessed_cgi {  sub get_unprocessed_cgi {
   my ($query)= @_;    my ($query,$possible_names)= @_;
   map {    # $Apache::lonxml::debug=1;
     foreach (split(/&/,$query)) {
     my ($name, $value) = split(/=/,$_);      my ($name, $value) = split(/=/,$_);
     $value =~ tr/+/ /;      $name = &Apache::lonnet::unescape($name);
     $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;      if (!defined($possible_names) || (grep {$_ eq $name} @$possible_names)) {
     if (!defined($ENV{'form.'.$name})) { $ENV{'form.'.$name}=$value; }        $value =~ tr/+/ /;
   } (split(/&/,$query));        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
         &Apache::lonxml::debug("Seting :$name: to :$value:");
         unless (defined($ENV{'form.'.$name})) { &add_to_env('form.'.$name,$value) };
       }
     }
 }  }
   
 sub cacheheader {  sub cacheheader {
     unless ($ENV{'request.method'} eq 'GET') { return ''; }
   my $date=strftime("%a, %d %b %Y %H:%M:%S GMT",gmtime);    my $date=strftime("%a, %d %b %Y %H:%M:%S GMT",gmtime);
   my $output .='<meta HTTP-EQUIV="Expires" CONTENT="'.$date.'" />    my $output .='<meta HTTP-EQUIV="Expires" CONTENT="'.$date.'" />
                 <meta HTTP-EQUIV="Cache-control" CONTENT="no-cache" />                  <meta HTTP-EQUIV="Cache-control" CONTENT="no-cache" />
Line 79  sub cacheheader { Line 571  sub cacheheader {
   return $output;    return $output;
 }  }
   
   sub no_cache {
     my ($r) = @_;
     unless ($ENV{'request.method'} eq 'GET') { return ''; }
     #my $date=strftime("%a, %d %b %Y %H:%M:%S GMT",gmtime);
     $r->no_cache(1);
     $r->header_out("Pragma" => "no-cache");
     #$r->header_out("Expires" => $date);
   }
   
   sub add_to_env {
     my ($name,$value)=@_;
     if (defined($ENV{$name})) {
       if (ref($ENV{$name})) {
         #already have multiple values
         push(@{ $ENV{$name} },$value);
       } else {
         #first time seeing multiple values, convert hash entry to an arrayref
         my $first=$ENV{$name};
         undef($ENV{$name});
         push(@{ $ENV{$name} },$first,$value);
       }
     } else {
       $ENV{$name}=$value;
     }
   }
   
   #---CSV Upload/Handling functions
   
   # ========================================================= Store uploaded file
   # needs $ENV{'form.upfile'}
   # return $datatoken to be put into hidden field
   
   sub upfile_store {
       my $r=shift;
       $ENV{'form.upfile'}=~s/\r/\n/gs;
       $ENV{'form.upfile'}=~s/\f/\n/gs;
       $ENV{'form.upfile'}=~s/\n+/\n/gs;
       $ENV{'form.upfile'}=~s/\n+$//gs;
   
       my $datatoken=$ENV{'user.name'}.'_'.$ENV{'user.domain'}.
    '_enroll_'.$ENV{'request.course.id'}.'_'.time.'_'.$$;
       {
    my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').
    '/tmp/'.$datatoken.'.tmp');
    print $fh $ENV{'form.upfile'};
       }
       return $datatoken;
   }
   
   # ================================================= Load uploaded file from tmp
   # needs $ENV{'form.datatoken'}
   # sets $ENV{'form.upfile'} to the contents of the file
   
   sub load_tmp_file {
       my $r=shift;
       my @studentdata=();
       {
    my $fh;
    if ($fh=Apache::File->new($r->dir_config('lonDaemons').
     '/tmp/'.$ENV{'form.datatoken'}.'.tmp')) {
       @studentdata=<$fh>;
    }
       }
       $ENV{'form.upfile'}=join('',@studentdata);
   }
   
   # ========================================= Separate uploaded file into records
   # returns array of records
   # needs $ENV{'form.upfile'}
   # needs $ENV{'form.upfiletype'}
   
   sub upfile_record_sep {
       if ($ENV{'form.upfiletype'} eq 'xml') {
       } else {
    return split(/\n/,$ENV{'form.upfile'});
       }
   }
   
   # =============================================== Separate a record into fields
   # needs $ENV{'form.upfiletype'}
   # takes $record as arg
   sub record_sep {
       my $record=shift;
       my %components=();
       if ($ENV{'form.upfiletype'} eq 'xml') {
       } elsif ($ENV{'form.upfiletype'} eq 'space') {
           my $i=0;
           foreach (split(/\s+/,$record)) {
               my $field=$_;
               $field=~s/^(\"|\')//;
               $field=~s/(\"|\')$//;
               $components{$i}=$field;
               $i++;
           }
       } elsif ($ENV{'form.upfiletype'} eq 'tab') {
           my $i=0;
           foreach (split(/\t+/,$record)) {
               my $field=$_;
               $field=~s/^(\"|\')//;
               $field=~s/(\"|\')$//;
               $components{$i}=$field;
               $i++;
           }
       } else {
           my @allfields=split(/\,/,$record);
           my $i=0;
           my $j;
           for ($j=0;$j<=$#allfields;$j++) {
               my $field=$allfields[$j];
               if ($field=~/^\s*(\"|\')/) {
    my $delimiter=$1;
                   while (($field!~/$delimiter$/) && ($j<$#allfields)) {
       $j++;
       $field.=','.$allfields[$j];
    }
                   $field=~s/^\s*$delimiter//;
                   $field=~s/$delimiter\s*$//;
               }
               $components{$i}=$field;
       $i++;
           }
       }
       return %components;
   }
   
   # =============================== HTML code to select file and specify its type
   sub upfile_select_html {
       return (<<'ENDUPFORM');
   <input type="file" name="upfile" size="50">
   <br />Type: <select name="upfiletype">
   <option value="csv">CSV (comma separated values, spreadsheet)</option>
   <option value="space">Space separated</option>
   <option value="tab">Tabulator separated</option>
   <option value="xml">HTML/XML</option>
   </select>
   ENDUPFORM
   }
   
   # ===================Prints a table of sample values from each column uploaded
   # $r is an Apache Request ref
   # $records is an arrayref from &Apache::loncommon::upfile_record_sep
   sub csv_print_samples {
       my ($r,$records) = @_;
       my (%sone,%stwo,%sthree);
       %sone=&record_sep($$records[0]);
       if (defined($$records[1])) {%stwo=&record_sep($$records[1]);}
       if (defined($$records[2])) {%sthree=&record_sep($$records[2]);}
   
       $r->print('Samples<br /><table border="2"><tr>');
       foreach (sort({$a <=> $b} keys(%sone))) { $r->print('<th>Column&nbsp;'.($_+1).'</th>'); }
       $r->print('</tr>');
       foreach my $hash (\%sone,\%stwo,\%sthree) {
    $r->print('<tr>');
    foreach (sort({$a <=> $b} keys(%sone))) {
       $r->print('<td>');
       if (defined($$hash{$_})) { $r->print($$hash{$_}); }
       $r->print('</td>');
    }
    $r->print('</tr>');
       }
       $r->print('</tr></table><br />'."\n");
   }
   
   # ======Prints a table to create associations between values and table columns
   # $r is an Apache Request ref
   # $records is an arrayref from &Apache::loncommon::upfile_record_sep
   # $d is an array of 2 element arrays (internal name, displayed name)
   sub csv_print_select_table {
       my ($r,$records,$d) = @_;
       my $i=0;my %sone;
       %sone=&record_sep($$records[0]);
       $r->print('Associate columns with student attributes.'."\n".
        '<table border="2"><tr><th>Attribute</th><th>Column</th></tr>'."\n");
       foreach (@$d) {
    my ($value,$display)=@{ $_ };
    $r->print('<tr><td>'.$display.'</td>');
   
    $r->print('<td><select name=f'.$i.
     ' onchange="javascript:flip(this.form,'.$i.');">');
    $r->print('<option value="none"></option>');
    foreach (sort({$a <=> $b} keys(%sone))) {
       $r->print('<option value="'.$_.'">Column '.($_+1).'</option>');
    }
    $r->print('</select></td></tr>'."\n");
    $i++;
       }
       $i--;
       return $i;
   }
   
   # ===================Prints a table of sample values from the upload and
   #                      can make associate samples to internal names
   # $r is an Apache Request ref
   # $records is an arrayref from &Apache::loncommon::upfile_record_sep
   # $d is an array of 2 element arrays (internal name, displayed name)
   sub csv_samples_select_table {
       my ($r,$records,$d) = @_;
       my %sone; my %stwo; my %sthree;
       my $i=0;
   
       $r->print('<table border=2><tr><th>Field</th><th>Samples</th></tr>');
       %sone=&record_sep($$records[0]);
       if (defined($$records[1])) {%stwo=&record_sep($$records[1]);}
       if (defined($$records[2])) {%sthree=&record_sep($$records[2]);}
   
       foreach (sort keys %sone) {
    $r->print('<tr><td><select name=f'.$i.
     ' onchange="javascript:flip(this.form,'.$i.');">');
    foreach (@$d) {
       my ($value,$display)=@{ $_ };
       $r->print('<option value='.$value.'>'.$display.'</option>');
    }
    $r->print('</select></td><td>');
    if (defined($sone{$_})) { $r->print($sone{$_}."</br>\n"); }
    if (defined($stwo{$_})) { $r->print($stwo{$_}."</br>\n"); }
    if (defined($sthree{$_})) { $r->print($sthree{$_}."</br>\n"); }
    $r->print('</td></tr>');
    $i++;
       }
       $i--;
       return($i);
   }
 1;  1;
 __END__;  __END__;
   
   
   =head1 NAME
   
   Apache::loncommon - pile of common routines
   
   =head1 SYNOPSIS
   
   Referenced by other mod_perl Apache modules.
   
   Invocation:
    &Apache::loncommon::SUBROUTINENAME(ARGUMENTS);
   
   =head1 INTRODUCTION
   
   Common collection of used subroutines.  This collection helps remove
   redundancy from other modules and increase efficiency of memory usage.
   
   Current things done:
   
    Makes a table out of the previous homework attempts
    Inputs result_from_symbread, user, domain, course_id
    Reads in non-network-related .tab files
   
   This is part of the LearningOnline Network with CAPA project
   described at http://www.lon-capa.org.
   
   =head1 HANDLER SUBROUTINE
   
   There is no handler subroutine.
   
   =head1 OTHER SUBROUTINES
   
   =over 4
   
   =item *
   
   BEGIN() : initialize values from language.tab, copyright.tab, filetypes.tab,
   and filecategories.tab.
   
   =item *
   
   languageids() : returns list of all language ids
   
   =item *
   
   languagedescription() : returns description of a specified language id
   
   =item *
   
   copyrightids() : returns list of all copyrights
   
   =item *
   
   copyrightdescription() : returns description of a specified copyright id
   
   =item *
   
   filecategories() : returns list of all file categories
   
   =item *
   
   filecategorytypes() : returns list of file types belonging to a given file
   category
   
   =item *
   
   fileembstyle() : returns embedding style for a specified file type
   
   =item *
   
   filedescription() : returns description for a specified file type
   
   =item *
   
   filedescriptionex() : returns description for a specified file type with
   extra formatting
   
   =item *
   
   get_previous_attempt() : return string with previous attempt on problem
   
   =item *
   
   get_student_view() : show a snapshot of what student was looking at
   
   =item *
   
   get_student_answers() : show a snapshot of how student was answering problem
   
   =item *
   
   get_unprocessed_cgi() : get unparsed CGI parameters
   
   =item *
   
   cacheheader() : returns cache-controlling header code
   
   =item *
   
   nocache() : specifies header code to not have cache
   
   =item *
   
   add_to_env($name,$value) : adds $name to the %ENV hash with value
   $value, if $name already exists, the entry is converted to an array
   reference and $value is added to the array.
   
   =back
   
   =cut

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


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