[LON-CAPA-cvs] cvs: loncom /homework essayresponse.pm inputtags.pm structuretags.pm /interface loncommon.pm
raeburn
raeburn at source.lon-capa.org
Tue Jul 26 13:14:56 EDT 2011
raeburn Tue Jul 26 17:14:56 2011 EDT
Modified files:
/loncom/homework essayresponse.pm inputtags.pm structuretags.pm
/loncom/interface loncommon.pm
Log:
- Bug 6459.
- Overwriting previously submitted file in "turned_in" portfolio.
- code used to generate path to subdirectory in portfolio moved
from essayresponse.pm to loncommon.pm to facilitate re-use.
- client side javascript used to detect if submitted file will
overwrite previously submitted file. User prompted to confirm.
- If resource includes more than one file upload, partid_responseid
included as additional subdirectory in path where file is stored.
- Work in progress. Still need to support multiple dropboxes in a .page.
-------------- next part --------------
Index: loncom/homework/essayresponse.pm
diff -u loncom/homework/essayresponse.pm:1.114 loncom/homework/essayresponse.pm:1.115
--- loncom/homework/essayresponse.pm:1.114 Sat Jan 29 19:41:41 2011
+++ loncom/homework/essayresponse.pm Tue Jul 26 17:14:51 2011
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# essay (ungraded) style responses
#
-# $Id: essayresponse.pm,v 1.114 2011/01/29 19:41:41 raeburn Exp $
+# $Id: essayresponse.pm,v 1.115 2011/07/26 17:14:51 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -441,81 +441,58 @@
}
}
if ($accepted_upload ne '') {
- my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
- my $turnindir;
- my %userhash = &Apache::lonnet::userenvironment($udom,$uname,'turnindir');
- $turnindir = $userhash{'turnindir'};
- if ($turnindir eq '') {
- $turnindir = &mt('turned in');
- $turnindir =~ s/\W+/_/g;
- my %newhash = (
- 'turnindir' => $turnindir,
- );
- &Apache::lonnet::put('environment',\%newhash,$udom,$uname);
- }
- my $prefix = 'portfolio';
- my $path = '/'.$turnindir.'/';
- my $restitle=&Apache::lonnet::gettitle($symb);
- $restitle =~ s/\W+/_/g;
- if ($restitle eq '') {
- $restitle = ($resurl =~ m{/[^/]+$});
- if ($restitle eq '') {
- $restitle = time;
- }
- }
- my @pathitems;
- my $navmap = Apache::lonnavmaps::navmap->new();
- if (defined($navmap)) {
- my $mapres = $navmap->getResourceByUrl($map);
- if (ref($mapres)) {
- my $pcslist = $mapres->map_hierarchy();
- if ($pcslist ne '') {
- foreach my $pc (split(/,/,$pcslist)) {
- my $res = $navmap->getByMapPc($pc);
- if (ref($res)) {
- my $title = $res->compTitle();
- $title =~ s/\W+/_/g;
- if ($title ne '') {
- push(@pathitems,$title);
- }
+ my ($path,$multiresp) =
+ &Apache::loncommon::get_turnedin_filepath($symb,$uname,$udom,
+ 'submission');
+ if ($path eq '') {
+ $$award = 'INTERNAL_ERROR';
+ } else {
+ if ($multiresp) {
+ $path .= '/'.$jspart.'_'.$id;
+ }
+ my $prefix = 'portfolio';
+ my $formelement = 'HWFILE'.$jspart.'_'.$id;
+ my $fname = &Apache::lonnet::clean_filename($env{'form.'.$formelement.'.filename'});
+ my $url = '/uploaded/'.$udom.'/'.$uname.'/'.$prefix.$path.'/'.$fname;
+ my @stat = &Apache::lonnet::stat_file($url);
+ my $conflicts = 0;
+ if (@stat && $stat[0] ne 'no_such_dir') {
+ my $current_permissions =
+ &Apache::lonnet::get_portfile_permissions($udom,$uname);
+ if (ref($current_permissions) eq 'HASH') {
+ if (ref($current_permissions->{$path.'/'.$fname}) eq 'ARRAY') {
+ foreach my $record (@{$current_permissions->{$path.'/'.$fname}}) {
+ if (ref($record) eq 'ARRAY') {
+ next if (($record->[0] eq $symb) &&
+ ($record->[1] eq $crsid));
+ $conflicts ++;
+ }
}
}
}
- my $maptitle = $mapres->compTitle();
- $maptitle =~ s/\W+/_/g;
- if ($maptitle ne '') {
- push(@pathitems,$maptitle);
+ if ($conflicts) {
+ $$award = 'FILENAME_INUSE';
}
- } else {
- $$award = 'INTERNAL_ERROR';
}
- } else {
- $$award = 'INTERNAL_ERROR';
- }
- push(@pathitems,$restitle);
- $path .= join('/', at pathitems);
- my $formelement = 'HWFILE'.$jspart.'_'.$id;
- my $fname = &Apache::lonnet::clean_filename($env{'form.'.$formelement.'.filename'});
- my $url = '/uploaded/'.$udom.'/'.$uname.'/'.$prefix.$path.'/'.$fname;
- my @stat = &Apache::lonnet::stat_file($url);
- if (@stat && $stat[0] ne 'no_such_dir') {
- $$award = 'FILENAME_INUSE';
- } else {
- my ($mode,%allfiles,%codebase);
- my $result = &Apache::lonnet::userfileupload($formelement,'',
+ unless ($conflicts) {
+ my ($mode,%allfiles,%codebase);
+ my $result = &Apache::lonnet::userfileupload($formelement,'',
$prefix.$path,$mode,\%allfiles,\%codebase);
- if ($result =~ m{^/uploaded/}) {
- $stored_upload = $path.'/'.$fname;
- $Apache::lonhomework::results{"resource.$part.$id.portfiles"} = $stored_upload;
- push(@tolock,$stored_upload);
- } else {
- $$award = 'INTERNAL_ERROR';
+ if ($result =~ m{^/uploaded/}) {
+ $stored_upload = $path.'/'.$fname;
+ unless (grep(/^\Q$stored_upload\E$/, at accepted_portfiles)) {
+ $Apache::lonhomework::results{"resource.$part.$id.portfiles"} = $stored_upload;
+ push(@tolock,$stored_upload);
+ }
+ } else {
+ $$award = 'INTERNAL_ERROR';
+ }
}
}
delete($env{'form.HWFILE'.$jspart.'_'.$id});
}
if (@accepted_portfiles) {
- if ($stored_upload) {
+ if ($Apache::lonhomework::results{"resource.$part.$id.portfiles"}) {
$Apache::lonhomework::results{"resource.$part.$id.portfiles"} .= ',';
}
$Apache::lonhomework::results{"resource.$part.$id.portfiles"}.=join(',', at accepted_portfiles);
Index: loncom/homework/inputtags.pm
diff -u loncom/homework/inputtags.pm:1.292 loncom/homework/inputtags.pm:1.293
--- loncom/homework/inputtags.pm:1.292 Tue Jul 12 12:55:50 2011
+++ loncom/homework/inputtags.pm Tue Jul 26 17:14:51 2011
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# input definitons
#
-# $Id: inputtags.pm,v 1.292 2011/07/12 12:55:50 christianto Exp $
+# $Id: inputtags.pm,v 1.293 2011/07/26 17:14:51 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -571,7 +571,7 @@
if ($which eq 'uploadonly' || $which eq 'both') {
$result.=&mt('Submit a file: (only one file per submission)').
' <br /><input type="file" size="50" name="HWFILE'.
- $jspart.'_'.$id.'" /><br />';
+ $jspart.'_'.$id.'" id="HWFILE'.$jspart.'_'.$id.'" /><br />';
}
if ( $which eq 'both') {
$result.='<br />'.'<strong>'.&mt('OR:').'</strong><br />';
Index: loncom/homework/structuretags.pm
diff -u loncom/homework/structuretags.pm:1.492 loncom/homework/structuretags.pm:1.493
--- loncom/homework/structuretags.pm:1.492 Mon Jul 25 12:02:45 2011
+++ loncom/homework/structuretags.pm Tue Jul 26 17:14:51 2011
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# definition of tags that give a structure to a document
#
-# $Id: structuretags.pm,v 1.492 2011/07/25 12:02:45 christianto Exp $
+# $Id: structuretags.pm,v 1.493 2011/07/26 17:14:51 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -170,37 +170,154 @@
return <<"ENDSCRIPT";
<script type="text/javascript">
// <![CDATA[
-function file_deletion_check(formname) {
+function file_deletion_check(formname,uploadid) {
var elemnum = formname.elements.length;
if (elemnum == 0) {
return true;
}
- var str = new RegExp("^HWFILE.+_delete\$");
- var delboxes = new Array();
+ var alluploads = new Array();
+ if ((uploadid != '') && (uploadid != undefined)) {
+ alluploads.push(uploadid);
+ } else {
+ var uploadstr = /^HWFILE.+\$/;
+ for (var i=0; i<formname.elements.length; i++) {
+ var id = formname.elements[i].id;
+ if (id != '') {
+ if (uploadstr.test(id)) {
+ if (formname.elements[i].type == 'file') {
+ alluploads.push(id);
+ }
+ }
+ }
+ }
+ }
+ for (var i=0; i<alluploads.length; i++) {
+ var delstr = new RegExp('^'+alluploads[i]+'_\\\\d+_delete\$');
+ var delboxes = new Array();
+ for (var j=0; j<formname.elements.length; j++) {
+ var id = formname.elements[j].id;
+ if (id != '') {
+ if (delstr.test(id)) {
+ if (formname.elements[j].type == 'checkbox') {
+ if (formname.elements[j].checked) {
+ delboxes.push(id);
+ }
+ }
+ }
+ }
+ }
+ if (delboxes.length > 0) {
+ if (!confirm("$delfilewarn")) {
+ for (var j=0; j<delboxes.length; j++) {
+ formname.elements[delboxes[j]].checked = false;
+ }
+ return false;
+ }
+ }
+ }
+ return true;
+}
+// ]]>
+</script>
+ENDSCRIPT
+}
+
+sub file_overwritechk_js {
+ my $overwritewarn = &mt('File(s) you uploaded for your submission will overwrite existing file(s) submitted for this item').'\\n'.
+ &mt('Continue submission and overwrite the file(s)?');
+ return <<"ENDSCRIPT";
+<script type="text/javascript">
+// <![CDATA[
+function file_overwrite_check(formname,path,multiresp) {
+ var elemnum = formname.elements.length;
+ if (elemnum == 0) {
+ return true;
+ }
+ var alluploads = new Array();
+ var uploaded = new Array();
+ var uploadstr = /^HWFILE.+\$/;
+ var fnametrim = /[^\\/\\\\]+\$/;
for (var i=0; i<formname.elements.length; i++) {
var id = formname.elements[i].id;
if (id != '') {
- if (str.test(id)) {
- if (formname.elements[i].type == 'checkbox') {
- if (formname.elements[i].checked) {
- delboxes.push(id);
+ if (uploadstr.test(id)) {
+ if (formname.elements[i].type == 'file') {
+ alluploads.push(id);
+ if ((formname.elements[i].value != undefined) &&
+ (formname.elements[i].value != '')) {
+ uploaded.push(id);
}
}
}
}
}
- if (delboxes.length > 0) {
- if (confirm("$delfilewarn")) {
- return true;
- } else {
- for (var j=0; j<delboxes.length; j++) {
- formname.elements[delboxes[j]].checked = false;
+ for (var i=0; i<alluploads.length; i++) {
+ var delstr = new RegExp("^"+alluploads[i]+"_\\\\d+_delete\$");
+ var delboxes = new Array();
+ for (var j=0; j<formname.elements.length; j++) {
+ var id = formname.elements[j].id;
+ if (id != '') {
+ if (delstr.test(id)) {
+ if (formname.elements[j].type == 'checkbox') {
+ delboxes.push(id);
+ }
+ }
+ }
+ }
+ var overwrites = new Array();
+ if (delboxes.length > 0) {
+ if ((formname.elements[alluploads[i]].value != undefined) &&
+ (formname.elements[alluploads[i]].value != '')) {
+ var filepath = formname.elements[alluploads[i]].value;
+ var newfilename = fnametrim.exec(filepath);
+ if (newfilename != null) {
+ var filename = String(newfilename);
+ var nospaces = filename.replace(/\\s+/g,'_');
+ var nospecials = nospaces.replace(/[^\\/\\w\\.\\-]/g,'');
+ var cleanfilename = nospecials.replace(/\\.(\\d+\\.)/g,"_\$1");
+ if (cleanfilename != '') {
+ var fullpath = path+"/"+cleanfilename;
+ if (multiresp == 1) {
+ var partid = String(alluploads[i]);
+ var subdir = partid.replace(/^HWFILE/,'');
+ if (subdir != "" && subdir != undefined) {
+ fullpath = path+"/"+subdir+"/"+cleanfilename;
+ }
+ }
+ for (var k=0; k<delboxes.length; k++) {
+ if (fullpath == formname.elements[delboxes[k]].value) {
+ var id = formname.elements[delboxes[k]].id;
+ if (id != '') {
+ if (!formname.elements[delboxes[k]].checked) {
+ overwrites.push(id);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (overwrites.length > 0) {
+ if (confirm("$overwritewarn")) {
+ var delcheck = file_deletion_check(formname,alluploads[i]);
+ if (delcheck == false) {
+ return false;
+ }
+ } else {
+ for (var n=0; n<overwrites.length; n++) {
+ formname.elements[overwrites[n]].value = "";
+ }
+ return false;
+ }
+ } else {
+ var delcheck = file_deletion_check(formname);
+ if (delcheck == false) {
+ return false;
+ }
}
- return false;
}
- } else {
- return true;
}
+ return true;
}
// ]]>
</script>
@@ -232,8 +349,43 @@
$extra_head .= &Apache::lonhtmlcommon::htmlareaselectactive(\%textarea_args);
}
my $is_task = ($env{'request.uri'} =~ /\.task$/);
+ my $needs_upload;
if ($is_task) {
$extra_head .= &file_delchk_js();
+ } else {
+ if (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.uploadedfiletypes") ne '') {
+ $needs_upload = 1;
+ } else {
+ unless ($env{'request.state'} eq 'construct') {
+ my ($symb)= &Apache::lonnet::whichuser();
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ if (ref($navmap)) {
+ my $res = $navmap->getBySymb($symb);
+ if (ref($res)) {
+ my $partlist = $res->parts();
+ if (ref($partlist) eq 'ARRAY') {
+ foreach my $part (@{$partlist}) {
+ my @types = $res->responseType($part);
+ my @ids = $res->responseIds($part);
+ for (my $i=0; $i < scalar(@ids); $i++) {
+ if ($types[$i] eq 'essay') {
+ my $partid = $part.'_'.$ids[$i];
+ if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') {
+ $needs_upload = 1;
+ last;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if ($needs_upload) {
+ $extra_head .= &file_overwritechk_js()."\n".
+ &file_delchk_js();
}
my %body_args;
@@ -316,7 +468,6 @@
if (!defined($found{'body'}) && $env{'request.state'} ne 'construct') {
$page_start .= &Apache::lonxml::message_location();
}
-
my $form_tag_start;
if (!defined($found{'form'})) {
$form_tag_start='<form name="lonhomework" enctype="multipart/form-data" method="post" action="';
@@ -327,8 +478,13 @@
if ($target eq 'edit') {
$form_tag_start.=&Apache::edit::form_change_detection();
}
+ my ($symb,$courseid,$udom,$uname)=&Apache::lonnet::whichuser();
+ my ($path,$multiresp) =
+ &Apache::loncommon::get_turnedin_filepath($symb,$uname,$udom);
if ($is_task) {
$form_tag_start .= ' onsubmit="return file_deletion_check(this);"';
+ } elsif ($needs_upload) {
+ $form_tag_start .= ' onsubmit="return file_overwrite_check(this,'."'$path','$multiresp'".');"';
}
$form_tag_start.='>'."\n";
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1014 loncom/interface/loncommon.pm:1.1015
--- loncom/interface/loncommon.pm:1.1014 Mon Jul 4 09:24:58 2011
+++ loncom/interface/loncommon.pm Tue Jul 26 17:14:56 2011
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.1014 2011/07/04 09:24:58 foxr Exp $
+# $Id: loncommon.pm,v 1.1015 2011/07/26 17:14:56 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -9106,6 +9106,113 @@
=pod
+=item * &get_turnedin_filepath()
+
+Determines path in a user's portfolio file for storage of files uploaded
+to a specific essayresponse or dropbox item.
+
+Inputs: 3 required + 1 optional.
+$symb is symb for resource, $uname and $udom are for current user (required).
+$caller is optional (can be "submission", if routine is called when storing
+an upoaded file when "Submit Answer" button was pressed).
+
+Returns array containing $path and $multiresp.
+$path is path in portfolio. $multiresp is 1 if this resource contains more
+than one file upload item. Callers of routine should append partid as a
+subdirectory to $path in cases where $multiresp is 1.
+
+Called by: homework/essayresponse.pm and homework/structuretags.pm
+
+=cut
+
+sub get_turnedin_filepath {
+ my ($symb,$uname,$udom,$caller) = @_;
+ my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
+ my $turnindir;
+ my %userhash = &Apache::lonnet::userenvironment($udom,$uname,'turnindir');
+ $turnindir = $userhash{'turnindir'};
+ my ($path,$multiresp);
+ if ($turnindir eq '') {
+ if ($caller eq 'submission') {
+ $turnindir = &mt('turned in');
+ $turnindir =~ s/\W+/_/g;
+ my %newhash = (
+ 'turnindir' => $turnindir,
+ );
+ &Apache::lonnet::put('environment',\%newhash,$udom,$uname);
+ }
+ }
+ if ($turnindir ne '') {
+ $path = '/'.$turnindir.'/';
+ my ($multipart,$turnin, at pathitems);
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ if (defined($navmap)) {
+ my $mapres = $navmap->getResourceByUrl($map);
+ if (ref($mapres)) {
+ my $pcslist = $mapres->map_hierarchy();
+ if ($pcslist ne '') {
+ foreach my $pc (split(/,/,$pcslist)) {
+ my $res = $navmap->getByMapPc($pc);
+ if (ref($res)) {
+ my $title = $res->compTitle();
+ $title =~ s/\W+/_/g;
+ if ($title ne '') {
+ push(@pathitems,$title);
+ }
+ }
+ }
+ }
+ my $maptitle = $mapres->compTitle();
+ $maptitle =~ s/\W+/_/g;
+ if ($maptitle ne '') {
+ push(@pathitems,$maptitle);
+ }
+ unless ($env{'request.state'} eq 'construct') {
+ my $res = $navmap->getBySymb($symb);
+ if (ref($res)) {
+ my $partlist = $res->parts();
+ my $totaluploads = 0;
+ if (ref($partlist) eq 'ARRAY') {
+ foreach my $part (@{$partlist}) {
+ my @types = $res->responseType($part);
+ my @ids = $res->responseIds($part);
+ for (my $i=0; $i < scalar(@ids); $i++) {
+ if ($types[$i] eq 'essay') {
+ my $partid = $part.'_'.$ids[$i];
+ if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') {
+ $totaluploads ++;
+ }
+ }
+ }
+ }
+ if ($totaluploads > 1) {
+ $multiresp = 1;
+ }
+ }
+ }
+ }
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+ my $restitle=&Apache::lonnet::gettitle($symb);
+ $restitle =~ s/\W+/_/g;
+ if ($restitle eq '') {
+ $restitle = ($resurl =~ m{/[^/]+$});
+ if ($restitle eq '') {
+ $restitle = time;
+ }
+ }
+ push(@pathitems,$restitle);
+ $path .= join('/', at pathitems);
+ }
+ return ($path,$multiresp);
+}
+
+=pod
+
=back
=head1 CSV Upload/Handling functions
More information about the LON-CAPA-cvs
mailing list