Files
SimpleNotes/domain/src/ExportService.kt
T
2023-05-09 22:40:10 +02:00

61 lines
1.9 KiB
Kotlin

package be.simplenotes.domain
import be.simplenotes.persistence.repositories.NoteRepository
import be.simplenotes.types.ExportedNote
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.json.Json
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 jakarta.inject.Singleton
interface ExportService {
fun exportAsJson(userId: Int): String
fun exportAsZip(userId: Int): InputStream
}
@Singleton
internal class ExportServiceImpl(
private val noteRepository: NoteRepository,
private val json: Json,
) : ExportService {
override fun exportAsJson(userId: Int): String {
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())
}
}
private 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()
}
}