Add zip export

This commit is contained in:
2020-09-28 19:13:54 +02:00
parent a7c8e63b11
commit 0dfb2a7e03
4 changed files with 70 additions and 16 deletions
+5
View File
@@ -61,6 +61,11 @@
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-serialization-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.20</version>
</dependency>
</dependencies>
</project>
@@ -1,5 +1,8 @@
package be.simplenotes.domain.usecases.export
import java.io.InputStream
interface ExportUseCase {
fun export(userId: Int): String
fun exportAsJson(userId: Int): String
fun exportAsZip(userId: Int): InputStream
}
@@ -11,10 +11,15 @@ import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.InputStream
import java.time.LocalDateTime
internal class ExportUseCaseImpl(private val noteRepository: NoteRepository) : ExportUseCase {
override fun export(userId: Int): String {
override fun exportAsJson(userId: Int): String {
val module = SerializersModule {
contextual(LocalDateTime::class, LocalDateTimeSerializer)
}
@@ -27,8 +32,41 @@ internal class ExportUseCaseImpl(private val noteRepository: NoteRepository) : E
val notes = noteRepository.export(userId)
return json.encodeToString(ListSerializer(ExportedNote.serializer()), notes)
}
private fun sanitizeFilename(inputName: String): String = inputName.replace("[^a-zA-Z0-9-_.]".toRegex(), "_")
override fun exportAsZip(userId: Int): InputStream {
val notes = noteRepository.export(userId)
val zipOutput = ZipOutput()
zipOutput.use { zip ->
notes.forEach {
val name = sanitizeFilename(it.title)
zip.write("notes/$name.md", it.markdown)
}
}
return ByteArrayInputStream(zipOutput.outputStream.toByteArray())
}
}
class ZipOutput : AutoCloseable {
val outputStream = ByteArrayOutputStream()
private val zipOutputStream = ZipArchiveOutputStream(outputStream)
fun write(path: String, content: String) {
val entry = ZipArchiveEntry(path)
zipOutputStream.putArchiveEntry(entry)
zipOutputStream.write(content.toByteArray())
zipOutputStream.closeArchiveEntry()
}
override fun close() {
zipOutputStream.finish()
zipOutputStream.close()
}
}
internal object LocalDateTimeSerializer : KSerializer<LocalDateTime> {
override val descriptor: SerialDescriptor
get() = PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING)