Index: content-bundles/resources/content.properties =================================================================== --- content-bundles/resources/content.properties (revision 309293) +++ content-bundles/resources/content.properties (working copy) @@ -662,9 +662,9 @@ content.action.my = Gets the content items for the current user's workspace site. URL should be of the form /direct/content/my.format. dragndrop.success.upload = File successfully uploaded -dragndrop.upload.error = There was an error uploading the file {0} to server -dragndrop.duplicated.error = The file {0} cannot be duplicated in server more than {1} times -dragndrop.collection.error = There was an error managing the collection {0} to store the file {1} +dragndrop.upload.error = There was an error uploading the file {0} to the server +dragndrop.duplicated.error = The file {0} cannot be duplicated more than {1} times +dragndrop.collection.error = There was an error attempting to store the file {1} in the folder {0} # SAK-25709 list.cols.columns=Display Columns Index: content-bundles/resources/types.properties =================================================================== --- content-bundles/resources/types.properties (revision 309293) +++ content-bundles/resources/types.properties (working copy) @@ -533,7 +533,8 @@ # SAK-23367 notes.expandfolder=Expand folder(s) of interest and select item(s) to copy to your current site above. -label.dragDescription=Drag and drop files into the box to upload. If you upload a zip file the contents will be unzipped into a folder. It may take a few minutes to upload large files. +label.dragDescription=Drag and drop files from your dekstop into the box below. +label.dragDescriptionZip=Zip files will be automatically expanded. Large files may take several minutes to upload. label.dragZoneMessage=Drop files here to upload. alert.over-site-upload-quota=Your file upload attempt could not be completed because doing so would put you over your site quota. Please check the sum total file size of all items you wish to upload before your next attempt. link.switch.to.dnd = Switch to Drag and Drop Upload? @@ -549,4 +550,4 @@ dragndrop.dictCancelUploadConfirmation=Are you sure you want to cancel this upload? dragndrop.dictRemoveFile=Remove file dragndrop.dictMaxFilesExceeded=You can not upload any more files. -dragndrop.dictFolderUploadError=Folder upload is not supported by your current browser. Currently, only Chrome 21 or upper allows it. \ No newline at end of file +dragndrop.dictFolderUploadError=Folder upload is not supported by your current browser. Currently, only Chrome 21 or upper allows it. Index: content-bundles/resources/types_ca_ES.properties =================================================================== --- content-bundles/resources/types_ca_ES.properties (revision 309293) +++ content-bundles/resources/types_ca_ES.properties (working copy) @@ -524,7 +524,8 @@ # SAK-23367 notes.expandfolder=Desplegueu les carpetes d'inter\u00e8s i escolliu els elements que voleu copiar al vostre espai. -label.dragDescription=Arrossegueu els fitxers fins al quadre per pujar-los. Si pugeu un fitxer comprimit zip els seus continguts es descompriran dins d'una carpeta. El proc\u00e9s pot durar uns minuts si pugueu fitxers grans. +label.dragDescription=Arrossegueu els fitxers fins al quadre per pujar-los. +label.dragDescriptionZip=Si pugeu un fitxer comprimit zip els seus continguts es descompriran dins d'una carpeta. El proc\u00e9s pot durar uns minuts si pugueu fitxers grans. label.dragZoneMessage=Arrossegueu fins aqu\u00ed els fitxer que voleu pujar. alert.over-site-upload-quota=El fitxer no s'ha pogut pujar perqu\u00e8 implicaria superar la quota d'emmagatzematge d'aquest espai. Comproveu la mida total dels elements que voleu pujar abans de tornar-ho a provar. Index: content-bundles/resources/types_es_ES.properties =================================================================== --- content-bundles/resources/types_es_ES.properties (revision 309293) +++ content-bundles/resources/types_es_ES.properties (working copy) @@ -524,7 +524,8 @@ # SAK-23367 notes.expandfolder=Expanda la(s) carpeta(s) de inter\u00e9s y seleccione el/los elemento(s) a copiar a su sitio actual. -label.dragDescription=Arrastre y suelte ficheros en la caja para subirlos. Si sube un fichero zip, los contenidos ser\u00e1 descomprimidos en una carpeta. Puede llevar unos pocos minutos si intenta subir ficheros pesados. +label.dragDescription=Arrastre y suelte ficheros en la caja para subirlos. +label.dragDescriptionZip=Si sube un fichero zip, los contenidos ser\u00e1 descomprimidos en una carpeta. Puede llevar unos pocos minutos si intenta subir ficheros pesados. label.dragZoneMessage=Arrastre y suelte ficheros para subirlos. alert.over-site-upload-quota=Su acci\u00f3n de subir ficheros no se pudo completar porque sobrepasan la capacidad de almacenamiento de su sitio. Por favor, compruebe la suma total de los tama\u00f1os de todos los \u00edtems que quiere subir antes del pr\u00f3ximo intento. link.switch.to.dnd=Cambiar a carga mediante Drag&Drop Index: content-bundles/resources/types_eu.properties =================================================================== --- content-bundles/resources/types_eu.properties (revision 309293) +++ content-bundles/resources/types_eu.properties (working copy) @@ -520,7 +520,8 @@ # SAK-23367 notes.expandfolder=Zabaldu interesatzen zaizkizun karpetak eta hautatu itemak zure uneko gunea kopiatzeko, goian. -label.dragDescription=Igotzeko fitxategiak arrastatu eta askatu eremu barrura. Zip bat igotzen baduzu edukiak karpeta baten barruan deskonprimituko dira. Fitxategi luzeek minutu batzuk behar dituzte kargatu arte. +label.dragDescription=Igotzeko fitxategiak arrastatu eta askatu eremu barrura. +label.dragDescriptionZip=Zip bat igotzen baduzu edukiak karpeta baten barruan deskonprimituko dira. Fitxategi luzeek minutu batzuk behar dituzte kargatu arte. label.dragZoneMessage=Ekarri hona fitxategiak igotzeko. alert.over-site-upload-quota=Fitxategia igotzeko saioa ezin izan da burutu gunearen kapazitate muga gainditzear egon daitekeelako. Begiratu igo nahi dituzun fitxategien pisua. Index: content-tool/tool/src/java/org/sakaiproject/content/tool/ResourcesHelperAction.java =================================================================== --- content-tool/tool/src/java/org/sakaiproject/content/tool/ResourcesHelperAction.java (revision 309293) +++ content-tool/tool/src/java/org/sakaiproject/content/tool/ResourcesHelperAction.java (working copy) @@ -704,6 +704,7 @@ Boolean dragAndDrop = ServerConfigurationService.getBoolean("content.upload.dragndrop", true); String strDragAndDropEnabled = ToolManager.getCurrentPlacement().getConfig().getProperty(TOOL_PROP_DRAGNDROP_ENABLED); + Boolean decompressZipFilesEnabled = ServerConfigurationService.getBoolean("content.zip.enabled", true) && ServerConfigurationService.getBoolean("content.zip.expand.enabled",true); if (StringUtils.isNotBlank(strDragAndDropEnabled)) { @@ -711,6 +712,7 @@ } context.put("dragAndDrop", dragAndDrop); + context.put("decompressZipFilesEnabled", decompressZipFilesEnabled); // int max_bytes = 1024 * 1024; // try @@ -1961,7 +1963,7 @@ } - private synchronized void doDragDropUpload(HttpServletRequest request, HttpServletResponse response, String fullPath) + private void doDragDropUpload(HttpServletRequest request, HttpServletResponse response, String fullPath) { //Feel free to sent comments/warnings/advices to me at daniel.merino AT unavarra.es @@ -1979,117 +1981,107 @@ String collectionName=null; String resourceGroup = toolSession.getAttribute("resources.request.create_wizard_collection_id").toString(); + + Boolean decompressZipFiles = ServerConfigurationService.getBoolean("content.zip.enabled", true) && ServerConfigurationService.getBoolean("content.zip.expand.enabled",true); - if (!("undefined".equals(fullPath))) + //Start of synchronization (see SAK-26102) + synchronized(this) { - //Received a file that is inside an uploaded folder - //Try to create a collection with this folder and to add the file inside it after - File myfile = new File(fullPath); - String fileName = myfile.getName(); - collectionName=resourceGroup+myfile.getParent(); - - //AFAIK it is not possible to check undoubtedly if a collection exists - //isCollection() only tests if name is valid and checkCollection() returns void type - //So the procedure is to create the collection and capture thrown Exceptions - collection = createCollectionIfNotExists(collectionName); - - if (collection==null) + if (!("undefined".equals(fullPath))) { - addAlert(state,contentResourceBundle.getFormattedMessage("dragndrop.collection.error",new Object[]{collectionName,fileName})); - return; - } - } + //Received a file that is inside an uploaded folder + //Try to create a collection with this folder and to add the file inside it after + File myfile = new File(fullPath); + String fileName = myfile.getName(); + collectionName=resourceGroup+myfile.getParent(); - try - { - //Now upload the received file - //Test that file has been sent in request - DiskFileItem uploadFile = (DiskFileItem) request.getAttribute("file"); - String contentType = uploadFile.getContentType(); - - if(uploadFile != null) - { - uploadFileName=uploadFile.getName(); + //AFAIK it is not possible to check undoubtedly if a collection exists + //isCollection() only tests if name is valid and checkCollection() returns void type + //So the procedure is to create the collection and capture thrown Exceptions + collection = createCollectionIfNotExists(collectionName); - String extension = ""; - String basename = uploadFileName.trim(); - if (uploadFileName.contains(".")) { - String[] parts = uploadFileName.split("\\."); - basename = parts[0]; - if (parts.length > 1) { - extension = parts[parts.length - 1]; - } - for (int i = 1; i < parts.length - 1; i++) { - basename += "." + parts[i]; - } - } - - if (collection!=null) + if (collection==null) { - logger.debug("Adding resource "+uploadFileName+" in collection "+collection.getId()); - resource = ContentHostingService.addResource(collection.getId(), Validator.escapeResourceName(basename),Validator.escapeResourceName(extension),5); + addAlert(state,contentResourceBundle.getFormattedMessage("dragndrop.collection.error",new Object[]{collectionName,fileName})); + return; } - else - { - //Method getUniqueFileName was added to change external name of uploaded resources if they exist already in the collection, just the same way that their internal id. - //However, that is not the way Resources tool works. Internal id is changed but external name is the same for every copy of the same file. - //So I disable this method call, though it can be enabled again if desired. - - //String resourceName = getUniqueFileName(uploadFileName, resourceGroup); - - logger.debug("Adding resource "+uploadFileName+" in current folder ("+resourceGroup+")"); - resource = ContentHostingService.addResource(resourceGroup, Validator.escapeResourceName(basename), Validator.escapeResourceName(extension),5); - } + } - if (resource != null) + try + { + //Now upload the received file + //Test that file has been sent in request + DiskFileItem uploadFile = (DiskFileItem) request.getAttribute("file"); + String contentType = uploadFile.getContentType(); + + if(uploadFile != null) { - if (contentType!=null) resource.setContentType(contentType); + uploadFileName=uploadFile.getName(); - ResourcePropertiesEdit resourceProps = resource.getPropertiesEdit(); - resourceProps.addProperty(ResourcePropertiesEdit.PROP_DISPLAY_NAME, uploadFileName); - resource.setContent(uploadFile.getInputStream()); - resource.setContentType(contentType); - ContentHostingService.commitResource(resource, NotificationService.NOTI_NONE); - - if (collection != null){ - ContentHostingService.commitCollection(collection); - logger.debug("Collection commited: "+collection.getId()); + String extension = ""; + String basename = uploadFileName.trim(); + if (uploadFileName.contains(".")) { + String[] parts = uploadFileName.split("\\."); + basename = parts[0]; + if (parts.length > 1) { + extension = parts[parts.length - 1]; + } + for (int i = 1; i < parts.length - 1; i++) { + basename += "." + parts[i]; + } } + + if (collection!=null) + { + logger.debug("Adding resource "+uploadFileName+" in collection "+collection.getId()); + resource = ContentHostingService.addResource(collection.getId(), Validator.escapeResourceName(basename),Validator.escapeResourceName(extension),5); + } + else + { + //Method getUniqueFileName was added to change external name of uploaded resources if they exist already in the collection, just the same way that their internal id. + //However, that is not the way Resources tool works. Internal id is changed but external name is the same for every copy of the same file. + //So I disable this method call, though it can be enabled again if desired. + + //String resourceName = getUniqueFileName(uploadFileName, resourceGroup); + + logger.debug("Adding resource "+uploadFileName+" in current folder ("+resourceGroup+")"); + resource = ContentHostingService.addResource(resourceGroup, Validator.escapeResourceName(basename), Validator.escapeResourceName(extension),5); + } - if (uploadFileName.contains(".zip")) + if (resource != null) { - ZipContentUtil zipContentUtil = new ZipContentUtil(); - zipContentUtil.extractArchive(EntityManager.newReference(resource.getReference())); + if (contentType!=null) resource.setContentType(contentType); + + ResourcePropertiesEdit resourceProps = resource.getPropertiesEdit(); + resourceProps.addProperty(ResourcePropertiesEdit.PROP_DISPLAY_NAME, uploadFileName); + resource.setContent(uploadFile.getInputStream()); + resource.setContentType(contentType); + ContentHostingService.commitResource(resource, NotificationService.NOTI_NONE); + + if (collection != null){ + ContentHostingService.commitCollection(collection); + logger.debug("Collection commited: "+collection.getId()); + } } + else + { + addAlert(state, contentResourceBundle.getFormattedMessage("dragndrop.upload.error",new Object[]{uploadFileName})); + return; + } } - else - { - addAlert(state, contentResourceBundle.getFormattedMessage("dragndrop.upload.error",new Object[]{uploadFileName})); - return; - } } - } - catch (IdUniquenessException e) - { - addAlert(state,contentResourceBundle.getFormattedMessage("dragndrop.duplicated.error",new Object[]{uploadFileName,ResourcesAction.MAXIMUM_ATTEMPTS_FOR_UNIQUENESS})); - return; - } - catch (OverQuotaException e) { - addAlert(state, rb.getString("alert.over-site-upload-quota")); - logger.warn("Drag and drop upload failed: " + e, e); - } catch (Exception e) { - logger.warn("Drag and drop upload failed: " + e, e); - } finally - { - if (uploadFileName.contains(".zip")) { - //remove the zip file after unpacking it - try { - ContentHostingService.removeResource(resource.getId()); - } catch (Exception e) { - logger.warn("Unable to remove zip file: " + e, e); - } + catch (IdUniquenessException e) + { + addAlert(state,contentResourceBundle.getFormattedMessage("dragndrop.duplicated.error",new Object[]{uploadFileName,ResourcesAction.MAXIMUM_ATTEMPTS_FOR_UNIQUENESS})); + return; } - } + catch (OverQuotaException e) { + addAlert(state, rb.getString("alert.over-site-upload-quota")); + logger.warn("Drag and drop upload failed: " + e, e); + } catch (Exception e) { + logger.warn("Drag and drop upload failed: " + e, e); + } + } //End of synchronization block try { @@ -2106,6 +2098,39 @@ logger.error("Exception writing response in ResourcesHelperAction"); return; } + + //The unzip is out of synchronized code so we don't stop other uploads from happening at the same time + try + { + if ((uploadFileName.contains(".zip")) && (decompressZipFiles)) + { + ContentHostingService.expandZippedResource(EntityManager.newReference(resource.getReference())); + } + } + catch (OverQuotaException e) + { + addAlert(state, rb.getString("alert.over-site-upload-quota")); + logger.warn("Drag and drop upload failed: " + e, e); + } + catch (Exception e) + { + logger.warn("Drag and drop upload failed: " + e, e); + } + finally + { + if ((uploadFileName.contains(".zip")) && (decompressZipFiles)) + { + //remove the zip file after unpacking it + try + { + ContentHostingService.removeResource(resource.getId()); + } + catch (Exception e) + { + logger.warn("Unable to remove zip file: " + e, e); + } + } + } toolSession.setAttribute(ResourceToolAction.DONE, Boolean.TRUE); } Index: content-tool/tool/src/webapp/vm/resources/sakai_create_uploads.vm =================================================================== --- content-tool/tool/src/webapp/vm/resources/sakai_create_uploads.vm (revision 309293) +++ content-tool/tool/src/webapp/vm/resources/sakai_create_uploads.vm (working copy) @@ -120,7 +120,11 @@ #if($dragAndDrop)
-

$tlang.getString("label.dragDescription") $tlang.getString("link.switch.to.upload")

+

$tlang.getString("label.dragDescription") + #if($decompressZipFilesEnabled) + $tlang.getString("label.dragDescriptionZip") + #end + $tlang.getString("link.switch.to.upload")