Add file storage unzip for uploader and extract the resources
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Sambo Chea 2022-04-21 16:53:00 +07:00
parent fd12704bd5
commit c38b8767a5
Signed by: sombochea
GPG Key ID: 3C7CF22A05D95490
6 changed files with 107 additions and 9 deletions

View File

@ -2,6 +2,7 @@ package com.cubetiqs.web.modules.file
import org.springframework.web.multipart.MultipartFile import org.springframework.web.multipart.MultipartFile
import java.io.File import java.io.File
import java.io.InputStream
object FileStorageFactory { object FileStorageFactory {
private var provider: FileStorageProvider? = null private var provider: FileStorageProvider? = null
@ -36,10 +37,16 @@ object FileStorageFactory {
} }
fun zipAll(): ByteArray? { fun zipAll(): ByteArray? {
if (getProvider() is FileStorageZipper) { if (getProvider() is FileStorageZip) {
return (getProvider() as FileStorageZipper).zip(null) return (getProvider() as FileStorageZip).zip(null)
} }
return null return null
} }
fun unzip(inputStream: InputStream) {
if (getProvider() is FileStorageUnzip) {
(getProvider() as FileStorageUnzip).unzip(inputStream, null)
}
}
} }

View File

@ -2,11 +2,12 @@ package com.cubetiqs.web.modules.file
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
open class FileStorageLocalProvider( open class FileStorageLocalProvider(
private val basePath: String, private val basePath: String,
) : FileStorageProvider, FileStorageZipper { ) : FileStorageProvider, FileStorageZip, FileStorageUnzip {
private fun loadBasePath(fileName: String): String { private fun loadBasePath(fileName: String): String {
val prefixPath = if (basePath.endsWith("/")) { val prefixPath = if (basePath.endsWith("/")) {
"" ""
@ -60,4 +61,8 @@ open class FileStorageLocalProvider(
override fun zip(sourceFolder: String?): ByteArray { override fun zip(sourceFolder: String?): ByteArray {
return FileZipper.zipToBytes(sourceFolder ?: basePath) return FileZipper.zipToBytes(sourceFolder ?: basePath)
} }
override fun unzip(inputStream: InputStream, destinationFolder: String?) {
return FileZipper.unzip(inputStream, destinationFolder ?: basePath)
}
} }

View File

@ -0,0 +1,7 @@
package com.cubetiqs.web.modules.file
import java.io.InputStream
interface FileStorageUnzip {
fun unzip(inputStream: InputStream, destinationFolder: String?)
}

View File

@ -3,7 +3,7 @@ package com.cubetiqs.web.modules.file
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.OutputStream import java.io.OutputStream
interface FileStorageZipper { interface FileStorageZip {
fun zip(sourceFolder: String?, os: OutputStream) fun zip(sourceFolder: String?, os: OutputStream)
fun zip(sourceFolder: String?): ByteArray { fun zip(sourceFolder: String?): ByteArray {
val os = ByteArrayOutputStream() val os = ByteArrayOutputStream()

View File

@ -1,15 +1,17 @@
package com.cubetiqs.web.modules.file package com.cubetiqs.web.modules.file
import java.io.ByteArrayOutputStream import java.io.*
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream
import java.nio.file.* import java.nio.file.*
import java.nio.file.attribute.BasicFileAttributes import java.nio.file.attribute.BasicFileAttributes
import java.util.zip.ZipEntry import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream import java.util.zip.ZipOutputStream
object FileZipper { object FileZipper {
private const val BUFFER = 2048
fun zip(sourceFolder: String, destFolder: String) { fun zip(sourceFolder: String, destFolder: String) {
try { try {
val zipFolder = if (destFolder.endsWith(".zip")) { val zipFolder = if (destFolder.endsWith(".zip")) {
@ -55,4 +57,71 @@ object FileZipper {
zipToStream(sourceFolder, bos) zipToStream(sourceFolder, bos)
return bos.toByteArray() return bos.toByteArray()
} }
fun unzipFromFile(sourceZipFile: File, destFolder: String) {
try {
val zipFile = ZipFile(sourceZipFile)
val entries = zipFile.entries()
while (entries.hasMoreElements()) {
val entry = entries.nextElement()
val destFile = File(destFolder, entry.name)
if (entry.isDirectory) {
destFile.mkdirs()
} else {
destFile.parentFile.mkdirs()
val istream = zipFile.getInputStream(entry)
val ostream = FileOutputStream(destFile)
val buffer = ByteArray(BUFFER)
var len: Int
while (istream.read(buffer).also { len = it } > 0) {
ostream.write(buffer, 0, len)
}
ostream.close()
istream.close()
}
}
zipFile.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
fun unzip(fis: InputStream, destFolder: String) {
try {
val root = File(destFolder)
if (!root.exists()) {
root.mkdir()
}
val zis = ZipInputStream(BufferedInputStream(fis))
var entry: ZipEntry?
while (zis.nextEntry.also { entry = it } != null) {
val fileName = entry?.name
val file = File(destFolder + File.separator.toString() + fileName)
if (entry?.isDirectory == false) {
extractFileContentFromArchive(file, zis)
} else {
if (!file.exists()) {
file.mkdirs()
}
}
zis.closeEntry()
}
zis.close()
} catch (e: Exception) {
e.printStackTrace()
}
}
@Throws(IOException::class)
private fun extractFileContentFromArchive(file: File, zis: ZipInputStream) {
val fos = FileOutputStream(file)
val bos = BufferedOutputStream(fos, BUFFER)
var len: Int
val data = ByteArray(BUFFER)
while (zis.read(data, 0, BUFFER).also { len = it } != -1) {
bos.write(data, 0, len)
}
bos.flush()
bos.close()
}
} }

View File

@ -79,10 +79,11 @@ class UploaderController @Autowired constructor(
@GetMapping("/zip", produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE]) @GetMapping("/zip", produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE])
@Operation(summary = "Zip all files") @Operation(summary = "Zip all files")
fun zipAll( fun zipAll(
@RequestParam(required = false, value = "filename", defaultValue = "files") filename: String?,
response: HttpServletResponse, response: HttpServletResponse,
) { ) {
val zipBytes = FileStorageFactory.zipAll() ?: throw IllegalArgumentException("Zip file not found") val zipBytes = FileStorageFactory.zipAll() ?: throw IllegalArgumentException("Zip file not found")
response.setHeader("Content-Disposition", "attachment; filename=\"files.zip\"") response.setHeader("Content-Disposition", "attachment; filename=\"$filename.zip\"")
response.contentType = "application/zip" response.contentType = "application/zip"
response.setContentLengthLong(zipBytes.size.toLong()) response.setContentLengthLong(zipBytes.size.toLong())
@ -99,6 +100,15 @@ class UploaderController @Autowired constructor(
return repository.save(entity) return repository.save(entity)
} }
@ResponseStatus(value = org.springframework.http.HttpStatus.CREATED)
@PostMapping("/unzip", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
@Operation(summary = "Zip a file")
fun unzip(
@RequestPart file: MultipartFile,
) {
FileStorageFactory.unzip(file.inputStream)
}
@ResponseStatus(value = org.springframework.http.HttpStatus.OK) @ResponseStatus(value = org.springframework.http.HttpStatus.OK)
@PutMapping("/{id}") @PutMapping("/{id}")
@Operation(summary = "Update a file by id") @Operation(summary = "Update a file by id")