Changeset 25


Ignore:
Timestamp:
Mar 31, 2011, 12:07:02 PM (8 years ago)
Author:
robert@…
Message:

Implemented uploadify as upload tool

Location:
trunk
Files:
9 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/conf/BaseFilters.groovy

    r20 r25  
    3636                                }
    3737                               
     38                                // File uploads don't occur in a session, since the flash script can't
     39                                // continue the session. For that reason, all uploads are allowed.
     40                                if( actionName == "upload" && controllerName == "file" ) {
     41                                        return true;
     42                                }
     43                               
    3844                                if( !ConfigurationHolder.config.gscf.baseURL ) {
    3945                                        throw new Exception( "No GSCF instance specified. Please check configuration." )
  • trunk/grails-app/controllers/nl/tno/metagenomics/files/FileController.groovy

    r22 r25  
    1818
    1919import org.codehaus.groovy.grails.commons.ConfigurationHolder
     20import org.springframework.web.multipart.MultipartHttpServletRequest
    2021import grails.converters.*
    2122import org.apache.commons.io.IOUtils;
     
    180181
    181182        protected def moveUploadedFile(File absolutePath ) {
    182                 PrintWriter writer = null;
    183                 InputStream is = null;
    184                 FileOutputStream fos = null;
    185 
    186                 try {
    187                         writer = response.getWriter();
    188                 } catch (IOException ex) {
    189                         log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
    190                 }
    191 
    192                 String filename = request.getHeader("X-File-Name");
     183                if( !( request instanceof MultipartHttpServletRequest ) ) {
     184                        response.setStatus( response.SC_BAD_REQUEST );
     185                        log.error( "Request for file upload is not multipart: " + params );
     186                        return [];
     187                }
     188               
     189                MultipartHttpServletRequest mpr = (MultipartHttpServletRequest) request;
     190                def uploadedFile = mpr.getFile( 'Filedata' )
     191               
     192                String filename = uploadedFile.getOriginalFilename();
    193193
    194194                // URL decode the filename
     
    198198                String newFilename = fileService.getUniqueFilename( filename, absolutePath );
    199199                try {
    200                         is = request.getInputStream();
    201                         fos = new FileOutputStream(new File(absolutePath, newFilename));
    202                         IOUtils.copy(is, fos);
     200                        uploadedFile.transferTo( new File( absolutePath, newFilename ) );
     201
    203202                        response.setStatus(response.SC_OK);
     203                       
    204204                        return [ 'success': true, 'filename': newFilename ]
    205                 } catch (FileNotFoundException ex) {
     205                } catch (Exception ex) {
     206                        log.error( "Fileupload has thrown an exception: " + ex.getMessage());
     207
    206208                        response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
    207                         log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
    208 
    209209                        return [ 'success': false ]
    210                 } catch (IOException ex) {
    211                         response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
    212                         log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
    213 
    214                         return [ 'success': false ]
    215                 } finally {
    216                         try {
    217                                 fos.close();
    218                                 is.close();
    219                         } catch (IOException ignored) {
    220                         }
    221210                }
    222211        }
  • trunk/grails-app/taglib/nl/tno/metagenomics/UploadTagLib.groovy

    r9 r25  
    1515        def fileUpload = { attrs ->
    1616                def multiple = attrs.multiple ?: false;
    17                
    18                 out << '<div id="upload_field_container_' + attrs.name + '"  class="upload_field_container upload_field_container_' + ( multiple ? 'multiple' : 'single' ) + '">';
    19                 out << '<div id="upload_field_' + attrs.name + '"  class="upload_field"></div>';
     17                out << '<div class="uploadContainer" id="uploadcontainer_' + attrs.name + '">'
     18                out << '<div class="files">'
    2019                out << '<div id="' + attrs.name + 'Example" class="upload_info"></div>';
    2120                out << '<a id="' + attrs.name + 'DeleteExisting" class="upload_del" href="#" onClick="if( confirm( \'Are you sure to delete this file?\' ) ) { deleteFileExisting( \'' + attrs.name + '\' ); } return false;"><img src="' + resource( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' ) + '"></a>';
    2221                out << '<a id="' + attrs.name + 'DeleteUploaded" class="upload_del" href="#" onClick="if( confirm( \'Are you sure to delete this file?\' ) ) { deleteFileUploaded( \'' + attrs.name + '\' ); } return false;"><img src="' + resource( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' ) + '"></a>';
     22                out << '</div>'
     23                out << '<input type="file" name="ajaxupload_' + attrs.name + '" id="upload_field_' + attrs.name + '" />'
    2324                out << '<script type="text/javascript">';
    24                 out << '  $(document).ready( function() { ';
     25                out << '  $(function() { ';
    2526                out << '    var filename = "' + ( attrs.value ?: '' ) + '";';
    2627                out << '    fileUploadField( "' + attrs.name + '", ' + ( multiple ? 'true' : 'false' ) + ( attrs.onUpload ? ', function(params) { ' + attrs.onUpload + '(params); }' : '' ) + ( attrs.onDelete ? ', function(params) { ' + attrs.onDelete + '(params); }' : '' ) + ');';
    2728                out << '    if( filename != "" ) {';
    2829                out << '      $("#' + attrs.name + 'DeleteExisting").show();';
    29                 out << '      $("#' + attrs.name + 'Example").html("Current file: " + createFileHTML( filename ) )';
     30                out << '      $("#' + attrs.name + 'Example").html("Current file: " + createFileHTML( filename ) );';
     31                out << '      $("#uploadcontainer_' + attrs.name + ' .files").show();';
    3032                out << '    }';
    3133                out << '  } );';
    3234                out << "</script>\n";
    33                
     35
    3436                // Show a custom list when uploading multiple files
    3537                if( multiple ) {
    36                         out << '<ul class="multipleFiles"></ul>';
     38                        out << '<ul class="files"></ul>';
    3739                } else {
    3840                        out << '<input type="hidden" name="' + attrs.name + '" id="' + attrs.name + '" value="' + attrs.value + '">';
     
    4042
    4143                out << '</div>';
     44               
    4245        }
     46       
     47//      def fileUpload = { attrs ->
     48//              def multiple = attrs.multiple ?: false;
     49//             
     50//              out << '<div id="upload_field_container_' + attrs.name + '"  class="upload_field_container upload_field_container_' + ( multiple ? 'multiple' : 'single' ) + '">';
     51//              out << '<div id="upload_field_' + attrs.name + '"  class="upload_field"></div>';
     52//              out << '<div id="' + attrs.name + 'Example" class="upload_info"></div>';
     53//              out << '<a id="' + attrs.name + 'DeleteExisting" class="upload_del" href="#" onClick="if( confirm( \'Are you sure to delete this file?\' ) ) { deleteFileExisting( \'' + attrs.name + '\' ); } return false;"><img src="' + resource( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' ) + '"></a>';
     54//              out << '<a id="' + attrs.name + 'DeleteUploaded" class="upload_del" href="#" onClick="if( confirm( \'Are you sure to delete this file?\' ) ) { deleteFileUploaded( \'' + attrs.name + '\' ); } return false;"><img src="' + resource( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' ) + '"></a>';
     55//              out << '<script type="text/javascript">';
     56//              out << '  $(document).ready( function() { ';
     57//              out << '    var filename = "' + ( attrs.value ?: '' ) + '";';
     58//              out << '    fileUploadField( "' + attrs.name + '", ' + ( multiple ? 'true' : 'false' ) + ( attrs.onUpload ? ', function(params) { ' + attrs.onUpload + '(params); }' : '' ) + ( attrs.onDelete ? ', function(params) { ' + attrs.onDelete + '(params); }' : '' ) + ');';
     59//              out << '    if( filename != "" ) {';
     60//              out << '      $("#' + attrs.name + 'DeleteExisting").show();';
     61//              out << '      $("#' + attrs.name + 'Example").html("Current file: " + createFileHTML( filename ) )';
     62//              out << '    }';
     63//              out << '  } );';
     64//              out << "</script>\n";
     65//             
     66//              // Show a custom list when uploading multiple files
     67//              if( multiple ) {
     68//                      out << '<ul class="multipleFiles"></ul>';
     69//              } else {
     70//                      out << '<input type="hidden" name="' + attrs.name + '" id="' + attrs.name + '" value="' + attrs.value + '">';
     71//              }
     72//
     73//              out << '</div>';
     74//      }
    4375
    4476        /**
  • trunk/grails-app/views/assay/show.gsp

    r24 r25  
    1616                <g:javascript src="enterTagsDialog.js" />
    1717
    18                 <g:javascript src="fileuploader.new.js" />
    1918                <g:javascript src="fileuploads.new.js" />
    2019               
  • trunk/grails-app/views/layouts/main.gsp

    r15 r25  
    2222                <script type="text/javascript" src="${resource(dir: 'js', file: 'paginate.js')}"></script>
    2323                <script type="text/javascript" src="${resource(dir: 'js', file: 'forms.js')}"></script>
     24               
     25        <!--  Uploadify -->
     26            <link href="${resource(dir: 'uploadify', file: 'uploadify.css')}" type="text/css" rel="stylesheet" />
     27            <script type="text/javascript" src="${resource(dir: 'uploadify', file: 'swfobject.js')}"></script>
     28            <script type="text/javascript" src="${resource(dir: 'uploadify', file: 'jquery.uploadify.v2.1.4.min.js')}"></script>
    2429               
    2530                <g:layoutHead/>
  • trunk/grails-app/views/run/_addFilesDialog.gsp

    r7 r25  
    77                        Select sequence and quality files to upload. It is possible to zip the files before upload.
    88                </p>
    9                 <g:fileUpload name="sequencefiles" value="" multiple="${true}" onUpload="handleFileUploadData" onDelete="deleteProcessButton"/>
     9                <g:fileUpload name="sequencefiles" value="" multiple="${true}" onUpload="handleFileUploadData" onDelete="deleteProcessButton" />
    1010        </g:form>
    1111</div>
  • trunk/grails-app/views/run/index.gsp

    r18 r25  
    66                <g:javascript src="run.index.runDialog.js" />
    77
    8                 <g:javascript src="fileuploader.new.js" />
    98                <g:javascript src="fileuploads.new.js" />
    109
  • trunk/grails-app/views/run/show.gsp

    r24 r25  
    1919                <g:javascript src="assay.show.showRunDialog.js" />
    2020
    21                 <g:javascript src="fileuploader.new.js" />
    2221                <g:javascript src="fileuploads.new.js" />
    2322               
  • trunk/web-app/css/fileuploader.new.css

    r2 r25  
    88.upload_field_container .qq-upload-list { display: none; }
    99
    10 .upload_field_container .multipleFiles { list-style-type: none; margin-left: 0; padding-left: 0; }
    11 .upload_field_container .multipleFiles li { margin: 3px 0px; border-bottom: 1px solid #ccc; }
    12 .upload_field_container .multipleFiles li:last-child { border-bottom-width: 0px; }
    13 .upload_field_container .multipleFiles li span {       
     10.uploadContainer ul.files { list-style-type: none; margin-left: 0; padding-left: 0; }
     11.uploadContainer ul.files li { margin: 2px 0px; border-bottom: 1px solid #ccc; }
     12.uploadContainer ul.files li:last-child { border-bottom-width: 0px; }
     13.uploadContainer ul.files li span { padding: 4px 0;     
    1414        display: inline-block;
    1515        zoom: 1; /* IE 6 & 7 hack */
    1616        *display: inline; /* IE 6 & 7 hack */   
    1717}
    18 .upload_field_container .multipleFiles li span.filename { width: 200px; margin-right: 10px; }
    19 .upload_field_container .multipleFiles li span.filesize { width: 60px; margin-right: 10px; }
     18.uploadContainer ul.files li span.filename { width: 280px; margin-right: 10px; }
     19.uploadContainer ul.files li span.filesize { width: 60px; margin-right: 10px; }
    2020
    2121.upload_info { color: #006DBA; display: inline;  margin-left: 5px; }
  • trunk/web-app/css/metagenomics.css

    r24 r25  
    220220        width: 120px;
    221221        display: inline-block;
     222        vertical-align: top;
    222223        zoom: 1; /* IE 6 & 7 hack */
    223224        *display: inline; /* IE 6 & 7 hack */
     
    496497.ui-dialog .assaySampleDetails span.value { width: 150px; display: inline-block; *display: inline; zoom: 1; }
    497498
     499.uploadContainer { display: inline-block; *display: inline; zoom: 1 }
     500
    498501/* Makes sure the filenames in the dialog don't exceed 200px */
    499502.dataTables_wrapper .uploadedFile { display: inline-block; zoom: 1; *display: inline; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 190px; height: 15px; }
  • trunk/web-app/js/addFilesDialog.js

    r9 r25  
    3636 */
    3737function deleteProcessButton( params ) {
    38         if( $( '#upload_field_container_sequencefiles .multipleFiles li' ).size() == 0 ) {
     38        if( $( '#upload_field_container_sequencefiles ul.files li' ).size() == 0 ) {
    3939                var firstButton = $(":button:contains('Process')");
    4040                firstButton.attr("disabled","disabled").addClass('ui-state-disabled');         
  • trunk/web-app/js/fileuploads.new.js

    r2 r25  
     1// The uploadfields are saved in an array to avoid them being created twice in a jquery dialog
     2var uploadfields = new Array();
     3
    14/*************************************************
    25 *
     
    2326        if( multiple == undefined )
    2427                multiple = false;
     28       
     29        // Check whether the field has already been created
     30        if( uploadfields[ field_id ] != undefined )
     31                return;
    2532       
    2633        var uploader;
     
    3037                uploader = _createSingleUploader( field_id, uploadCallback, deleteCallback );
    3138        }
     39       
     40        uploadfields[ field_id ] = uploader;
    3241}
    3342
     
    4554 */
    4655function _createSingleUploader( field_id, uploadCallback, deleteCallback ) {
    47         var uploader;   
    48         uploader = new qq.FileUploader({
    49                 element: document.getElementById( 'upload_field_' + field_id ),
    50                 action: baseUrl + '/file/upload',
    51                 params : {},
    52                 name : field_id,
    53                 multiple: false,
    54                 onSubmit : function(id, file){
    55                         oldFile = $('#' + field_id).val();
    56                         if( oldFile != '' ) {
    57                                 if( !confirm( 'The old file is deleted when uploading a new file. Do you want to continue?') ) {
    58                                         return false;
     56        var clearId = null;
     57          $('#upload_field_' + field_id ).uploadify({
     58                    'uploader'  : baseUrl + '/uploadify/uploadify.swf',
     59                    'script'    : baseUrl + '/file/upload',
     60                    'cancelImg' : baseUrl + '/uploadify/cancel.png',
     61                    'auto'      : true,
     62                    'removeCompleted': true,
     63                    'multi'             : false,
     64                    'height'    : 20,
     65                    'buttonImg': baseUrl + '/uploadify/button.png',
     66                    'onSelect'  : function(event, id, fileObj) {
     67                        var oldFile = $('#' + field_id).val();
     68                                if( oldFile != '' ) {
     69                                        if( !confirm( 'The old file is deleted when uploading a new file. Do you want to continue?') ) {
     70                                                clearId = id;
     71                                                return false;
     72                                        }
     73                                       
     74                                        // Delete the file from disk, if it has been just uploaded. If the file was already moved from
     75                                        // the temporary directory, if will not be deleted
     76                                        if( $('#' + field_id + 'DeleteUploaded').css( 'display' ) != 'none' ) {
     77                                                deleteFileUploaded( field_id );
     78                                        }
     79                                        $('#' + field_id + 'DeleteExisting').hide();
     80                                        $('#' + field_id + 'DeleteUploaded').hide();
    5981                                }
    6082                               
    61                                 // Delete the file from disk, if it has been just uploaded. If the file was already moved from
    62                                 // the temporary directory, if will not be deleted
    63                                 if( $('#' + field_id + 'DeleteUploaded').css( 'display' ) != 'none' ) {
    64                                         deleteFileUploaded( field_id );
     83                                $('#upload_field_' + field_id ).uploadifySettings( 'scriptData', {
     84                                        'field':   field_id,
     85                                        'oldFile': oldFile
     86                                }, true);
     87                               
     88                        },
     89                        'onSelectOnce': function( event, data ) {
     90                                // This is a hack to cancel upload if the user doesn't want to overwrite his already
     91                                // uploaded file. It should be possible to cancel an upload using 'return false' from
     92                                // the onSelect event, but that doesn't work. See also uploadify forums
     93                                if( clearId != null ) {
     94                                        $('#upload_field_' + field_id ).uploadifyCancel( clearId );
     95                                        clearId = null;
     96                                }
     97                        },
     98                        'onComplete' : function(event, id, file, response, data) {
     99                                // Parse as json
     100                                var responseJSON = JSON.parse( response );
     101                               
     102                                if( response == "" || !responseJSON.success ) {
     103                                        $('#' + field_id).val( '' );
     104                                        $('#' + field_id + 'Example').html('<span class="error">Error uploading ' + createFileHTML( file.name ) + '</span>' );
     105                                        $('#' + field_id + 'DeleteUploaded').hide();
     106                                } else {
     107                                        // Activate user callback if supplied
     108                                        if( typeof uploadCallback == 'function')
     109                                                uploadCallback( {field: field_id, filename: responseJSON.filename} );
     110                                       
     111                                        $('#' + field_id).val( responseJSON.filename );
     112       
     113                                        $('#' + field_id + 'Example').html('Uploaded ' + createFileHTML( responseJSON.filename ) );
     114                                        $('#' + field_id + 'DeleteUploaded').show();
     115                                        $('#uploadcontainer_' + field_id + ' .files').show();
    65116                                }
    66117                        }
    67 
    68                         uploader.setParams({
    69                                 'field':   field_id,
    70                                 'oldFile': oldFile
    71                         });
    72 
    73                         // Give feedback to the user
    74                         $('#' + field_id + 'Example').html('Uploading ' + createFileHTML( file ) + ': ' + _createProgressHtml( field_id ) );
    75                         $('#' + field_id + 'Progress').show();
    76                         $('#' + field_id + 'DeleteExisting').hide();
    77                         $('#' + field_id + 'DeleteUploaded').hide();
    78                        
    79                         return true;
    80                 },
    81                 onProgress: function(id, fileName, loaded, total) {
    82                 if (loaded != total){
    83                     text = Math.round(loaded / total * 100) + '% from ' + uploader._formatSize(total) + " " + _createSpinnerHtml();
    84                 } else {                                   
    85                     text = uploader._formatSize(total);
    86                 }
    87                         $('#' + field_id + 'Progress').html( text );
    88                 },
    89                 onComplete : function(id, file, responseJSON) {
    90                         if( responseJSON == "" || !responseJSON.success ) {
    91                                 $('#' + field_id).val( '' );
    92                                 $('#' + field_id + 'Example').html('<span class="error">Error uploading ' + createFileHTML( file ) + '</span>' );
    93                                 $('#' + field_id + 'DeleteUploaded').hide();
    94                         } else {
    95                                 // Activate user callback if supplied
    96                                 if( typeof uploadCallback == 'function')
    97                                         uploadCallback( {field: field_id, filename: responseJSON.filename} );
    98                                
    99                                 $('#' + field_id).val( responseJSON.filename );
    100 
    101                                 $('#' + field_id + 'Example').html('Uploaded ' + createFileHTML( responseJSON.filename ) );
    102                                 $('#' + field_id + 'DeleteUploaded').show();
    103                         }
    104                 }
     118         
    105119        });
    106120       
     
    116130        }               
    117131       
    118         return uploader;
     132        return  $('#upload_field_' + field_id );
    119133}
    120134
     
    133147 */
    134148function _createMultipleUploader( field_id, uploadCallback, deleteCallback ) {
    135         var uploader;   
    136         uploader = new qq.FileUploader({
    137                 element: document.getElementById( 'upload_field_' + field_id ),
    138                 action: baseUrl + '/file/upload',
    139                 params : {},
    140                 name : field_id,
    141                 multiple: true,
    142                 onSubmit : function(id, file){
    143                         uploader.setParams({
    144                                 'field': field_id,
    145                                 'oldFile': ''
    146                         })
    147                        
    148                         // Give feedback to the user
    149                         $('#' + field_id + 'Example').html('Uploading ' + createFileHTML( file ) + ': ' + _createProgressHtml( field_id ) );
    150                         $('#' + field_id + 'Progress').show();
    151                        
    152                         return true;
    153                 },
    154                 onProgress: function(id, fileName, loaded, total) {
    155                 if (loaded != total){
    156                     text = Math.round(loaded / total * 100) + '% from ' + uploader._formatSize(total) + " " + _createSpinnerHtml();
    157                 } else {                                   
    158                     text = uploader._formatSize(total);
    159                 }
    160                         $('#' + field_id + 'Progress').html( text );
    161                 },
    162                
    163                 onComplete : function(id, file, responseJSON) {
    164                         if( responseJSON == "" || !responseJSON.success ) {
    165                                 $('#' + field_id + 'Example').html('<span class="error">Error uploading ' + createFileHTML( file ) + '</span>' );
    166                         } else {
    167                                 // Activate user callback if supplied
    168                                 if( typeof uploadCallback == 'function')
    169                                         uploadCallback( {field: field_id, filename: responseJSON.filename} );
    170 
    171                                 // Add filename to the list
    172                                 $( '#upload_field_container_' + field_id + ' ul.multipleFiles').append( _createMultipleFileHtml( field_id, id, responseJSON.filename, deleteCallback ) );
    173 
    174                                 // Remove progress text
    175                                 $('#' + field_id + 'Example').text( '' );
     149        $('#upload_field_' + field_id ).uploadify({
     150                    'uploader'  : baseUrl + '/uploadify/uploadify.swf',
     151                    'script'    : baseUrl + '/file/upload',
     152                    'cancelImg' : baseUrl + '/uploadify/cancel.png',
     153                    'auto'      : true,
     154                    'removeCompleted': true,
     155                    'multi'             : true,
     156                    'height'    : 20,
     157                    'buttonImg': baseUrl + '/uploadify/button.png',
     158                    'onSelect'  : function(event, id, fileObj) {
     159                                $('#upload_field_' + field_id ).uploadifySettings( 'scriptData', {
     160                                        'field':   field_id,
     161                                        'oldFile': ''
     162                                }, true);
     163                        },
     164                        'onComplete' : function(event, id, file, response, data) {
     165                                // Parse as json
     166                                var responseJSON = JSON.parse( response );
     167
     168                                if( response == "" || !responseJSON.success ) {
     169                                        $('#' + field_id).val( '' );
     170                                        $('#' + field_id + 'Example').html('<span class="error">Error uploading ' + createFileHTML( file.name ) + '</span>' );
     171                                } else {
     172                                        // Activate user callback if supplied
     173                                        if( typeof uploadCallback == 'function')
     174                                                uploadCallback( {field: field_id, filename: responseJSON.filename} );
     175                                       
     176                                        //$('#' + field_id + 'Example').html('Uploaded ' + createFileHTML( responseJSON.filename ) );
     177
     178                                        // Add filename to the list
     179                                        $( '#uploadcontainer_' + field_id + ' ul.files').append( _createMultipleFileHtml( field_id, id, responseJSON.filename, deleteCallback ) );
     180                                       
     181                                        // Show the upload message and the files list
     182                                        $('#uploadcontainer_' + field_id + ' .files').show();
     183                                }
     184                               
     185                                $( '#upload_field_' + field_id ).uploadifyCancel( id );
    176186                        }
    177                 }
    178         });     
    179         return uploader;
    180        
     187         
     188        });
     189       
     190        return $('#upload_field_' + field_id );
    181191}
    182192
Note: See TracChangeset for help on using the changeset viewer.