Index: build.gradle =================================================================== diff -u -r12bf8be979676a724c45b4d047efda4c6f941605 -r3152d1837aa6c1bcc2a9418285093646e922f14f --- build.gradle (.../build.gradle) (revision 12bf8be979676a724c45b4d047efda4c6f941605) +++ build.gradle (.../build.gradle) (revision 3152d1837aa6c1bcc2a9418285093646e922f14f) @@ -28,6 +28,7 @@ maven { url 'https://workhorse.lemanscorp.com/nexus/content/groups/public/' } } + dependencies { implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'org.springframework.boot:spring-boot-starter-web' @@ -70,6 +71,10 @@ implementation 'org.springframework.boot:spring-boot-starter-data-jpa' compile group: 'com.opencsv', name: 'opencsv', version: '3.3' compile group: 'org.json', name: 'json', version: '20090211' + + compile group: 'org.apache.tika', name: 'tika-core', version: '1.4' + compile 'commons-fileupload:commons-fileupload:1.3.1' + compile 'org.codehaus.groovy.modules.http-builder:http-builder:0.7.2' } test { Index: src/main/groovy/com/lemans/media/MediaApplication.groovy =================================================================== diff -u -r12bf8be979676a724c45b4d047efda4c6f941605 -r3152d1837aa6c1bcc2a9418285093646e922f14f --- src/main/groovy/com/lemans/media/MediaApplication.groovy (.../MediaApplication.groovy) (revision 12bf8be979676a724c45b4d047efda4c6f941605) +++ src/main/groovy/com/lemans/media/MediaApplication.groovy (.../MediaApplication.groovy) (revision 3152d1837aa6c1bcc2a9418285093646e922f14f) @@ -1,13 +1,13 @@ package com.lemans.media +import com.lemans.services.LemansApplication import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication @SpringBootApplication -class MediaApplication { +class MediaApplication extends LemansApplication { static void main(String[] args) { SpringApplication.run(MediaApplication, args) } - } Index: src/main/groovy/com/lemans/media/controllers/TemporaryMediaController.groovy =================================================================== diff -u --- src/main/groovy/com/lemans/media/controllers/TemporaryMediaController.groovy (revision 0) +++ src/main/groovy/com/lemans/media/controllers/TemporaryMediaController.groovy (revision 3152d1837aa6c1bcc2a9418285093646e922f14f) @@ -0,0 +1,48 @@ +package com.lemans.media.controllers + +import com.lemans.api.LeMansApiController +import com.lemans.media.services.MediaManagerService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.RestController +import org.springframework.web.multipart.MultipartFile + +@RestController +@RequestMapping("/dm/{dm}") +class TemporaryMediaController extends LeMansApiController { + + @Autowired(required = true) + MediaManagerService mediaManagerService + + @PostMapping(value = "/media") + def addTempMedia(@RequestParam('file') MultipartFile[] multipartFiles) { + List multiPartFiles = multipartFiles ?: [] + List errors = [] + if (!multiPartFiles) { errors << 'No files found to upload!' } + if (!request.getParameter('mediaTypeId')) { errors << 'Media Type is a required field' } + if (!request.getParameter('mediaCategoryId')) { errors << 'Media Category is a required field' } + if (errors) { renderErrors(errors) } + else { + Map data = mediaManagerService.addTemporaryMedia(multiPartFiles, mediaCriteria()) + if (data.errors) { renderErrors(data.errors) } + else { render([results: data.results]) } + } + } + + @PostMapping(value = "/media/temp") + def temp(@RequestParam('file') MultipartFile[] multipartFile) { + MultipartFile file = multipartFile ? multipartFile[0] : null + if (file) { + Map data = mediaManagerService.addTemporaryMedia(file) + if (data.errors) { renderErrors(data.errors) } + else { render([results: data.results]) } + } else { renderErrors(['No file found to upload!']) } + } + + private Map mediaCriteria() { + [mediaCategoryId: request.getParameter('mediaCategoryId').toInteger(), + mediaTypeId: request.getParameter('mediaTypeId').toInteger()] + filters(['description']) + } +} Index: src/main/groovy/com/lemans/media/services/MediaManagerService.groovy =================================================================== diff -u --- src/main/groovy/com/lemans/media/services/MediaManagerService.groovy (revision 0) +++ src/main/groovy/com/lemans/media/services/MediaManagerService.groovy (revision 3152d1837aa6c1bcc2a9418285093646e922f14f) @@ -0,0 +1,129 @@ +package com.lemans.media.services + +import com.lemans.services.LemansManager +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service +import org.springframework.web.multipart.MultipartFile +import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest +import org.apache.commons.io.FilenameUtils +import org.apache.tika.detect.Detector +import org.apache.tika.metadata.Metadata +import org.apache.tika.parser.AutoDetectParser + +@Service +class MediaManagerService extends LemansManager { + + @Autowired(required = true) + String temporaryDocumentPath + + @Autowired(required = true) + String temporaryMediaPath + + private static final String MIME_TYPE_SQL = ''' +SELECT * +FROM dbo.vwMimeType +WHERE mimeType = ? AND extension = ? +''' + + Map addTemporaryMedia(List multiPartFiles, Map criteria) { + List errors = [] + List results = [] + multiPartFiles.each { StandardMultipartHttpServletRequest.StandardMultipartFile multiPartFile -> + String fileName = multiPartFile.originalFilename + if (multiPartFile.isEmpty()) { errors << "Uploaded file $fileName is empty, Please upload a valid file" } + else { + String randomString = UUID.randomUUID() + try { + File file = new File(tempFileName(randomString, fileName)) + file << multiPartFile.inputStream + } catch (IOException x) { + String message = "Error uploading file $fileName" + log.error(message, x) + errors << "$message, try again." + } + results << criteria + splitFileName(fileName) + [tempId: randomString, prefixUrl: 'dealer/temp/'] + } + } + [results: results, errors: errors] + } + + private String tempFileName(String randomString, String fileName) { + String temp = temporaryDocumentPath + File.separator + randomString + String ext = extension(fileName) + if (ext) { temp += ".$ext" } + temp + } + + private Map splitFileName(String name) { + name ? [fileName: FilenameUtils.getBaseName(name), extension: extension(name)] : [:] + } + + Map addTemporaryMedia(MultipartFile multiPartFile) { + List errors = [] + Map results = [:] + Map mimeType = [:] + String fileName = multiPartFile.originalFilename + if (multiPartFile.isEmpty()) { errors << "Uploaded file $fileName is empty, Please upload a valid file" } + else { + String randomString = UUID.randomUUID() + try { + String tempFileName = tempFilePath(randomString, fileName) + File file = new File(tempFileName) + file << multiPartFile.inputStream + String mimeTypeDescription = getMimeType(file, tempFileName) + mimeType = findMimeType(mimeTypeDescription, extension(tempFileName)) + if (!mimeType?.mimeTypeId) { errors << 'Mime type of the uploaded file is not supported' } + if (!mimeType?.mediaTypeId) { errors << 'Media type of the uploaded file is not supported' } + } catch (IOException x) { + String message = "Error uploading file $fileName" + log.error message, x + errors << "$message, try again." + } + results = [tempId: randomString, prefixUrl: 'media/'] + originalFileName(fileName) + mimeTypeInfo(mimeType) + } + [results: results, errors: errors] + } + + private mimeTypeInfo(Map mimeType) { + mimeType ? [mimeTypeId: mimeType.mimeTypeId, mediaTypeId: mimeType.mediaTypeId, mediaTypeCode: mimeType.mediaTypeCode] : [:] + } + + private String tempFilePath(String randomString, String fileName) { + String temp = temporaryMediaPath + File.separator + randomString + String ext = extension(fileName) + if (ext) { temp += ".$ext" } + temp + } + + private String extension(String name) { name ? FilenameUtils.getExtension(name) : '' } + + private Map originalFileName(String name) { + name ? [originalFileName: FilenameUtils.getBaseName(name), extension: extension(name)] : [:] + } + + private Map findMimeType(String mimeType, String extension) { + sql().rows(MIME_TYPE_SQL, [mimeType, extension])[0] + } + + @SuppressWarnings(['CatchException']) + private String getMimeType(File file, String fileName) { + if (file.exists() && file.canRead()) { + InputStream is + BufferedInputStream bis + try { + is = new FileInputStream(file) + AutoDetectParser parser = new AutoDetectParser() + Detector detector = parser.detector + Metadata md = new Metadata() + md.add(Metadata.RESOURCE_NAME_KEY, fileName) + bis = new BufferedInputStream(is) + detector.detect(bis, md)?.toString() + } catch (Exception e) { + log.error e.message + } finally { + is?.close() + bis?.close() + } + } + } +} Index: src/main/resources/resources.groovy =================================================================== diff -u -r12bf8be979676a724c45b4d047efda4c6f941605 -r3152d1837aa6c1bcc2a9418285093646e922f14f --- src/main/resources/resources.groovy (.../resources.groovy) (revision 12bf8be979676a724c45b4d047efda4c6f941605) +++ src/main/resources/resources.groovy (.../resources.groovy) (revision 3152d1837aa6c1bcc2a9418285093646e922f14f) @@ -2,16 +2,23 @@ import org.apache.http.impl.client.DefaultHttpClient import org.apache.http.impl.conn.PoolingClientConnectionManager - beans { if (Env.getCurrent() == Env.PRODUCTION) { authServiceContext(org.springframework.jndi.JndiObjectFactoryBean) { jndiName = 'java:comp/env/authServiceContext' } + temporaryDocumentPath(org.springframework.jndi.JndiObjectFactoryBean) { + jndiName = 'java:comp/env/temporaryDocumentPath' + } + temporaryMediaPath(org.springframework.jndi.JndiObjectFactoryBean) { + jndiName = 'java:comp/env/temporaryMediaPath' + } } else { authServiceContext(String, 'http://services3.dev.lemanscorp.com/auth-service/verifyRequest') + temporaryDocumentPath(String, 'temporaryDocumentPath') + temporaryMediaPath(String, 'temporaryMediaPath') } httpConnectionManager(PoolingClientConnectionManager) {