File:
[LON-CAPA] /
loncom /
interface /
portfolio.pm
Revision
1.104:
download - view:
text,
annotated -
select for diffs
Fri Jun 16 22:37:10 2006 UTC (18 years ago) by
raeburn
Branches:
MAIN
CVS tags:
HEAD
Enable users to set access controls on portfolio files to permit public viewing. Third iteration of data structure in file_permissions.db for storage of access contol records. Now uses key = value for individual access control records and a key = anonymous hash for fast look-ups of all records for a single file. Use of a temporary lock record to prevent others modifying access control records for a specific portfolio file while the record for the same file is being updated. Additional argument added to call to lonhtmlcommon::datesetter() to optionally suppress display of calendar link.
1: # Copyright Michigan State University Board of Trustees
2: #
3: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
4: #
5: # LON-CAPA is free software; you can redistribute it and/or modify
6: # it under the terms of the GNU General Public License as published by
7: # the Free Software Foundation; either version 2 of the License, or
8: # (at your option) any later version.
9: #
10: # LON-CAPA is distributed in the hope that it will be useful,
11: # but WITHOUT ANY WARRANTY; without even the implied warranty of
12: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: # GNU General Public License for more details.
14: #
15: # You should have received a copy of the GNU General Public License
16: # along with LON-CAPA; if not, write to the Free Software
17: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18: #
19: # /home/httpd/html/adm/gpl.txt
20: #
21: # http://www.lon-capa.org/
22: #
23:
24: package Apache::portfolio;
25: use strict;
26: use Apache::Constants qw(:common :http);
27: use Apache::loncommon;
28: use Apache::lonnet;
29: use Apache::lontexconvert;
30: use Apache::lonfeedback;
31: use Apache::lonlocal;
32: use Apache::lonnet;
33: use Apache::longroup;
34: use lib '/home/httpd/lib/perl';
35: use LONCAPA;
36:
37: # receives a file name and path stub from username/userfiles/portfolio/
38: # returns an anchor tag consisting encoding filename and currentpath
39: sub make_anchor {
40: my ($url, $filename, $current_path, $current_mode, $field_name,
41: $continue_select,$group) = @_;
42: if ($continue_select ne 'true') {$continue_select = 'false'};
43: my $anchor = '<a href="'.$url.'?selectfile='.$filename.'¤tpath='.$current_path.'&mode='.$current_mode.'&continue='.$continue_select.'&fieldname='.$field_name;
44: if (defined($group)) {
45: $anchor .= '&group='.$group;
46: }
47: $anchor .= '">'.$filename.'</a>';
48: return $anchor;
49: }
50: my $dirptr=16384;
51: sub display_common {
52: my ($r,$url,$current_path,$is_empty,$dir_list,$group)=@_;
53: my $groupitem;
54: my $namespace = &get_namespace($group);
55: my $port_path = &get_port_path($group);
56: if (defined($group)) {
57: $groupitem = '<input type="hidden" name="group" value="'.$group.'" />';
58: }
59: my $iconpath= $r->dir_config('lonIconsURL') . "/";
60: my %text=&Apache::lonlocal::texthash('upload' => 'Upload',
61: 'upload_label' =>
62: 'Upload file to current directory:',
63: 'createdir' => 'Create Subdirectory',
64: 'createdir_label' =>
65: 'Create subdirectory in current directory:');
66: $r->print(<<"TABLE");
67: <table border="0" cellspacing="2" cellpadding="2">
68: <form method="post" enctype="multipart/form-data">
69: <tr valign="middle">
70: <td bgcolor="#ccddaa" align="right">
71: $text{'upload_label'}
72: </td>
73: <td bgcolor="#ccddaa" align="left">$groupitem
74: <input name="uploaddoc" type="file" />
75: <input type="hidden" name="currentpath" value="$current_path" />
76: <input type="hidden" name="action" value="$env{"form.action"}" />
77: <input type="hidden" name="fieldname" value="$env{"form.fieldname"}" />
78: <input type="hidden" name="mode" value="$env{"form.mode"}" />
79: <input type="submit" name="storeupl" value="$text{'upload'}" />
80: </td>
81: </tr>
82: </form>
83: <form method="post">
84: <tr>
85: <td bgcolor="#ccddaa" align="right">
86: $text{'createdir_label'}
87: </td>
88: <td bgcolor="#ccddaa" align="left">
89: <input name="newdir" type="input" />$groupitem
90: <input type="hidden" name="currentpath" value="$current_path" />
91: <input type="hidden" name="action" value="$env{"form.action"}" />
92: <input type="hidden" name="fieldname" value="$env{"form.fieldname"}" />
93: <input type="hidden" name="mode" value="$env{"form.mode"}" />
94: <input type="submit" name="createdir" value="$text{'createdir'}" />
95: </td>
96: </tr>
97: </form>
98: </table>
99: TABLE
100: my @tree = split (/\//,$current_path);
101: $r->print('<font size="+2">'.&make_anchor($url,$port_path,'/',$env{"form.mode"},$env{"form.fieldname"},$env{"form.continue"},$group).'/');
102: if (@tree > 1){
103: my $newCurrentPath = '';
104: for (my $i = 1; $i< @tree; $i++){
105: $newCurrentPath .= $tree[$i].'/';
106: $r->print(&make_anchor($url,$tree[$i],'/'.$newCurrentPath, $env{"form.mode"},$env{"form.fieldname"}, $env{"form.continue"},$group).'/');
107: }
108: }
109: $r->print('</font>');
110: &Apache::lonhtmlcommon::store_recent($namespace,$current_path,$current_path);
111: $r->print('<br /><form method=post action="'.$url.'?mode='.$env{"form.mode"}.'&fieldname='.$env{"form.fieldname"});
112: if (defined($group)) {
113: $r->print('&group='.$group);
114: }
115: $r->print('">'.
116: &Apache::lonhtmlcommon::select_recent($namespace,'currentpath',
117: 'this.form.submit();'));
118: $r->print("</form>");
119: }
120: sub display_directory {
121: my ($r,$url,$current_path,$is_empty,$dir_list,$group)=@_;
122: my $iconpath= $r->dir_config('lonIconsURL') . "/";
123: my ($groupitem,$groupecho);
124: my $display_out;
125: my $select_mode;
126: my $checked_files;
127: my $port_path = &get_port_path($group);
128: my ($uname,$udom) = &get_name_dom($group);
129: if (defined($group)) {
130: $groupitem = '<input type="hidden" name="group" value="'.$group.'" />';
131: $groupecho = '&group='.$group;
132: }
133: my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
134: $uname);
135: my %locked_files = &Apache::lonnet::get_marked_as_readonly_hash(
136: $current_permissions,$group);
137: my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group);
138: my $now = time;
139: if ($env{"form.mode"} eq 'selectfile'){
140: &select_files($r);
141: $checked_files =&Apache::lonnet::files_in_path($uname,$env{'form.currentpath'});
142: $select_mode = 'true';
143: }
144: if ($is_empty && ($current_path ne '/')) {
145: $display_out = '<form method="post" action="'.$url.'">'.$groupitem.
146: '<input type="hidden" name="action" value="deletedir" />'.
147: '<input type="submit" name="deletedir" value="'.&mt("Delete Directory").'" />'.
148: '<input type="hidden" name="selectfile" value="" />'.
149: '<input type="hidden" name="currentpath" value="'.$current_path.'" />'.
150: '</form>';
151:
152: $r->print($display_out);
153: return;
154: }
155: if ($select_mode eq 'true') {
156: $r->print('<table border="0" cellspacing="2" cellpadding="2">'.
157: '<tr><th>Select</th><th> </th><th>Name</th><th>Size</th><th>Last Modified</th></tr>');
158: $r->print('<form method="post" name="checkselect" action="'.$url.'">');
159: } else {
160: $r->print('<table border="0" cellspacing="2" cellpadding="2">'.
161: '<tr><th colspan="2">Actions</th><th> </th><th>Name</th><th>Size</th><th>Last Modified</th><th>Current Access Status</th></tr>');
162: $r->print('<form method="post" action="'.$url.'">');
163: }
164: if (defined($group)) {
165: $r->print("\n".$groupitem."\n");
166: }
167: my $href_location="/uploaded/$udom/$uname/$port_path".$current_path;
168: my $href_edit_location="/editupload/$udom/$uname/$port_path".$current_path;
169: foreach my $line (sort
170: {
171: my ($afile)=split('&',$a,2);
172: my ($bfile)=split('&',$b,2);
173: return (lc($afile) cmp lc($bfile));
174: } (@$dir_list)) {
175: #$strip holds directory/file name
176: #$dom
177: my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$line,16);
178: $filename =~ s/\s+$//;
179: if (($filename ne '.') && ($filename ne '..') && ($filename !~ /\.meta$/ ) && ($filename !~ /(.*)\.(\d+)\.([^\.]*)$/)) {
180: if ($dirptr&$testdir) {
181: if ($select_mode eq 'true'){
182: $r->print('<tr bgcolor="#FFAA99"><td><img src="'.$iconpath.'folder_closed.gif"></td>');
183: } else {
184: $r->print('<tr bgcolor="#FFAA99"><td colspan="2"><img src="'.$iconpath.'folder_closed.gif"></td>');
185: }
186: $r->print('<td>Go to ...</td>');
187: $r->print('<td>'.&make_anchor($url,$filename.'/',$current_path.$filename.'/',$env{'form.mode'},$env{"form.fieldname"},$env{'form.continue'},$group).'</td>');
188: $r->print('</tr>');
189: } else {
190: $r->print('<tr bgcolor="#CCCCFF">');
191: my $fullpath = $current_path.$filename;
192: $fullpath = &prepend_group($fullpath,$group);
193: if ($select_mode eq 'true'){
194: $r->print('<td><input type="checkbox" name="checkfile" value="'.$filename.'"');
195: if ($$checked_files{$filename} eq 'selected') {
196: $r->print("CHECKED");
197: }
198: $r->print('></td>');
199: } else {
200: if (exists $locked_files{$fullpath}) {
201: $r->print('<td colspan="2"><a href="'.$url.'?lockinfo='.$current_path.$filename.$groupecho.'">Locked</a></td>');
202: } else {
203: my $cat='<img alt="'.&mt('Catalog Information').
204: '" src="'.&Apache::loncommon::lonhttpdurl('/res/adm/pages/catalog.gif').'" />';
205: $r->print('<td><input type="checkbox" name="selectfile" value="'.$filename.'" />
206: <a href="'.$url.'?rename='.$filename.'&currentpath='.$current_path.$groupecho.'">Rename</a></td>
207: <td><a href="'.$href_edit_location.$filename.'.meta">'.$cat.'</a>
208: </td>');
209: }
210: }
211: my $curr_access;
212: my $pub_access = 0;
213: foreach my $key (sort(keys(%{$access_controls{$fullpath}}))) {
214: my ($scope,$end,$start) = ($key =~ /^[^:]+:([a-z]+)_(\d*)_?(\d*)$/);
215: if (($now > $start) && (!$end || $end > $now)) {
216: if ($scope eq 'public') {
217: $pub_access = 1;
218: }
219: }
220: }
221: if (!$pub_access) {
222: $curr_access = 'Private'
223: } else {
224: $curr_access = 'Public';
225: }
226: $r->print('<td><img src="'.&Apache::loncommon::icon($filename).'"></td>');
227: $r->print('<td><a href="'.$href_location.$filename.'">'.
228: $filename.'</a></td>');
229: $r->print('<td>'.$size.'</td>');
230: $r->print('<td>'.&Apache::lonlocal::locallocaltime($mtime).'</td>');
231: $r->print('<td><nobr>'.&mt($curr_access).' '.
232: '<a href="'.$url.'?access='.$filename.
233: '&currentpath='.$current_path.$groupecho.
234: '">'.&mt('View/Change').'</a></nobr></td>');
235: $r->print('</tr>');
236: }
237: }
238: }
239: if ($select_mode eq 'true') {
240: $r->print('</table>
241: <input type="hidden" name="continue" value="true">
242: <input type="hidden" name="fieldname" value="'.$env{'form.fieldname'}.'">
243: <input type="hidden" name="mode" value="selectfile">
244: <input type="submit" name="submit" value="Select checked files, and continue selecting." /><br />
245: <input type="button" name="doit" onClick= "finishSelect();" value="Select checked files, and close window" />
246: <input type="hidden" name="currentpath" value="'.$current_path.'" />
247: </form>');
248: } else {
249: $r->print('</table>
250: <input type="submit" name="doit" value="Delete Checked Files" />
251: <input type="hidden" name="action" value="delete" />
252: <input type="hidden" name="currentpath" value="'.$current_path.'" />
253: </form>');
254: }
255: }
256:
257: sub open_form {
258: my ($r,$url)=@_;
259: my @files=&Apache::loncommon::get_env_multiple('form.selectfile');
260: $r->print('<form name="portform" method="post" action="'.$url.'">');
261: $r->print('<input type="hidden" name="action" value="'.
262: $env{'form.action'}.'" />');
263: $r->print('<input type="hidden" name="confirmed" value="1" />');
264: foreach (@files) {
265: $r->print('<input type="hidden" name="selectfile" value="'.
266: $_.'" />');
267: }
268: $r->print('<input type="hidden" name="currentpath" value="'.
269: $env{'form.currentpath'}.'" />');
270: }
271:
272: sub close_form {
273: my ($r,$url,$group)=@_;
274: $r->print('<p><input type="submit" value="'.&mt('Continue').'" />');
275: if (defined($group)) {
276: $r->print("\n".'<input type="hidden" name="group" value="'.
277: $group.'" />');
278: }
279: $r->print('</p></form>');
280: $r->print('<form action="'.$url.'" method="POST">
281: <p>
282: <input type="hidden" name="currentpath" value="'.
283: $env{'form.currentpath'}.'" />');
284: if (defined($group)) {
285: $r->print("\n".'<input type="hidden" name="group" value="'.
286: $group.'" />');
287: }
288: $r->print("\n".' <input type="submit" value="'.&mt('Cancel').'" />
289: </p></form>');
290: }
291:
292: sub display_file {
293: my ($path,$filename)=@_;
294: my $display_file_text;
295: if (!defined($path)) { $path=$env{'form.currentpath'}; }
296: if (!defined($filename)) {
297: $filename=$env{'form.selectfile'};
298: $display_file_text = '<tt>'.$path.$filename.'</tt>';
299: } elsif (ref($filename) eq "ARRAY") {
300: foreach (@$filename) {
301: $display_file_text .= '<tt>'.$path.$_.'</tt><br />';
302: }
303: } elsif (ref($filename) eq "SCALAR") {
304: $display_file_text = '<tt>'.$path.$filename.'</tt>';
305: }
306: return $display_file_text;
307: }
308:
309: sub done {
310: my ($message,$url,$group)=@_;
311: unless (defined $message) {
312: $message='Done';
313: }
314: my $result = '<h3><a href="'.$url.'?currentpath='.
315: $env{'form.currentpath'}.
316: '&fieldname='.$env{'form.fieldname'}.
317: '&mode='.$env{'form.mode'};
318: if (defined($group)) {
319: $result .= '&group='.$group;
320: }
321: $result .= '">'.&mt($message).'</a></h3>';
322: return $result;
323: }
324:
325: sub delete {
326: my ($r,$url,$group)=@_;
327: my @check;
328: my $file_name = $env{'form.currentpath'}.$env{'form.selectfile'};
329: $file_name = &prepend_group($file_name,$group);
330: my @files=&Apache::loncommon::get_env_multiple('form.selectfile');
331: my ($uname,$udom) = &get_name_dom($group);
332: if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {
333: $r->print ("The file is locked and cannot be deleted.<br />");
334: $r->print(&done('Back',$url,$group));
335: } else {
336: if (scalar(@files)) {
337: &open_form($r,$url);
338: $r->print('<p>'.&mt('Delete').' '.&display_file(undef,\@files).'?</p>');
339: &close_form($r,$url,$group);
340: } else {
341: $r->print("No file was checked to delete.<br />");
342: $r->print(&done(undef,$url,$group));
343: }
344: }
345: }
346:
347: sub delete_confirmed {
348: my ($r,$url,$group)=@_;
349: my @files=&Apache::loncommon::get_env_multiple('form.selectfile');
350: my $result;
351: my ($uname,$udom) = &get_name_dom($group);
352: my $port_path = &get_port_path($group);
353: foreach my $delete_file (@files) {
354: $result=&Apache::lonnet::removeuserfile($uname,$udom,$port_path.
355: $env{'form.currentpath'}.
356: $delete_file);
357: if ($result ne 'ok') {
358: $r->print('<font color="red"> An error occured ('.$result.
359: ') while trying to delete '.&display_file(undef, $delete_file).'</font><br />');
360: }
361: }
362: $r->print(&done(undef,$url,$group));
363: }
364:
365: sub delete_dir {
366: my ($r,$url,$group)=@_;
367: &open_form($r,$url);
368: $r->print('<p>'.&mt('Delete').' '.&display_file().'?</p>');
369: &close_form($r,$url,$group);
370: }
371:
372: sub delete_dir_confirmed {
373: my ($r,$url,$group)=@_;
374: my $directory_name = $env{'form.currentpath'};
375: $directory_name =~ s|/$||; # remove any trailing slash
376: my ($uname,$udom) = &get_name_dom($group);
377: my $namespace = &get_namespace($group);
378: my $port_path = &get_port_path($group);
379: my $result=&Apache::lonnet::removeuserfile($uname,$udom,$port_path.
380: $directory_name);
381:
382: if ($result ne 'ok') {
383: $r->print('<font color="red"> An error occured (dir) ('.$result.
384: ') while trying to delete '.$directory_name.'</font><br />');
385: } else {
386: # now remove from recent
387: # $r->print('<br /> removing '.$directory_name.'<br /');
388: &Apache::lonhtmlcommon::remove_recent($namespace,[$directory_name.'/']);
389: my @dirs = split m!/!, $directory_name;
390:
391: # $directory_name =~ m/^(\/*\/)(\/*.)$/;
392: $directory_name='/';
393: for (my $i=1; $i < (@dirs - 1); $i ++){
394: $directory_name .= $dirs[$i].'/';
395: }
396: $env{'form.currentpath'} = $directory_name;
397: }
398: $r->print(&done(undef,$url,$group));
399: }
400:
401: sub rename {
402: my ($r,$url,$group)=@_;
403: my $file_name = $env{'form.currentpath'}.$env{'form.rename'};
404: my ($uname,$udom) = &get_name_dom($group);
405: $file_name = &prepend_group($file_name,$group);
406: if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {
407: $r->print ("The file is locked and cannot be renamed.<br />");
408: $r->print(&done(undef,$url,$group));
409: } else {
410: &open_form($r,$url);
411: $r->print('<p>'.&mt('Rename').' '.&display_file().' to
412: <input name="filenewname" type="input" size="50" />?</p>');
413: &close_form($r,$url,$group);
414: }
415: }
416:
417: sub rename_confirmed {
418: my ($r,$url,$group)=@_;
419: my $filenewname=&Apache::lonnet::clean_filename($env{'form.filenewname'});
420: my ($uname,$udom) = &get_name_dom($group);
421: my $port_path = &get_port_path($group);
422: if ($filenewname eq '') {
423: $r->print('<font color="red">'.
424: &mt("Error: no valid filename was provided to rename to.").
425: '</font><br />');
426: $r->print(&done(undef,$url,$group));
427: return;
428: }
429: my $result=
430: &Apache::lonnet::renameuserfile($uname,$udom,
431: $port_path.$env{'form.currentpath'}.$env{'form.selectfile'},
432: $port_path.$env{'form.currentpath'}.$filenewname);
433: if ($result ne 'ok') {
434: $r->print('<font color="red"> An errror occured ('.$result.
435: ') while trying to rename '.&display_file().' to '.
436: &display_file(undef,$filenewname).'</font><br />');
437: }
438: if ($filenewname ne $env{'form.filenewname'}) {
439: $r->print("The new file name was changed from:<br /><strong>".$env{'form.filenewname'}."</strong> to <strong>$filenewname </strong>");
440: }
441: $r->print(&done(undef,$url,$group));
442: }
443:
444: sub display_access {
445: my ($r,$url,$group) = @_;
446: my ($uname,$udom) = &get_name_dom($group);
447: my $file_name = $env{'form.currentpath'}.$env{'form.access'};
448: $file_name = &prepend_group($file_name,$group);
449: my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
450: $uname);
451: my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group,$file_name);
452: &open_form($r,$url);
453: $r->print('<h3>'.&mt('Allowing others to retrieve portfolio file: [_1]',$env{'form.currentpath'}.$env{'form.access'}).'</h3>'."\n");
454: $r->print(&mt('Access to this file by others can be set to be one the following types: public.').'<br /><ul><li>'.&mt('Public files are available to anyone without the need for login.').'</li></ul><br />');
455: &access_setting_table($r,$access_controls{$file_name});
456: &close_form($r,$url,$group);
457: }
458:
459: sub update_access {
460: my ($r,$url,$group) = @_;
461: my $totalprocessed = 0;
462: my %processing;
463: my %title = (
464: 'activate' => 'New controls added',
465: 'delete' => 'Existing controls deleted',
466: 'update' => 'Existing controls modified',
467: );
468: my $changes;
469: foreach my $chg (sort(keys(%title))) {
470: @{$processing{$chg}} = &Apache::loncommon::get_env_multiple('form.'.$chg);
471: $totalprocessed += @{$processing{$chg}};
472: foreach my $num (@{$processing{$chg}}) {
473: my $scope = $env{'form.scope_'.$num};
474: my ($start,$end) = &get_dates_from_form($num);
475: my $newkey = $num.':'.$scope.'_'.$end.'_'.$start;
476: if ($chg eq 'delete') {
477: $$changes{$chg}{$newkey} = 1;
478: } else {
479: $$changes{$chg}{$newkey} =
480: &build_access_record($num,$scope,$start,$end);
481: }
482: }
483: }
484: my $file_name = $env{'form.currentpath'}.$env{'form.selectfile'};
485: $r->print('<h3>'.&mt('Allowing others to retrieve portfolio file: [_1]',$file_name).'</h3>'."\n");
486: $file_name = &prepend_group($file_name,$group);
487: my ($uname,$udom) = &get_name_dom($group);
488: my ($errors,$outcome,$deloutcome,$new_values,$translation);
489: if ($totalprocessed) {
490: ($outcome,$deloutcome,$new_values,$translation) =
491: &Apache::lonnet::modify_access_controls($file_name,$changes,$udom,$uname);
492: }
493: my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom, $uname);
494: my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group,$file_name);
495: if ($totalprocessed) {
496: if ($outcome eq 'ok') {
497: my $updated_controls = $access_controls{$file_name};
498: my ($showstart,$showend);
499: $r->print(&Apache::loncommon::start_data_table());
500: $r->print(&Apache::loncommon::start_data_table_row());
501: $r->print('<th>'.&mt('Type of change').'</th><th>'.&mt('Access control').'</th><th>'.&mt('Start date').'</th><th>'.&mt('End date').'</th>');
502: $r->print(&Apache::loncommon::end_data_table_row());
503: foreach my $chg (sort(keys(%processing))) {
504: if (@{$processing{$chg}} > 0) {
505: if ($chg eq 'delete') {
506: if (!($deloutcome eq 'ok')) {
507: $errors .= &mt('A problem occurred deleting access controls: [_1]',$deloutcome);
508: next;
509: }
510: }
511: my $numchgs = @{$processing{$chg}};
512: $r->print(&Apache::loncommon::start_data_table_row());
513: $r->print('<td rowspan="'.$numchgs.'">'.&mt($title{$chg}).'.</td>');
514: my $count = 0;
515: foreach my $key (sort(keys(%{$$changes{$chg}}))) {
516: if ($count) {
517: $r->print(&Apache::loncommon::start_data_table_row());
518: }
519: my ($num,$scope,$end,$start) =
520: ($key =~ /^([^:]+):([a-z]+)_(\d*)_?(\d*)$/);
521: my $newkey = $key;
522: if ($chg eq 'activate') {
523: $newkey =~ s/^(\d+)/$$translation{$1}/;
524: }
525: my %content = &Apache::lonnet::parse_access_controls(
526: $$updated_controls{$newkey});
527: if ($chg eq 'delete') {
528: $showstart = &mt('Deleted');
529: $showend = $showstart;
530: } else {
531: $showstart = localtime($start);
532: if ($end == 0) {
533: $showend = &mt('No end date');
534: } else {
535: $showend = localtime($end);
536: }
537: }
538: $r->print('<td>'.&mt($scope).'</td><td>'.$showstart.
539: '</td><td>'. $showend.'</td>');
540: $r->print(&Apache::loncommon::end_data_table_row());
541: $count ++;
542: }
543: }
544: }
545: $r->print(&Apache::loncommon::end_data_table());
546: } else {
547: if ((@{$processing{'activate'}} > 0) || (@{$processing{'update'}} > 0)) {
548: $errors .= &mt('A problem occurred storing access control settings: [_1]',$outcome);
549: }
550: }
551: if ($errors) {
552: $r->print($errors);
553: }
554: }
555: $r->print('<br /><a href="'.$url.'?access='.$env{'form.selectfile'}.'¤tpath='.$env{'form.currentpath'}.'">'.&mt('Display all access settings for this file').'</a>');
556: return;
557: }
558:
559: sub build_access_record {
560: my ($num,$scope,$start,$end) = @_;
561: my $record = '<scope type="'.$scope.'"><start>'.$start.'</start><end>'.$end.
562: '</end></scope>';
563: return $record;
564: }
565:
566: sub get_dates_from_form {
567: my ($id) = @_;
568: my $startdate;
569: my $enddate;
570: $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate_'.$id);
571: $enddate = &Apache::lonhtmlcommon::get_date_from_form('enddate_'.$id);
572: if ( exists ($env{'form.noend_'.$id}) ) {
573: $enddate = 0;
574: }
575: return ($startdate,$enddate);
576: }
577:
578: sub access_setting_table {
579: my ($r,$access_controls) = @_;
580: my ($public,$publictext);
581: $publictext = '<b>'.&mt('Off').'</b>';
582: my ($guest,$guesttext);
583: $guesttext = '<b>'.&mt('Off').'</b>';
584: my @courses = ();
585: my @groups = ();
586: my @domains = ();
587: my @users = ();
588: my $now = time;
589: my $then = $now + (60*60*24*180); # six months approx.
590: foreach my $key (sort(keys(%{$access_controls}))) {
591: my ($scope) = ($key =~ /^[^:]+:([a-z]+)_\d*_?\d*$/);
592: if ($scope eq 'public') {
593: $public = $key;
594: $publictext = '<b>'.&mt('On').'</b>';
595: }
596: }
597: $r->print(&Apache::loncommon::start_data_table());
598: $r->print(&Apache::loncommon::start_data_table_row());
599: $r->print('<th>'.&mt('Access Type').'</th><th colspan="3">'.
600: &mt('Settings').'</th>'."\n");
601: $r->print(&Apache::loncommon::end_data_table_row());
602: $r->print(&Apache::loncommon::start_data_table_row());
603: $r->print('<td><b>Public</b><br />'.$publictext.'</td><td colspan="3">');
604: $r->print(&Apache::loncommon::start_data_table());
605: $r->print(&Apache::loncommon::start_data_table_row());
606: my ($pub_startdate,$pub_enddate,$pub_action,$pub_noend);
607: if ($public) {
608: my ($num,$end,$start) = ($public =~ /^([^:]+):[a-z]+_(\d*)_?(\d*)$/);
609: if ($end == 0) {
610: $pub_noend = 'checked="checked"';
611: }
612: $pub_action = '<td><input type="checkbox" name="delete" value="'.$num.
613: '" />'.&mt('Delete').'<br /><input type="checkbox" '.
614: 'name="update" value="'.$num.'" />'.&mt('Update').
615: '<input type="hidden" name="scope_'.$num.'"'.
616: ' value="public" /></td>';
617: $pub_startdate = &Apache::lonhtmlcommon::date_setter('portform',
618: 'startdate_'.$num,$start,undef,undef,undef,1,undef,
619: undef,undef,1);
620: $pub_enddate = &Apache::lonhtmlcommon::date_setter('portform',
621: 'enddate_'.$num,$end,undef,undef,undef,1,undef,
622: undef,undef,1).
623: ' <nobr><input type="checkbox" name="noend_'.
624: $num.'" '.$pub_noend.' />'.&mt('No end date').'</nobr>';
625: } else {
626: $pub_action = '<input type="checkbox" name="activate" value="0" />'.
627: &mt('Activate').
628: '<input type="hidden" name="scope_0" value="public" />';
629: $pub_startdate = &Apache::lonhtmlcommon::date_setter('portform',
630: 'startdate_0',$now,undef,undef,undef,1,undef,
631: undef,undef,1);
632: $pub_enddate = &Apache::lonhtmlcommon::date_setter('portform',
633: 'enddate_0',$then,,undef,undef,undef,1,undef,
634: undef,undef,1).
635: '  <nobr><input type="checkbox" '.
636: 'name="noend_0" />'.&mt('No end date').
637: '</nobr>';
638:
639: }
640: $r->print('<td>'.$pub_action.'</td><td>'.&mt('Start: ').$pub_startdate.
641: '<br />'.&mt('End: ').$pub_enddate.'</td>');
642: $r->print(&Apache::loncommon::end_data_table_row());
643: $r->print(&Apache::loncommon::end_data_table());
644: $r->print('</td>');
645: $r->print(&Apache::loncommon::end_data_table_row());
646: $r->print(&Apache::loncommon::end_data_table());
647: }
648:
649: sub select_files {
650: my ($r,$group) = @_;
651: if ($env{'form.continue'} eq 'true') {
652: # here we update the selections for the currentpath
653: # eventually, have to handle removing those not checked, but . . .
654: my @items=&Apache::loncommon::get_env_multiple('form.checkfile');
655: if (scalar(@items)){
656: &Apache::lonnet::save_selected_files($env{'user.name'}, $env{'form.currentpath'}, @items);
657: }
658: } else {
659: #empty the file for a fresh start
660: &Apache::lonnet::clear_selected_files($env{'user.name'});
661: }
662: my @files = &Apache::lonnet::files_not_in_path($env{'user.name'}, $env{'form.currentpath'});
663: my $java_files = join ",", @files;
664: if ($java_files) {
665: $java_files.=',';
666: }
667: my $javascript =(<<ENDSMP);
668: <script language='javascript'>
669: function finishSelect() {
670: ENDSMP
671: $javascript .= 'fileList = "'.$java_files.'";';
672: $javascript .= (<<ENDSMP);
673: for (i=0;i<document.forms.checkselect.length;i++) {
674: if (document.forms.checkselect[i].checked){
675: fileList = fileList + document.forms.checkselect.currentpath.value + document.forms.checkselect[i].value + "," ;
676: }
677: }
678: opener.document.forms.lonhomework.
679: ENDSMP
680: $javascript .= $env{'form.fieldname'};
681: $javascript .= (<<ENDSMP);
682: .value=fileList;
683: self.close();
684: }
685: </script>
686: ENDSMP
687: $r->print($javascript);
688: $r->print("<h1>Select portfolio files</h1>
689: Check as many as you wish in response to the problem.<br />");
690: my @otherfiles=&Apache::lonnet::files_not_in_path($env{'user.name'}, $env{'form.currentpath'});
691: if (@otherfiles) {
692: $r->print("<strong>Files selected from other directories:</strong><br />");
693: foreach my $file (@otherfiles) {
694: $r->print($file."<br />");
695: }
696: }
697: }
698: sub upload {
699: my ($r,$url,$group)=@_;
700: my $fname=$env{'form.uploaddoc.filename'};
701: my $filesize = (length($env{'form.uploaddoc'})) / 1000; #express in k (1024?)
702: my $disk_quota = 20000; # expressed in k
703: $fname=&Apache::lonnet::clean_filename($fname);
704:
705: my $portfolio_root=&get_portfolio_root($group);
706: my ($uname,$udom) = &get_name_dom($group);
707: my $port_path = &get_port_path($group);
708: # Fixme --- Move the checking for existing file to LOND error return
709: my @dir_list=&get_dir_list($portfolio_root,$group);
710: my $found_file = 0;
711: my $locked_file = 0;
712: foreach my $line (@dir_list) {
713: my ($file_name)=split(/\&/,$line,2);
714: if ($file_name eq $fname){
715: $file_name = $env{'form.currentpath'}.$file_name;
716: $file_name = &prepend_group($file_name,$group);
717: $found_file = 1;
718: if (defined($group)) {
719: $file_name = $group.'/'.$file_name;
720: }
721: if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {
722: $locked_file = 1;
723: }
724: }
725: }
726: my $current_disk_usage = &Apache::lonnet::diskusage($udom,$uname,$portfolio_root);
727: if (($current_disk_usage + $filesize) > $disk_quota){
728: $r->print('<font color="red">Unable to upload <strong>'.$fname.' (size = '.$filesize.' kilobytes)</strong>. Disk quota will be exceeded.'.
729: '<br />Disk quota is '.$disk_quota.' kilobytes. Your current disk usage is '.$current_disk_usage.' kilobytes.');
730: $r->print(&done('Back',$url,$group));
731: }
732: elsif ($found_file){
733: if ($locked_file){
734: $r->print('<font color="red">Unable to upload <strong>'.$fname.'</strong>, a <strong>locked</strong> file by that name was found in <strong>'.$port_path.$env{'form.currentpath'}.'</strong></font>'.
735: '<br />You will be able to rename or delete existing '.$fname.' after a grade has been assigned.');
736: $r->print(&done('Back',$url,$group));
737: } else {
738: $r->print('<font color="red">Unable to upload <strong>'.$fname.'</strong>, a file by that name was found in <strong>'.$port_path.$env{'form.currentpath'}.'</strong></font>'.
739: '<br />To upload, rename or delete existing '.$fname.' in '.$port_path.$env{'form.currentpath'});
740: $r->print(&done('Back',$url,$group));
741: }
742: } else {
743: my $result=&Apache::lonnet::userfileupload('uploaddoc','',
744: $port_path.$env{'form.currentpath'});
745: if ($result !~ m|^/uploaded/|) {
746: $r->print('<font color="red"> An errror occured ('.$result.
747: ') while trying to upload '.&display_file().'</font><br />');
748: $r->print(&done('Back',$url,$group));
749: } else {
750: $r->print(&done(undef,$url,$group));
751: }
752: }
753: }
754: sub lock_info {
755: my ($r,$url,$group) = @_;
756: my ($uname,$udom) = &get_name_dom($group);
757: my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
758: $uname);
759: my $file_name = $env{'form.lockinfo'};
760: $file_name = &prepend_group($file_name,$group);
761: if (defined($file_name) && defined($$current_permissions{$file_name})) {
762: foreach my $array_item (@{$$current_permissions{$file_name}}) {
763: if (ref($array_item) eq 'ARRAY') {
764: my $filetext;
765: if (defined($group)) {
766: $filetext = '<strong>'.$env{'form.lockinfo'}.
767: '</strong> (group: '.$group.')';
768: } else {
769: $filetext = '<strong>'.$file_name.'</strong>';
770: }
771: $r->print(&mt('[_1] was submitted in response to problem: ',
772: $filetext).
773: '<strong>'.&Apache::lonnet::gettitle($$array_item[0]).
774: '</strong><br />');
775: my %course_description = &Apache::lonnet::coursedescription($$array_item[1]);
776: $r->print(&mt('In the course: <strong>[_1]</strong><br />',
777: $course_description{'description'}));
778: # $r->print('the third is '.$$array_item[2].'<br>');
779: # $r->print("item is $$array_item[0]<br> and $$array_item[0]");
780: }
781: }
782: }
783: $r->print(&done('Back',$url,$group));
784: return 'ok';
785: }
786: sub createdir {
787: my ($r,$url,$group)=@_;
788: my $newdir=&Apache::lonnet::clean_filename($env{'form.newdir'});
789: if ($newdir eq '') {
790: $r->print('<font color="red">'.
791: &mt("Error: no directory name was provided.").
792: '</font><br />');
793: $r->print(&done(undef,$url,$group));
794: return;
795: }
796: my $portfolio_root = &get_portfolio_root($group);
797: my @dir_list=&get_dir_list($portfolio_root,$group);
798: my $found_file = 0;
799: foreach my $line (@dir_list) {
800: my ($filename)=split(/\&/,$line,2);
801: if ($filename eq $newdir){
802: $found_file = 1;
803: }
804: }
805: if ($found_file){
806: $r->print('<font color="red"> Unable to create a directory named <strong>'.$newdir.
807: ' </strong>a file or directory by that name already exists.</font><br />');
808: } else {
809: my ($uname,$udom) = &get_name_dom($group);
810: my $port_path = &get_port_path($group);
811: my $result=&Apache::lonnet::mkdiruserfile($uname,$udom,
812: $port_path.$env{'form.currentpath'}.$newdir);
813: if ($result ne 'ok') {
814: $r->print('<font color="red"> An errror occured ('.$result.
815: ') while trying to create a new directory '.&display_file().'</font><br />');
816: }
817: }
818: if ($newdir ne $env{'form.newdir'}) {
819: $r->print("The new directory name was changed from:<br /><strong>".$env{'form.newdir'}."</strong> to <strong>$newdir </strong>");
820: }
821: $r->print(&done(undef,$url,$group));
822: }
823:
824: sub get_portfolio_root {
825: my ($group) = @_;
826: my ($portfolio_root,$udom,$uname,$path);
827: ($uname,$udom) = &get_name_dom($group);
828: if (defined($group)) {
829: $path = '/userfiles/groups/'.$group.'/portfolio';
830: } else {
831: $path = '/userfiles/portfolio';
832: }
833: return (&Apache::loncommon::propath($udom,$uname).$path);
834: }
835:
836: sub get_dir_list {
837: my ($portfolio_root,$group) = @_;
838: my ($uname,$udom) = &get_name_dom($group);
839: return &Apache::lonnet::dirlist($env{'form.currentpath'},
840: $udom,$uname,$portfolio_root);
841: }
842:
843: sub get_name_dom {
844: my ($group) = @_;
845: my ($uname,$udom);
846: if (defined($group)) {
847: $udom = $env{'course.'.$env{'request.course.id'}.'.domain'};
848: $uname = $env{'course.'.$env{'request.course.id'}.'.num'};
849: } else {
850: $udom = $env{'user.domain'};
851: $uname = $env{'user.name'};
852: }
853: return ($uname,$udom);
854: }
855:
856: sub prepend_group {
857: my ($filename,$group) = @_;
858: if (defined($group)) {
859: $filename = $group.'/'.$filename;
860: }
861: return $filename;
862: }
863:
864: sub get_namespace {
865: my ($group) = @_;
866: my $namespace = 'portfolio';
867: if (defined($group)) {
868: my ($uname,$udom) = &get_name_dom($group);
869: $namespace .= '_'.$udom.'_'.$uname.'_'.$group;
870: }
871: return $namespace;
872: }
873:
874: sub get_port_path {
875: my ($group) = @_;
876: my $port_path;
877: if (defined($group)) {
878: $port_path = "groups/$group/portfolio";
879: } else {
880: $port_path = 'portfolio';
881: }
882: return $port_path;
883: }
884:
885: sub handler {
886: # this handles file management
887: my $r = shift;
888: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
889: ['selectfile','currentpath','meta','lockinfo','currentfile',
890: 'action','fieldname','mode','rename','continue','group','access']);
891: my ($uname,$udom,$portfolio_root,$url,$group,$caller,$title);
892: if ($r->uri =~ m|^(/adm/)([^/]+)|) {
893: $url = $1.$2;
894: $caller = $2;
895: }
896: if ($caller eq 'coursegrp_portfolio') {
897: # Needs to be in a course
898: if (! ($env{'request.course.fn'})) {
899: # Not in a course
900: $env{'user.error.msg'}=
901: "/adm/coursegrp_portfolio:rgf:0:0:Cannot view group portfolio";
902: return HTTP_NOT_ACCEPTABLE;
903: }
904: my $earlyout = 0;
905: my $view_permission = &Apache::lonnet::allowed('vcg',
906: $env{'request.course.id'});
907: $group = $env{'form.group'};
908: $group =~ s/\W//g;
909: if ($group) {
910: ($uname,$udom) = &get_name_dom($group);
911: my %curr_groups = &Apache::longroup::coursegroups($udom,$uname,
912: $group);
913: if (%curr_groups) {
914: if (($view_permission) || (&Apache::lonnet::allowed('rgf',
915: $env{'request.course.id'}.'/'.$group))) {
916: $portfolio_root = &get_portfolio_root($group);
917: } else {
918: $r->print('You do not have the privileges required to access the shared files space for this group');
919: $earlyout = 1;
920: }
921: } else {
922: $r->print('Not a valid group for this course');
923: $earlyout = 1;
924: }
925: $title = &mt('Group files').' for '.$group;
926: } else {
927: $r->print('Invalid group');
928: $earlyout = 1;
929: }
930: if ($earlyout) { return OK; }
931: } else {
932: ($uname,$udom) = &get_name_dom();
933: $portfolio_root = &get_portfolio_root();
934: $title = &mt('Portfolio Manager');
935: }
936:
937: &Apache::loncommon::no_cache($r);
938: &Apache::loncommon::content_type($r,'text/html');
939: $r->send_http_header;
940: # Give the LON-CAPA page header
941: if ($env{"form.mode"} eq 'selectfile'){
942: $r->print(&Apache::loncommon::start_page($title,undef,
943: {'only_body' => 1}));
944: } else {
945: $r->print(&Apache::loncommon::start_page($title));
946: }
947: $r->rflush();
948: if (($env{'form.storeupl'}) & (!$env{'form.uploaddoc.filename'})){
949: $r->print('<font color="red"> No file was selected to upload.'.
950: 'To upload a file, click <strong>Browse...</strong>'.
951: ', select a file, then click <strong>Upload</strong>,</font>');
952: }
953: if ($env{'form.meta'}) {
954: &open_form($r,$url);
955: # $r->print(&edit_meta_data($r, $env{'form.currentpath'}.$env{'form.selectfile'}));
956: $r->print('Edit the meta data<br />');
957: &close_form($r,$url,$group);
958: }
959: if ($env{'form.store'}) {
960: }
961:
962: if ($env{'form.uploaddoc.filename'}) {
963: &upload($r,$url,$group);
964: } elsif ($env{'form.action'} eq 'delete' && $env{'form.confirmed'}) {
965: &delete_confirmed($r,$url,$group);
966: } elsif ($env{'form.action'} eq 'delete') {
967: &delete($r,$url,$group);
968: } elsif ($env{'form.action'} eq 'deletedir' && $env{'form.confirmed'}) {
969: &delete_dir_confirmed($r,$url,$group);
970: } elsif ($env{'form.action'} eq 'deletedir'){
971: &delete_dir($r,$url,$group);
972: } elsif ($env{'form.action'} eq 'rename' && $env{'form.confirmed'}) {
973: &rename_confirmed($r,$url,$group);
974: } elsif ($env{'form.rename'}) {
975: $env{'form.selectfile'} = $env{'form.rename'};
976: $env{'form.action'} = 'rename';
977: &rename($r,$url,$group);
978: } elsif ($env{'form.access'}) {
979: $env{'form.selectfile'} = $env{'form.access'};
980: $env{'form.action'} = 'chgaccess';
981: &display_access($r,$url,$group);
982: } elsif ($env{'form.action'} eq 'chgaccess') {
983: &update_access($r,$url,$group);
984: } elsif ($env{'form.createdir'}) {
985: &createdir($r,$url,$group);
986: } elsif ($env{'form.lockinfo'}) {
987: &lock_info($r,$url,$group);
988: } else {
989: my $current_path='/';
990: if ($env{'form.currentpath'}) {
991: $current_path = $env{'form.currentpath'};
992: }
993: my @dir_list=&get_dir_list($portfolio_root,$group);
994: if ($dir_list[0] eq 'no_such_dir'){
995: # two main reasons for this:
996: # 1) never been here, so directory structure not created
997: # 2) back-button navigation after deleting a directory
998: if ($current_path eq '/'){
999: &Apache::lonnet::mkdiruserfile($uname,$udom,
1000: &get_port_path($group));
1001: } else {
1002: # some directory that snuck in get rid of the directory
1003: # from the recent pulldown, just in case
1004: &Apache::lonhtmlcommon::remove_recent('portfolio',
1005: [$current_path]);
1006: $current_path = '/'; # force it back to the root
1007: }
1008: # now grab the directory list again, for the first time
1009: @dir_list=&Apache::lonnet::dirlist($current_path,
1010: $udom,$uname,$portfolio_root);
1011: }
1012: # need to know if directory is empty so it can be removed if desired
1013: my $is_empty=(@dir_list == 2);
1014: &display_common($r,$url,$current_path,$is_empty,\@dir_list,$group);
1015: &display_directory($r,$url,$current_path,$is_empty,\@dir_list,$group);
1016: $r->print(&Apache::loncommon::end_page());
1017: }
1018: return OK;
1019: }
1020: 1;
1021: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>