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: my @dir_lines;
170: my %versioned;
171: foreach my $line (sort
172: {
173: my ($afile)=split('&',$a,2);
174: my ($bfile)=split('&',$b,2);
175: return (lc($afile) cmp lc($bfile));
176: } (@$dir_list)) {
177: #$strip holds directory/file name
178: #$dom
179: my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$line,16);
180: $filename =~ s/\s+$//;
181: my ($fname,$version,$extension) = &Apache::grades::file_name_version_ext($filename);
182: if ($version) {
183: $versioned{$fname} .= $version.",";
184: }
185: push(@dir_lines, [$filename,$dom,$testdir,$size,$mtime,$obs]);
186: }
187: foreach my $line (@dir_lines) {
188: my ($filename,$dom,$testdir,$size,$mtime,$obs) = @$line;
189: my ($fname,$version,$extension) = &Apache::grades::file_name_version_ext($filename);
190: if (($filename ne '.') && ($filename ne '..') && ($filename !~ /\.meta$/ ) && ($filename !~ /(.*)\.(\d+)\.([^\.]*)$/)) {
191: if ($dirptr&$testdir) {
192: if ($select_mode eq 'true'){
193: $r->print('<tr bgcolor="#FFAA99"><td><img src="'.$iconpath.'folder_closed.gif"></td>');
194: } else {
195: $r->print('<tr bgcolor="#FFAA99"><td colspan="2"><img src="'.$iconpath.'folder_closed.gif"></td>');
196: }
197: $r->print('<td>Go to ...</td>');
198: $r->print('<td>'.&make_anchor($url,$filename.'/',$current_path.$filename.'/',$env{'form.mode'},$env{"form.fieldname"},$env{'form.continue'},$group).'</td>');
199: $r->print('</tr>');
200: } else {
201: $r->print('<tr bgcolor="#CCCCFF">');
202: my $version_flag;
203: if (exists($versioned{$fname})) {
204: $version_flag = "*";
205: } else {
206: $version_flag = "";
207: }
208: my $fullpath = $current_path.$filename;
209: $fullpath = &prepend_group($fullpath,$group);
210: if ($select_mode eq 'true'){
211: $r->print('<td><input type="checkbox" name="checkfile" value="'.$filename.'"');
212: if ($$checked_files{$filename} eq 'selected') {
213: $r->print("CHECKED");
214: }
215: $r->print('></td>');
216: } else {
217: if (exists $locked_files{$fullpath}) {
218: $r->print('<td colspan="2"><a href="'.$url.'?lockinfo='.$current_path.$filename.$groupecho.'">Locked</a></td>');
219: } else {
220: my $cat='<img alt="'.&mt('Catalog Information').
221: '" src="'.&Apache::loncommon::lonhttpdurl('/res/adm/pages/catalog.gif').'" />';
222: $r->print('<td><input type="checkbox" name="selectfile" value="'.$filename.'" />
223: <a href="'.$url.'?rename='.$filename.'&currentpath='.$current_path.$groupecho.'">Rename</a></td>
224: <td><a href="'.$href_edit_location.$filename.'.meta">'.$cat.'</a>
225: </td>');
226: }
227: }
228: my $curr_access;
229: my $pub_access = 0;
230: foreach my $key (sort(keys(%{$access_controls{$fullpath}}))) {
231: my ($scope,$end,$start) = ($key =~ /^[^:]+:([a-z]+)_(\d*)_?(\d*)$/);
232: if (($now > $start) && (!$end || $end > $now)) {
233: if ($scope eq 'public') {
234: $pub_access = 1;
235: }
236: }
237: }
238: if (!$pub_access) {
239: $curr_access = 'Private'
240: } else {
241: $curr_access = 'Public';
242: }
243: $r->print('<td><img src="'.&Apache::loncommon::icon($filename).'"></td>');
244: $r->print('<td><a href="'.$href_location.$filename.'">'.
245: $filename.'</a></td>');
246: $r->print('<td>'.$size.'</td>');
247: $r->print('<td>'.&Apache::lonlocal::locallocaltime($mtime).'</td>');
248: $r->print('<td><nobr>'.&mt($curr_access).' '.
249: '<a href="'.$url.'?access='.$filename.
250: '&currentpath='.$current_path.$groupecho.
251: '">'.&mt('View/Change').'</a></nobr></td>');
252: $r->print('</tr>');
253: }
254: }
255: }
256: if ($select_mode eq 'true') {
257: $r->print('</table>
258: <input type="hidden" name="continue" value="true">
259: <input type="hidden" name="fieldname" value="'.$env{'form.fieldname'}.'">
260: <input type="hidden" name="mode" value="selectfile">
261: <input type="submit" name="submit" value="Select checked files, and continue selecting." /><br />
262: <input type="button" name="doit" onClick= "finishSelect();" value="Select checked files, and close window" />
263: <input type="hidden" name="currentpath" value="'.$current_path.'" />
264: </form>');
265: } else {
266: $r->print('</table>
267: <input type="submit" name="doit" value="Delete Checked Files" />
268: <input type="hidden" name="action" value="delete" />
269: <input type="hidden" name="currentpath" value="'.$current_path.'" />
270: </form>');
271: }
272: }
273:
274: sub open_form {
275: my ($r,$url)=@_;
276: my @files=&Apache::loncommon::get_env_multiple('form.selectfile');
277: $r->print('<form name="portform" method="post" action="'.$url.'">');
278: $r->print('<input type="hidden" name="action" value="'.
279: $env{'form.action'}.'" />');
280: $r->print('<input type="hidden" name="confirmed" value="1" />');
281: foreach (@files) {
282: $r->print('<input type="hidden" name="selectfile" value="'.
283: $_.'" />');
284: }
285: $r->print('<input type="hidden" name="currentpath" value="'.
286: $env{'form.currentpath'}.'" />');
287: }
288:
289: sub close_form {
290: my ($r,$url,$group)=@_;
291: $r->print('<p><input type="submit" value="'.&mt('Continue').'" />');
292: if (defined($group)) {
293: $r->print("\n".'<input type="hidden" name="group" value="'.
294: $group.'" />');
295: }
296: $r->print('</p></form>');
297: $r->print('<form action="'.$url.'" method="POST">
298: <p>
299: <input type="hidden" name="currentpath" value="'.
300: $env{'form.currentpath'}.'" />');
301: if (defined($group)) {
302: $r->print("\n".'<input type="hidden" name="group" value="'.
303: $group.'" />');
304: }
305: $r->print("\n".' <input type="submit" value="'.&mt('Cancel').'" />
306: </p></form>');
307: }
308:
309: sub display_file {
310: my ($path,$filename)=@_;
311: my $display_file_text;
312: if (!defined($path)) { $path=$env{'form.currentpath'}; }
313: if (!defined($filename)) {
314: $filename=$env{'form.selectfile'};
315: $display_file_text = '<tt>'.$path.$filename.'</tt>';
316: } elsif (ref($filename) eq "ARRAY") {
317: foreach (@$filename) {
318: $display_file_text .= '<tt>'.$path.$_.'</tt><br />';
319: }
320: } elsif (ref($filename) eq "SCALAR") {
321: $display_file_text = '<tt>'.$path.$filename.'</tt>';
322: }
323: return $display_file_text;
324: }
325:
326: sub done {
327: my ($message,$url,$group)=@_;
328: unless (defined $message) {
329: $message='Done';
330: }
331: my $result = '<h3><a href="'.$url.'?currentpath='.
332: $env{'form.currentpath'}.
333: '&fieldname='.$env{'form.fieldname'}.
334: '&mode='.$env{'form.mode'};
335: if (defined($group)) {
336: $result .= '&group='.$group;
337: }
338: $result .= '">'.&mt($message).'</a></h3>';
339: return $result;
340: }
341:
342: sub delete {
343: my ($r,$url,$group)=@_;
344: my @check;
345: my $file_name = $env{'form.currentpath'}.$env{'form.selectfile'};
346: $file_name = &prepend_group($file_name,$group);
347: my @files=&Apache::loncommon::get_env_multiple('form.selectfile');
348: my ($uname,$udom) = &get_name_dom($group);
349: if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {
350: $r->print ("The file is locked and cannot be deleted.<br />");
351: $r->print(&done('Back',$url,$group));
352: } else {
353: if (scalar(@files)) {
354: &open_form($r,$url);
355: $r->print('<p>'.&mt('Delete').' '.&display_file(undef,\@files).'?</p>');
356: &close_form($r,$url,$group);
357: } else {
358: $r->print("No file was checked to delete.<br />");
359: $r->print(&done(undef,$url,$group));
360: }
361: }
362: }
363:
364: sub delete_confirmed {
365: my ($r,$url,$group)=@_;
366: my @files=&Apache::loncommon::get_env_multiple('form.selectfile');
367: my $result;
368: my ($uname,$udom) = &get_name_dom($group);
369: my $port_path = &get_port_path($group);
370: foreach my $delete_file (@files) {
371: $result=&Apache::lonnet::removeuserfile($uname,$udom,$port_path.
372: $env{'form.currentpath'}.
373: $delete_file);
374: if ($result ne 'ok') {
375: $r->print('<font color="red"> An error occured ('.$result.
376: ') while trying to delete '.&display_file(undef, $delete_file).'</font><br />');
377: }
378: }
379: $r->print(&done(undef,$url,$group));
380: }
381:
382: sub delete_dir {
383: my ($r,$url,$group)=@_;
384: &open_form($r,$url);
385: $r->print('<p>'.&mt('Delete').' '.&display_file().'?</p>');
386: &close_form($r,$url,$group);
387: }
388:
389: sub delete_dir_confirmed {
390: my ($r,$url,$group)=@_;
391: my $directory_name = $env{'form.currentpath'};
392: $directory_name =~ s|/$||; # remove any trailing slash
393: my ($uname,$udom) = &get_name_dom($group);
394: my $namespace = &get_namespace($group);
395: my $port_path = &get_port_path($group);
396: my $result=&Apache::lonnet::removeuserfile($uname,$udom,$port_path.
397: $directory_name);
398:
399: if ($result ne 'ok') {
400: $r->print('<font color="red"> An error occured (dir) ('.$result.
401: ') while trying to delete '.$directory_name.'</font><br />');
402: } else {
403: # now remove from recent
404: # $r->print('<br /> removing '.$directory_name.'<br /');
405: &Apache::lonhtmlcommon::remove_recent($namespace,[$directory_name.'/']);
406: my @dirs = split m!/!, $directory_name;
407:
408: # $directory_name =~ m/^(\/*\/)(\/*.)$/;
409: $directory_name='/';
410: for (my $i=1; $i < (@dirs - 1); $i ++){
411: $directory_name .= $dirs[$i].'/';
412: }
413: $env{'form.currentpath'} = $directory_name;
414: }
415: $r->print(&done(undef,$url,$group));
416: }
417:
418: sub rename {
419: my ($r,$url,$group)=@_;
420: my $file_name = $env{'form.currentpath'}.$env{'form.rename'};
421: my ($uname,$udom) = &get_name_dom($group);
422: $file_name = &prepend_group($file_name,$group);
423: if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {
424: $r->print ("The file is locked and cannot be renamed.<br />");
425: $r->print(&done(undef,$url,$group));
426: } else {
427: &open_form($r,$url);
428: $r->print('<p>'.&mt('Rename').' '.&display_file().' to
429: <input name="filenewname" type="input" size="50" />?</p>');
430: &close_form($r,$url,$group);
431: }
432: }
433:
434: sub rename_confirmed {
435: my ($r,$url,$group)=@_;
436: my $filenewname=&Apache::lonnet::clean_filename($env{'form.filenewname'});
437: my ($uname,$udom) = &get_name_dom($group);
438: my $port_path = &get_port_path($group);
439: if ($filenewname eq '') {
440: $r->print('<font color="red">'.
441: &mt("Error: no valid filename was provided to rename to.").
442: '</font><br />');
443: $r->print(&done(undef,$url,$group));
444: return;
445: }
446: my $result=
447: &Apache::lonnet::renameuserfile($uname,$udom,
448: $port_path.$env{'form.currentpath'}.$env{'form.selectfile'},
449: $port_path.$env{'form.currentpath'}.$filenewname);
450: if ($result ne 'ok') {
451: $r->print('<font color="red"> An errror occured ('.$result.
452: ') while trying to rename '.&display_file().' to '.
453: &display_file(undef,$filenewname).'</font><br />');
454: }
455: if ($filenewname ne $env{'form.filenewname'}) {
456: $r->print("The new file name was changed from:<br /><strong>".$env{'form.filenewname'}."</strong> to <strong>$filenewname </strong>");
457: }
458: $r->print(&done(undef,$url,$group));
459: }
460:
461: sub display_access {
462: my ($r,$url,$group) = @_;
463: my ($uname,$udom) = &get_name_dom($group);
464: my $file_name = $env{'form.currentpath'}.$env{'form.access'};
465: $file_name = &prepend_group($file_name,$group);
466: my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
467: $uname);
468: my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group,$file_name);
469: &open_form($r,$url);
470: $r->print('<h3>'.&mt('Allowing others to retrieve portfolio file: [_1]',$env{'form.currentpath'}.$env{'form.access'}).'</h3>'."\n");
471: $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 />');
472: &access_setting_table($r,$access_controls{$file_name});
473: &close_form($r,$url,$group);
474: }
475:
476: sub update_access {
477: my ($r,$url,$group) = @_;
478: my $totalprocessed = 0;
479: my %processing;
480: my %title = (
481: 'activate' => 'New controls added',
482: 'delete' => 'Existing controls deleted',
483: 'update' => 'Existing controls modified',
484: );
485: my $changes;
486: foreach my $chg (sort(keys(%title))) {
487: @{$processing{$chg}} = &Apache::loncommon::get_env_multiple('form.'.$chg);
488: $totalprocessed += @{$processing{$chg}};
489: foreach my $num (@{$processing{$chg}}) {
490: my $scope = $env{'form.scope_'.$num};
491: my ($start,$end) = &get_dates_from_form($num);
492: my $newkey = $num.':'.$scope.'_'.$end.'_'.$start;
493: if ($chg eq 'delete') {
494: $$changes{$chg}{$newkey} = 1;
495: } else {
496: $$changes{$chg}{$newkey} =
497: &build_access_record($num,$scope,$start,$end);
498: }
499: }
500: }
501: my $file_name = $env{'form.currentpath'}.$env{'form.selectfile'};
502: $r->print('<h3>'.&mt('Allowing others to retrieve portfolio file: [_1]',$file_name).'</h3>'."\n");
503: $file_name = &prepend_group($file_name,$group);
504: my ($uname,$udom) = &get_name_dom($group);
505: my ($errors,$outcome,$deloutcome,$new_values,$translation);
506: if ($totalprocessed) {
507: ($outcome,$deloutcome,$new_values,$translation) =
508: &Apache::lonnet::modify_access_controls($file_name,$changes,$udom,$uname);
509: }
510: my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom, $uname);
511: my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group,$file_name);
512: if ($totalprocessed) {
513: if ($outcome eq 'ok') {
514: my $updated_controls = $access_controls{$file_name};
515: my ($showstart,$showend);
516: $r->print(&Apache::loncommon::start_data_table());
517: $r->print(&Apache::loncommon::start_data_table_row());
518: $r->print('<th>'.&mt('Type of change').'</th><th>'.&mt('Access control').'</th><th>'.&mt('Start date').'</th><th>'.&mt('End date').'</th>');
519: $r->print(&Apache::loncommon::end_data_table_row());
520: foreach my $chg (sort(keys(%processing))) {
521: if (@{$processing{$chg}} > 0) {
522: if ($chg eq 'delete') {
523: if (!($deloutcome eq 'ok')) {
524: $errors .= &mt('A problem occurred deleting access controls: [_1]',$deloutcome);
525: next;
526: }
527: }
528: my $numchgs = @{$processing{$chg}};
529: $r->print(&Apache::loncommon::start_data_table_row());
530: $r->print('<td rowspan="'.$numchgs.'">'.&mt($title{$chg}).'.</td>');
531: my $count = 0;
532: foreach my $key (sort(keys(%{$$changes{$chg}}))) {
533: if ($count) {
534: $r->print(&Apache::loncommon::start_data_table_row());
535: }
536: my ($num,$scope,$end,$start) =
537: ($key =~ /^([^:]+):([a-z]+)_(\d*)_?(\d*)$/);
538: my $newkey = $key;
539: if ($chg eq 'activate') {
540: $newkey =~ s/^(\d+)/$$translation{$1}/;
541: }
542: my %content = &Apache::lonnet::parse_access_controls(
543: $$updated_controls{$newkey});
544: if ($chg eq 'delete') {
545: $showstart = &mt('Deleted');
546: $showend = $showstart;
547: } else {
548: $showstart = localtime($start);
549: if ($end == 0) {
550: $showend = &mt('No end date');
551: } else {
552: $showend = localtime($end);
553: }
554: }
555: $r->print('<td>'.&mt($scope).'</td><td>'.$showstart.
556: '</td><td>'. $showend.'</td>');
557: $r->print(&Apache::loncommon::end_data_table_row());
558: $count ++;
559: }
560: }
561: }
562: $r->print(&Apache::loncommon::end_data_table());
563: } else {
564: if ((@{$processing{'activate'}} > 0) || (@{$processing{'update'}} > 0)) {
565: $errors .= &mt('A problem occurred storing access control settings: [_1]',$outcome);
566: }
567: }
568: if ($errors) {
569: $r->print($errors);
570: }
571: }
572: $r->print('<br /><a href="'.$url.'?access='.$env{'form.selectfile'}.'¤tpath='.$env{'form.currentpath'}.'">'.&mt('Display all access settings for this file').'</a>');
573: return;
574: }
575:
576: sub build_access_record {
577: my ($num,$scope,$start,$end) = @_;
578: my $record = '<scope type="'.$scope.'"><start>'.$start.'</start><end>'.$end.
579: '</end></scope>';
580: return $record;
581: }
582:
583: sub get_dates_from_form {
584: my ($id) = @_;
585: my $startdate;
586: my $enddate;
587: $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate_'.$id);
588: $enddate = &Apache::lonhtmlcommon::get_date_from_form('enddate_'.$id);
589: if ( exists ($env{'form.noend_'.$id}) ) {
590: $enddate = 0;
591: }
592: return ($startdate,$enddate);
593: }
594:
595: sub access_setting_table {
596: my ($r,$access_controls) = @_;
597: my ($public,$publictext);
598: $publictext = '<b>'.&mt('Off').'</b>';
599: my ($guest,$guesttext);
600: $guesttext = '<b>'.&mt('Off').'</b>';
601: my @courses = ();
602: my @groups = ();
603: my @domains = ();
604: my @users = ();
605: my $now = time;
606: my $then = $now + (60*60*24*180); # six months approx.
607: foreach my $key (sort(keys(%{$access_controls}))) {
608: my ($scope) = ($key =~ /^[^:]+:([a-z]+)_\d*_?\d*$/);
609: if ($scope eq 'public') {
610: $public = $key;
611: $publictext = '<b>'.&mt('On').'</b>';
612: }
613: }
614: $r->print(&Apache::loncommon::start_data_table());
615: $r->print(&Apache::loncommon::start_data_table_row());
616: $r->print('<th>'.&mt('Access Type').'</th><th colspan="3">'.
617: &mt('Settings').'</th>'."\n");
618: $r->print(&Apache::loncommon::end_data_table_row());
619: $r->print(&Apache::loncommon::start_data_table_row());
620: $r->print('<td><b>Public</b><br />'.$publictext.'</td><td colspan="3">');
621: $r->print(&Apache::loncommon::start_data_table());
622: $r->print(&Apache::loncommon::start_data_table_row());
623: my ($pub_startdate,$pub_enddate,$pub_action,$pub_noend);
624: if ($public) {
625: my ($num,$end,$start) = ($public =~ /^([^:]+):[a-z]+_(\d*)_?(\d*)$/);
626: if ($end == 0) {
627: $pub_noend = 'checked="checked"';
628: }
629: $pub_action = '<td><label>
630: <input type="checkbox" name="delete" value="'.$num.
631: '" />'.&mt('Delete').'
632: </label> <br />
633: <label><input type="checkbox" name="update" value="'.
634: $num.'" />'.&mt('Update').
635: '</label>'.
636: '<input type="hidden" name="scope_'.$num.'"'.
637: ' value="public" /></td>';
638: $pub_startdate = &Apache::lonhtmlcommon::date_setter('portform',
639: 'startdate_'.$num,$start,undef,undef,undef,1,undef,
640: undef,undef,1);
641: $pub_enddate = &Apache::lonhtmlcommon::date_setter('portform',
642: 'enddate_'.$num,$end,undef,undef,undef,1,undef,
643: undef,undef,1).
644: ' <nobr><label>
645: <input type="checkbox" name="noend_'.
646: $num.'" '.$pub_noend.' />'.&mt('No end date').
647: '</label></nobr>';
648: } else {
649: $pub_action = '<label>'.
650: '<input type="checkbox" name="activate" value="0" />'.
651: &mt('Activate').'</label>'.
652: '<input type="hidden" name="scope_0" value="public" />';
653: $pub_startdate = &Apache::lonhtmlcommon::date_setter('portform',
654: 'startdate_0',$now,undef,undef,undef,1,undef,
655: undef,undef,1);
656: $pub_enddate = &Apache::lonhtmlcommon::date_setter('portform',
657: 'enddate_0',$then,,undef,undef,undef,1,undef,
658: undef,undef,1).
659: '  <nobr><label><input type="checkbox" '.
660: 'name="noend_0" />'.&mt('No end date').
661: '</label></nobr>';
662:
663: }
664: $r->print('<td>'.$pub_action.'</td><td>'.&mt('Start: ').$pub_startdate.
665: '<br />'.&mt('End: ').$pub_enddate.'</td>');
666: $r->print(&Apache::loncommon::end_data_table_row());
667: $r->print(&Apache::loncommon::end_data_table());
668: $r->print('</td>');
669: $r->print(&Apache::loncommon::end_data_table_row());
670: $r->print(&Apache::loncommon::end_data_table());
671: }
672:
673: sub select_files {
674: my ($r,$group) = @_;
675: if ($env{'form.continue'} eq 'true') {
676: # here we update the selections for the currentpath
677: # eventually, have to handle removing those not checked, but . . .
678: my @items=&Apache::loncommon::get_env_multiple('form.checkfile');
679: if (scalar(@items)){
680: &Apache::lonnet::save_selected_files($env{'user.name'}, $env{'form.currentpath'}, @items);
681: }
682: } else {
683: #empty the file for a fresh start
684: &Apache::lonnet::clear_selected_files($env{'user.name'});
685: }
686: my @files = &Apache::lonnet::files_not_in_path($env{'user.name'}, $env{'form.currentpath'});
687: my $java_files = join ",", @files;
688: if ($java_files) {
689: $java_files.=',';
690: }
691: my $javascript =(<<ENDSMP);
692: <script language='javascript'>
693: function finishSelect() {
694: ENDSMP
695: $javascript .= 'fileList = "'.$java_files.'";';
696: $javascript .= (<<ENDSMP);
697: for (i=0;i<document.forms.checkselect.length;i++) {
698: if (document.forms.checkselect[i].checked){
699: fileList = fileList + document.forms.checkselect.currentpath.value + document.forms.checkselect[i].value + "," ;
700: }
701: }
702: opener.document.forms.lonhomework.
703: ENDSMP
704: $javascript .= $env{'form.fieldname'};
705: $javascript .= (<<ENDSMP);
706: .value=fileList;
707: self.close();
708: }
709: </script>
710: ENDSMP
711: $r->print($javascript);
712: $r->print("<h1>Select portfolio files</h1>
713: Check as many as you wish in response to the problem.<br />");
714: my @otherfiles=&Apache::lonnet::files_not_in_path($env{'user.name'}, $env{'form.currentpath'});
715: if (@otherfiles) {
716: $r->print("<strong>Files selected from other directories:</strong><br />");
717: foreach my $file (@otherfiles) {
718: $r->print($file."<br />");
719: }
720: }
721: }
722: sub upload {
723: my ($r,$url,$group)=@_;
724: my $fname=$env{'form.uploaddoc.filename'};
725: my $filesize = (length($env{'form.uploaddoc'})) / 1000; #express in k (1024?)
726: my $disk_quota = 20000; # expressed in k
727: $fname=&Apache::lonnet::clean_filename($fname);
728:
729: my $portfolio_root=&get_portfolio_root($group);
730: my ($uname,$udom) = &get_name_dom($group);
731: my $port_path = &get_port_path($group);
732: # Fixme --- Move the checking for existing file to LOND error return
733: my @dir_list=&get_dir_list($portfolio_root,$group);
734: my $found_file = 0;
735: my $locked_file = 0;
736: foreach my $line (@dir_list) {
737: my ($file_name)=split(/\&/,$line,2);
738: if ($file_name eq $fname){
739: $file_name = $env{'form.currentpath'}.$file_name;
740: $file_name = &prepend_group($file_name,$group);
741: $found_file = 1;
742: if (defined($group)) {
743: $file_name = $group.'/'.$file_name;
744: }
745: if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {
746: $locked_file = 1;
747: }
748: }
749: }
750: my $current_disk_usage = &Apache::lonnet::diskusage($udom,$uname,$portfolio_root);
751: if (($current_disk_usage + $filesize) > $disk_quota){
752: $r->print('<font color="red">Unable to upload <strong>'.$fname.' (size = '.$filesize.' kilobytes)</strong>. Disk quota will be exceeded.'.
753: '<br />Disk quota is '.$disk_quota.' kilobytes. Your current disk usage is '.$current_disk_usage.' kilobytes.');
754: $r->print(&done('Back',$url,$group));
755: }
756: elsif ($found_file){
757: if ($locked_file){
758: $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>'.
759: '<br />You will be able to rename or delete existing '.$fname.' after a grade has been assigned.');
760: $r->print(&done('Back',$url,$group));
761: } else {
762: $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>'.
763: '<br />To upload, rename or delete existing '.$fname.' in '.$port_path.$env{'form.currentpath'});
764: $r->print(&done('Back',$url,$group));
765: }
766: } else {
767: my $result=&Apache::lonnet::userfileupload('uploaddoc','',
768: $port_path.$env{'form.currentpath'});
769: if ($result !~ m|^/uploaded/|) {
770: $r->print('<font color="red"> An errror occured ('.$result.
771: ') while trying to upload '.&display_file().'</font><br />');
772: $r->print(&done('Back',$url,$group));
773: } else {
774: $r->print(&done(undef,$url,$group));
775: }
776: }
777: }
778: sub lock_info {
779: my ($r,$url,$group) = @_;
780: my ($uname,$udom) = &get_name_dom($group);
781: my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
782: $uname);
783: my $file_name = $env{'form.lockinfo'};
784: $file_name = &prepend_group($file_name,$group);
785: if (defined($file_name) && defined($$current_permissions{$file_name})) {
786: foreach my $array_item (@{$$current_permissions{$file_name}}) {
787: if (ref($array_item) eq 'ARRAY') {
788: my $filetext;
789: if (defined($group)) {
790: $filetext = '<strong>'.$env{'form.lockinfo'}.
791: '</strong> (group: '.$group.')';
792: } else {
793: $filetext = '<strong>'.$file_name.'</strong>';
794: }
795: $r->print(&mt('[_1] was submitted in response to problem: ',
796: $filetext).
797: '<strong>'.&Apache::lonnet::gettitle($$array_item[0]).
798: '</strong><br />');
799: my %course_description = &Apache::lonnet::coursedescription($$array_item[1]);
800: $r->print(&mt('In the course: <strong>[_1]</strong><br />',
801: $course_description{'description'}));
802: # $r->print('the third is '.$$array_item[2].'<br>');
803: # $r->print("item is $$array_item[0]<br> and $$array_item[0]");
804: }
805: }
806: }
807: $r->print(&done('Back',$url,$group));
808: return 'ok';
809: }
810: sub createdir {
811: my ($r,$url,$group)=@_;
812: my $newdir=&Apache::lonnet::clean_filename($env{'form.newdir'});
813: if ($newdir eq '') {
814: $r->print('<font color="red">'.
815: &mt("Error: no directory name was provided.").
816: '</font><br />');
817: $r->print(&done(undef,$url,$group));
818: return;
819: }
820: my $portfolio_root = &get_portfolio_root($group);
821: my @dir_list=&get_dir_list($portfolio_root,$group);
822: my $found_file = 0;
823: foreach my $line (@dir_list) {
824: my ($filename)=split(/\&/,$line,2);
825: if ($filename eq $newdir){
826: $found_file = 1;
827: }
828: }
829: if ($found_file){
830: $r->print('<font color="red"> Unable to create a directory named <strong>'.$newdir.
831: ' </strong>a file or directory by that name already exists.</font><br />');
832: } else {
833: my ($uname,$udom) = &get_name_dom($group);
834: my $port_path = &get_port_path($group);
835: my $result=&Apache::lonnet::mkdiruserfile($uname,$udom,
836: $port_path.$env{'form.currentpath'}.$newdir);
837: if ($result ne 'ok') {
838: $r->print('<font color="red"> An errror occured ('.$result.
839: ') while trying to create a new directory '.&display_file().'</font><br />');
840: }
841: }
842: if ($newdir ne $env{'form.newdir'}) {
843: $r->print("The new directory name was changed from:<br /><strong>".$env{'form.newdir'}."</strong> to <strong>$newdir </strong>");
844: }
845: $r->print(&done(undef,$url,$group));
846: }
847:
848: sub get_portfolio_root {
849: my ($group) = @_;
850: my ($portfolio_root,$udom,$uname,$path);
851: ($uname,$udom) = &get_name_dom($group);
852: if (defined($group)) {
853: $path = '/userfiles/groups/'.$group.'/portfolio';
854: } else {
855: $path = '/userfiles/portfolio';
856: }
857: return (&Apache::loncommon::propath($udom,$uname).$path);
858: }
859:
860: sub get_dir_list {
861: my ($portfolio_root,$group) = @_;
862: my ($uname,$udom) = &get_name_dom($group);
863: return &Apache::lonnet::dirlist($env{'form.currentpath'},
864: $udom,$uname,$portfolio_root);
865: }
866:
867: sub get_name_dom {
868: my ($group) = @_;
869: my ($uname,$udom);
870: if (defined($group)) {
871: $udom = $env{'course.'.$env{'request.course.id'}.'.domain'};
872: $uname = $env{'course.'.$env{'request.course.id'}.'.num'};
873: } else {
874: $udom = $env{'user.domain'};
875: $uname = $env{'user.name'};
876: }
877: return ($uname,$udom);
878: }
879:
880: sub prepend_group {
881: my ($filename,$group) = @_;
882: if (defined($group)) {
883: $filename = $group.'/'.$filename;
884: }
885: return $filename;
886: }
887:
888: sub get_namespace {
889: my ($group) = @_;
890: my $namespace = 'portfolio';
891: if (defined($group)) {
892: my ($uname,$udom) = &get_name_dom($group);
893: $namespace .= '_'.$udom.'_'.$uname.'_'.$group;
894: }
895: return $namespace;
896: }
897:
898: sub get_port_path {
899: my ($group) = @_;
900: my $port_path;
901: if (defined($group)) {
902: $port_path = "groups/$group/portfolio";
903: } else {
904: $port_path = 'portfolio';
905: }
906: return $port_path;
907: }
908:
909: sub handler {
910: # this handles file management
911: my $r = shift;
912: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
913: ['selectfile','currentpath','meta','lockinfo','currentfile',
914: 'action','fieldname','mode','rename','continue','group','access']);
915: my ($uname,$udom,$portfolio_root,$url,$group,$caller,$title);
916: if ($r->uri =~ m|^(/adm/)([^/]+)|) {
917: $url = $1.$2;
918: $caller = $2;
919: }
920: if ($caller eq 'coursegrp_portfolio') {
921: # Needs to be in a course
922: if (! ($env{'request.course.fn'})) {
923: # Not in a course
924: $env{'user.error.msg'}=
925: "/adm/coursegrp_portfolio:rgf:0:0:Cannot view group portfolio";
926: return HTTP_NOT_ACCEPTABLE;
927: }
928: my $earlyout = 0;
929: my $view_permission = &Apache::lonnet::allowed('vcg',
930: $env{'request.course.id'});
931: $group = $env{'form.group'};
932: $group =~ s/\W//g;
933: if ($group) {
934: ($uname,$udom) = &get_name_dom($group);
935: my %curr_groups = &Apache::longroup::coursegroups($udom,$uname,
936: $group);
937: if (%curr_groups) {
938: if (($view_permission) || (&Apache::lonnet::allowed('rgf',
939: $env{'request.course.id'}.'/'.$group))) {
940: $portfolio_root = &get_portfolio_root($group);
941: } else {
942: $r->print('You do not have the privileges required to access the shared files space for this group');
943: $earlyout = 1;
944: }
945: } else {
946: $r->print('Not a valid group for this course');
947: $earlyout = 1;
948: }
949: $title = &mt('Group files').' for '.$group;
950: } else {
951: $r->print('Invalid group');
952: $earlyout = 1;
953: }
954: if ($earlyout) { return OK; }
955: } else {
956: ($uname,$udom) = &get_name_dom();
957: $portfolio_root = &get_portfolio_root();
958: $title = &mt('Portfolio Manager');
959: }
960:
961: &Apache::loncommon::no_cache($r);
962: &Apache::loncommon::content_type($r,'text/html');
963: $r->send_http_header;
964: # Give the LON-CAPA page header
965: if ($env{"form.mode"} eq 'selectfile'){
966: $r->print(&Apache::loncommon::start_page($title,undef,
967: {'only_body' => 1}));
968: } else {
969: $r->print(&Apache::loncommon::start_page($title));
970: }
971: $r->rflush();
972: if (($env{'form.storeupl'}) & (!$env{'form.uploaddoc.filename'})){
973: $r->print('<font color="red"> No file was selected to upload.'.
974: 'To upload a file, click <strong>Browse...</strong>'.
975: ', select a file, then click <strong>Upload</strong>,</font>');
976: }
977: if ($env{'form.meta'}) {
978: &open_form($r,$url);
979: # $r->print(&edit_meta_data($r, $env{'form.currentpath'}.$env{'form.selectfile'}));
980: $r->print('Edit the meta data<br />');
981: &close_form($r,$url,$group);
982: }
983: if ($env{'form.store'}) {
984: }
985:
986: if ($env{'form.uploaddoc.filename'}) {
987: &upload($r,$url,$group);
988: } elsif ($env{'form.action'} eq 'delete' && $env{'form.confirmed'}) {
989: &delete_confirmed($r,$url,$group);
990: } elsif ($env{'form.action'} eq 'delete') {
991: &delete($r,$url,$group);
992: } elsif ($env{'form.action'} eq 'deletedir' && $env{'form.confirmed'}) {
993: &delete_dir_confirmed($r,$url,$group);
994: } elsif ($env{'form.action'} eq 'deletedir'){
995: &delete_dir($r,$url,$group);
996: } elsif ($env{'form.action'} eq 'rename' && $env{'form.confirmed'}) {
997: &rename_confirmed($r,$url,$group);
998: } elsif ($env{'form.rename'}) {
999: $env{'form.selectfile'} = $env{'form.rename'};
1000: $env{'form.action'} = 'rename';
1001: &rename($r,$url,$group);
1002: } elsif ($env{'form.access'}) {
1003: $env{'form.selectfile'} = $env{'form.access'};
1004: $env{'form.action'} = 'chgaccess';
1005: &display_access($r,$url,$group);
1006: } elsif ($env{'form.action'} eq 'chgaccess') {
1007: &update_access($r,$url,$group);
1008: } elsif ($env{'form.createdir'}) {
1009: &createdir($r,$url,$group);
1010: } elsif ($env{'form.lockinfo'}) {
1011: &lock_info($r,$url,$group);
1012: } else {
1013: my $current_path='/';
1014: if ($env{'form.currentpath'}) {
1015: $current_path = $env{'form.currentpath'};
1016: }
1017: my @dir_list=&get_dir_list($portfolio_root,$group);
1018: if ($dir_list[0] eq 'no_such_dir'){
1019: # two main reasons for this:
1020: # 1) never been here, so directory structure not created
1021: # 2) back-button navigation after deleting a directory
1022: if ($current_path eq '/'){
1023: &Apache::lonnet::mkdiruserfile($uname,$udom,
1024: &get_port_path($group));
1025: } else {
1026: # some directory that snuck in get rid of the directory
1027: # from the recent pulldown, just in case
1028: &Apache::lonhtmlcommon::remove_recent('portfolio',
1029: [$current_path]);
1030: $current_path = '/'; # force it back to the root
1031: }
1032: # now grab the directory list again, for the first time
1033: @dir_list=&Apache::lonnet::dirlist($current_path,
1034: $udom,$uname,$portfolio_root);
1035: }
1036: # need to know if directory is empty so it can be removed if desired
1037: my $is_empty=(@dir_list == 2);
1038: &display_common($r,$url,$current_path,$is_empty,\@dir_list,$group);
1039: &display_directory($r,$url,$current_path,$is_empty,\@dir_list,$group);
1040: $r->print(&Apache::loncommon::end_page());
1041: }
1042: return OK;
1043: }
1044: 1;
1045: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>