61 lines
1.9 KiB
Kotlin
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()
|
|
}
|
|
}
|