Diff for /loncom/lonnet/perl/lonnet.pm between versions 1.1194 and 1.1199

version 1.1194, 2012/11/08 18:37:52 version 1.1199, 2012/11/27 23:45:22
Line 2653  sub allowuploaded { Line 2653  sub allowuploaded {
 # (b) When displaying folder contents in course editor, used to determine if  # (b) When displaying folder contents in course editor, used to determine if
 #     "Edit" link will be displayed alongside resource.  #     "Edit" link will be displayed alongside resource.
 #  #
 #  input: 3 args -- filename (decluttered), course number and course domain.  #  input: six args -- filename (decluttered), course number, course domain,
 #  output: array of four scalars --   #                   url, symb (if registered) and group (if this is a group
   #                   item -- e.g., bulletin board, group page etc.).
   #  output: array of five scalars -- 
 #          $cfile -- url for file editing if editable on current server  #          $cfile -- url for file editing if editable on current server
 #          $home -- homeserver of resource (i.e., for author if published,  #          $home -- homeserver of resource (i.e., for author if published,
 #                                           or course if uploaded.).  #                                           or course if uploaded.).
 #          $switchserver --  1 if server switch will be needed.  #          $switchserver --  1 if server switch will be needed.
 #          $uploaded -- 1 if resource is a file uploaded to a course.  #          $forceedit -- 1 if icon/link should be to go to edit mode 
   #          $forceview -- 1 if icon/link should be to go to view mode
 #  #
   
 sub can_edit_resource {  sub can_edit_resource {
Line 2668  sub can_edit_resource { Line 2671  sub can_edit_resource {
 #  #
 # For aboutme pages user can only edit his/her own.  # For aboutme pages user can only edit his/her own.
 #  #
     if ($resurl =~ m{^/adm/($match_domain)/($match_username)/aboutme$}) {      if ($resurl =~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) {
         my ($sdom,$sname) = ($1,$2);          my ($sdom,$sname) = ($1,$2);
         if (($sdom eq $env{'user.domain'}) && ($sname eq $env{'user.name'})) {          if (($sdom eq $env{'user.domain'}) && ($sname eq $env{'user.name'})) {
             $home = $env{'user.home'};              $home = $env{'user.home'};
Line 2689  sub can_edit_resource { Line 2692  sub can_edit_resource {
         if ($group ne '') {          if ($group ne '') {
 # if this is a group homepage or group bulletin board, check group privs  # if this is a group homepage or group bulletin board, check group privs
             my $allowed = 0;              my $allowed = 0;
             if ($resurl =~ m{^/adm/$cdom/$cnum/$group/smppg$}) {              if ($resurl =~ m{^/?adm/$cdom/$cnum/$group/smppg$}) {
                 if ((&Apache::lonnet::allowed('mdg',$env{'request.course.id'}.                  if ((&allowed('mdg',$env{'request.course.id'}.
                             ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) ||                                ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) ||
                         (&allowed('mgh',$env{'request.course.id'}.'/'.$group)) || $crsedit) {                          (&allowed('mgh',$env{'request.course.id'}.'/'.$group)) || $crsedit) {
                     $allowed = 1;                      $allowed = 1;
                 }                  }
             } elsif ($resurl =~ m{^/adm/$cdom/$cnum/\d+/bulletinboard$}) {              } elsif ($resurl =~ m{^/?adm/$cdom/$cnum/\d+/bulletinboard$}) {
                 unless ((&allowed(&Apache::lonnet::allowed('mdg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')))) ||                  if ((&allowed('mdg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) ||
                         (&allowed('cgb',$env{'request.course.id'}.$group)) || $crsedit) {                          (&allowed('cgb',$env{'request.course.id'}.'/'.$group)) || $crsedit) {
                     $allowed = 1;                      $allowed = 1;
                 }                  }
             }              }
Line 2748  sub can_edit_resource { Line 2751  sub can_edit_resource {
                         $forceedit = 1;                          $forceedit = 1;
                     }                      }
                     $cfile = $resurl;                      $cfile = $resurl;
                 } elsif (($resurl eq '/res/lib/templates/simpleproblem.problem')) {                  } elsif ($resurl eq '/res/lib/templates/simpleproblem.problem') {
                     $incourse = 1;                      $incourse = 1;
                     $cfile = $resurl.'/smpedit';                      $cfile = $resurl.'/smpedit';
                 } elsif ($resurl =~ /ext/) {                  } elsif ($resurl =~ m{^/adm/wrapper/ext/}) {
                     $incourse = 1;                      $incourse = 1;
                     # is external                      if ($env{'form.forceedit'}) {
                           $forceview = 1;
                       } else {
                           $forceedit = 1;
                       }
                       $cfile = $resurl;
                 }                  }
             } elsif ($resurl eq '/res/lib/templates/simpleproblem.problem/smpedit') {              } elsif ($resurl eq '/res/lib/templates/simpleproblem.problem/smpedit') {
                 my $template = '/res/lib/templates/simpleproblem.problem';                  my $template = '/res/lib/templates/simpleproblem.problem';
Line 2762  sub can_edit_resource { Line 2770  sub can_edit_resource {
                     $forceview = 1;                      $forceview = 1;
                     $cfile = $template;                      $cfile = $template;
                 }                  }
               } elsif (($resurl =~ m{^/adm/wrapper/ext/}) && ($env{'form.folderpath'} =~ /^supplemental/)) {
                       $incourse = 1;
                       if ($env{'form.forceedit'}) {
                           $forceview = 1;
                       } else {
                           $forceedit = 1;
                       }
                       $cfile = $resurl;
               } elsif (($resurl eq '/adm/extresedit') && ($symb || $env{'form.folderpath'})) {
                   $incourse = 1;
                   $forceview = 1;
                   if ($symb) {
                       my ($map,$id,$res)=&decode_symb($symb);
                       $env{'request.symb'} = $symb;
                       $cfile = &clutter($res);
                   } else {
                       $cfile = $env{'form.suppurl'};
                       $cfile =~ s{^http://}{};
                       $cfile = '/adm/wrapper/ext/'.$cfile;
                   }
             }              }
         }          }
         if ($uploaded || $incourse) {          if ($uploaded || $incourse) {
Line 2800  sub is_course_upload { Line 2828  sub is_course_upload {
 }  }
   
 sub in_course {  sub in_course {
     my ($udom,$uname,$cdom,$cnum,$type) = @_;      my ($udom,$uname,$cdom,$cnum,$type,$hideprivileged) = @_;
       if ($hideprivileged) {
           my $skipuser;
           if (&privileged($uname,$udom)) {
               $skipuser = 1;
               my %coursehash = &coursedescription($cdom.'_'.$cnum);
               if ($coursehash{'nothideprivileged'}) {
                   foreach my $item (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) {
                       my $user;
                       if ($item =~ /:/) {
                           $user = $item;
                       } else {
                           $user = join(':',split(/[\@]/,$item));
                       }
                       if ($user eq $uname.':'.$udom) {
                           undef($skipuser);
                           last;
                       }
                   }
               }
               if ($skipuser) {
                   return 0;
               }
           }
       }
     $type ||= 'any';      $type ||= 'any';
     if (!defined($cdom) || !defined($cnum)) {      if (!defined($cdom) || !defined($cnum)) {
         my $cid  = $env{'request.course.id'};          my $cid  = $env{'request.course.id'};
Line 2808  sub in_course { Line 2860  sub in_course {
         $cnum = $env{'course.'.$cid.'.num'};          $cnum = $env{'course.'.$cid.'.num'};
     }      }
     my $typesref;      my $typesref;
     if ($type eq 'all') {      if (($type eq 'any') || ($type eq 'all')) {
         $typesref = ['active','previous','future'];          $typesref = ['active','previous','future'];
     } elsif ($type eq 'previous' || $type eq 'future') {      } elsif ($type eq 'previous' || $type eq 'future') {
         $typesref = [$type];          $typesref = [$type];
Line 5664  sub tmpdel { Line 5716  sub tmpdel {
     return &reply("tmpdel:$token",$server);      return &reply("tmpdel:$token",$server);
 }  }
   
   # ------------------------------------------------------------ get_timebased_id 
   
   sub get_timebased_id {
       my ($prefix,$keyid,$namespace,$cdom,$cnum,$idtype,$who,$locktries,
           $maxtries) = @_;
       my ($newid,$error,$dellock);
       unless (($prefix =~ /^\w+$/) && ($keyid =~ /^\w+$/) && ($namespace ne '')) {  
           return ('','ok','invalid call to get suffix');
       }
   
   # set defaults for any optional args for which values were not supplied
       if ($who eq '') {
           $who = $env{'user.name'}.':'.$env{'user.domain'};
       }
       if (!$locktries) {
           $locktries = 3;
       }
       if (!$maxtries) {
           $maxtries = 10;
       }
       
       if (($cdom eq '') || ($cnum eq '')) {
           if ($env{'request.course.id'}) {
               $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
               $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
           }
           if (($cdom eq '') || ($cnum eq '')) {
               return ('','ok','call to get suffix not in course context');
           }
       }
   
   # construct locking item
       my $lockhash = {
                         $prefix."\0".'locked_'.$keyid => $who,
                      };
       my $tries = 0;
   
   # attempt to get lock on nohist_$namespace file
       my $gotlock = &Apache::lonnet::newput('nohist_'.$namespace,$lockhash,$cdom,$cnum);
       while (($gotlock ne 'ok') && $tries <$locktries) {
           $tries ++;
           sleep 1;
           $gotlock = &Apache::lonnet::newput('nohist_'.$namespace,$lockhash,$cdom,$cnum);
       }
   
   # attempt to get unique identifier, based on current timestamp
       if ($gotlock eq 'ok') {
           my %inuse = &Apache::lonnet::dump('nohist_'.$namespace,$cdom,$cnum,$prefix);
           my $id = time;
           $newid = $id;
           my $idtries = 0;
           while (exists($inuse{$prefix."\0".$newid}) && $idtries < $maxtries) {
               if ($idtype eq 'concat') {
                   $newid = $id.$idtries;
               } else {
                   $newid ++;
               }
               $idtries ++;
           }
           if (!exists($inuse{$prefix."\0".$newid})) {
               my %new_item =  (
                                 $prefix."\0".$newid => $who,
                               );
               my $putresult = &Apache::lonnet::put('nohist_'.$namespace,\%new_item,
                                                    $cdom,$cnum);
               if ($putresult ne 'ok') {
                   undef($newid);
                   $error = 'error saving new item: '.$putresult;
               }
           } else {
                $error = ('error: no unique suffix available for the new item ');
           }
   #  remove lock
           my @del_lock = ($prefix."\0".'locked_'.$keyid);
           $dellock = &Apache::lonnet::del('nohist_'.$namespace,\@del_lock,$cdom,$cnum);
       } else {
           $error = "error: could not obtain lockfile\n";
           $dellock = 'ok';
       }
       return ($newid,$dellock,$error);
   }
   
 # -------------------------------------------------- portfolio access checking  # -------------------------------------------------- portfolio access checking
   
 sub portfolio_access {  sub portfolio_access {
Line 10153  sub gettitle { Line 10287  sub gettitle {
     return $title;      return $title;
 }  }
   
   sub getdocspath {
       my ($symb) = @_;
       my $path;
       if ($symb) {
           my ($mapurl,$id,$resurl) = &decode_symb($symb);
           if ($resurl=~/\.(sequence|page)$/) {
               $mapurl=$resurl;
           } elsif ($resurl eq 'adm/navmaps') {
               $mapurl=$env{'course.'.$env{'request.course.id'}.'.url'};
           }
           my $mapresobj;
           my $navmap = Apache::lonnavmaps::navmap->new();
           if (ref($navmap)) {
               $mapresobj = $navmap->getResourceByUrl($mapurl);
           }
           $mapurl=~s{^.*/([^/]+)\.(\w+)$}{$1};
           my $type=$2;
           if (ref($mapresobj)) {
               my $pcslist = $mapresobj->map_hierarchy();
               if ($pcslist ne '') {
                   foreach my $pc (split(/,/,$pcslist)) {
                       next if ($pc <= 1);
                       my $res = $navmap->getByMapPc($pc);
                       if (ref($res)) {
                           my $thisurl = $res->src();
                           $thisurl=~s{^.*/([^/]+)\.\w+$}{$1};
                           my $thistitle = $res->title();
                           $path .= '&'.
                                    &Apache::lonhtmlcommon::entity_encode($thisurl).'&'.
                                    &Apache::lonhtmlcommon::entity_encode($thistitle).
                                    ':'.$res->randompick().
                                    ':'.$res->randomout().
                                    ':'.$res->encrypted().
                                    ':'.$res->randomorder();
                       }
                   }
               }
               $path =~ s/^\&//;
               my $maptitle = $mapresobj->title();
               if ($mapurl eq 'default') {
                   $maptitle = 'Main Course Documents';
               }
               $path .= ($path ne '')? '&' : ''.
                       &Apache::lonhtmlcommon::entity_encode($mapurl).'&'.
                       &Apache::lonhtmlcommon::entity_encode($maptitle).
                       ':'.$mapresobj->randompick().
                       ':'.$mapresobj->randomout().
                       ':'.$mapresobj->encrypted().
                       ':'.$mapresobj->randomorder();
           } else {
               my $maptitle = &gettitle($mapurl);
               if ($mapurl eq 'default') {
                   $maptitle = 'Main Course Documents';
               }
               $path = &Apache::lonhtmlcommon::entity_encode($mapurl).'&'.
                       &Apache::lonhtmlcommon::entity_encode($maptitle).'::::';
           }
           unless ($mapurl eq 'default') {
               $path = 'default&'.
                       &Apache::lonhtmlcommon::entity_encode('Main Course Documents').
                       '::::&'.$path;
           }
       }
       return $path;
   }
   
 sub get_slot {  sub get_slot {
     my ($which,$cnum,$cdom)=@_;      my ($which,$cnum,$cdom)=@_;
     if (!$cnum || !$cdom) {      if (!$cnum || !$cdom) {
Line 12233  of role statuses (active, future or prev Line 12433  of role statuses (active, future or prev
 to restrict the list of roles reported. If no array ref is   to restrict the list of roles reported. If no array ref is 
 provided for types, will default to return only active roles.  provided for types, will default to return only active roles.
   
   =item *
   
   in_course($udom,$uname,$cdom,$cnum,$type,$hideprivileged) : determine if
   user: $uname:$udom has a role in the course: $cdom_$cnum. 
   
   Additional optional arguments are: $type (if role checking is to be restricted 
   to certain user status types -- previous (expired roles), active (currently
   available roles) or future (roles available in the future), and
   $hideprivileged -- if true will not report course roles for users who
   have active Domain Coordinator or Super User roles.
   
 =back  =back
   
 =head2 User Modification  =head2 User Modification
Line 12435  data base, returning a hash that is keye Line 12646  data base, returning a hash that is keye
 values that are the resource value.  I believe that the timestamps and  values that are the resource value.  I believe that the timestamps and
 versions are also returned.  versions are also returned.
   
   
 =back  =back
   
 =head2 Course Modification  =head2 Course Modification
Line 12596  expirespread($uname,$udom,$stype,$usymb) Line 12806  expirespread($uname,$udom,$stype,$usymb)
 devalidate($symb) : devalidate temporary spreadsheet calculations,  devalidate($symb) : devalidate temporary spreadsheet calculations,
 forcing spreadsheet to reevaluate the resource scores next time.  forcing spreadsheet to reevaluate the resource scores next time.
   
   =item * 
   
   can_edit_resource($file,$cnum,$cdom,$resurl,$symb,$group) : determine if current user can edit a particular resource,
   when viewing in course context.
   
    input: six args -- filename (decluttered), course number, course domain,
                       url, symb (if registered) and group (if this is a 
                       group item -- e.g., bulletin board, group page etc.).
   
    output: array of five scalars --
            $cfile -- url for file editing if editable on current server
            $home -- homeserver of resource (i.e., for author if published,
                                             or course if uploaded.).
            $switchserver --  1 if server switch will be needed.
            $forceedit -- 1 if icon/link should be to go to edit mode 
            $forceview -- 1 if icon/link should be to go to view mode
   
   =item *
   
   is_course_upload($file,$cnum,$cdom)
   
   Used in course context to determine if current file was uploaded to 
   the course (i.e., would be found in /userfiles/docs on the course's 
   homeserver.
   
     input: 3 args -- filename (decluttered), course number and course domain.
     output: boolean -- 1 if file was uploaded.
   
 =back  =back
   
 =head2 Storing/Retreiving Data  =head2 Storing/Retreiving Data
Line 13151  Internal notes: Line 13389  Internal notes:
     
  Locks on files (resulting from submission of portfolio file to a homework problem stored in array of arrays.   Locks on files (resulting from submission of portfolio file to a homework problem stored in array of arrays.
   
   =item *
   
 modify_access_controls():  modify_access_controls():
   
 Modifies access controls for a portfolio file  Modifies access controls for a portfolio file
Line 13168  Returns: Line 13408  Returns:
 3. reference to hash of any new or updated access controls.  3. reference to hash of any new or updated access controls.
 4. reference to hash used to map incoming IDs to uniqueIDs assigned to control.  4. reference to hash used to map incoming IDs to uniqueIDs assigned to control.
    key = integer (inbound ID)     key = integer (inbound ID)
    value = uniqueID       value = uniqueID
   
   =item *
   
   get_timebased_id():
   
   Attempts to get a unique timestamp-based suffix for use with items added to a 
   course via the Course Editor (e.g., folders, composite pages, 
   group bulletin boards).
   
   Args: (first three required; six others optional)
   
   1. prefix (alphanumeric): of keys in hash, e.g., suppsequence, docspage,
      docssequence, or name of group
   
   2. keyid (alphanumeric): name of temporary locking key in hash,
      e.g., num, boardids
   
   3. namespace: name of gdbm file used to store suffixes already assigned;  
      file will be named nohist_namespace.db
   
   4. cdom: domain of course; default is current course domain from %env
   
   5. cnum: course number; default is current course number from %env
   
   6. idtype: set to concat if an additional digit is to be appended to the 
      unix timestamp to form the suffix, if the plain timestamp is already
      in use.  Default is to not do this, but simply increment the unix 
      timestamp by 1 until a unique key is obtained.
   
   7. who: holder of locking key; defaults to user:domain for user.
   
   8. locktries: number of attempts to obtain a lock (sleep of 1s before 
      retrying); default is 3.
   
   9. maxtries: number of attempts to obtain a unique suffix; default is 20.  
   
   Returns:
   
   1. suffix obtained (numeric)
   
   2. result of deleting locking key (ok if deleted, or lock never obtained)
   
   3. error: contains (localized) error message if an error occurred.
   
   
 =back  =back
   

Removed from v.1.1194  
changed lines
  Added in v.1.1199


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