124 lines
4.5 KiB
Kotlin
124 lines
4.5 KiB
Kotlin
package com.android.trisolarisserver.component
|
|
|
|
import org.apache.pdfbox.pdmodel.PDDocument
|
|
import org.apache.pdfbox.pdmodel.PDPage
|
|
import org.apache.pdfbox.pdmodel.PDPageContentStream
|
|
import org.apache.pdfbox.pdmodel.common.PDRectangle
|
|
import org.apache.pdfbox.pdmodel.font.PDType1Font
|
|
import org.springframework.beans.factory.annotation.Value
|
|
import org.springframework.stereotype.Component
|
|
import java.nio.file.Files
|
|
import java.nio.file.Path
|
|
import java.nio.file.Paths
|
|
import java.time.OffsetDateTime
|
|
import java.util.UUID
|
|
|
|
@Component
|
|
class EmailStorage(
|
|
@Value("\${storage.emails.root:/home/androidlover5842/docs/emails}")
|
|
private val rootPath: String
|
|
) {
|
|
fun storePdf(propertyId: UUID?, messageId: String?, subject: String?, body: String): String {
|
|
val dir = if (propertyId != null) {
|
|
Paths.get(rootPath, propertyId.toString())
|
|
} else {
|
|
Paths.get(rootPath, "unassigned")
|
|
}
|
|
Files.createDirectories(dir)
|
|
val safeName = (messageId ?: UUID.randomUUID().toString()).replace(Regex("[^A-Za-z0-9._-]"), "_")
|
|
val fileName = "${safeName}_${OffsetDateTime.now().toEpochSecond()}.pdf"
|
|
val path = dir.resolve(fileName).normalize()
|
|
val tmp = dir.resolve("${fileName}.tmp").normalize()
|
|
|
|
val document = PDDocument()
|
|
val page = PDPage(PDRectangle.LETTER)
|
|
document.addPage(page)
|
|
val header = "Subject: ${subject ?: ""}\n\n"
|
|
writeText(document, page, header + body)
|
|
document.save(tmp.toFile())
|
|
document.close()
|
|
atomicMove(tmp, path)
|
|
return path.toString()
|
|
}
|
|
|
|
private fun writeText(document: PDDocument, firstPage: PDPage, text: String) {
|
|
var page = firstPage
|
|
var y = 730f
|
|
val marginX = 50f
|
|
val lineHeight = 14f
|
|
val maxLines = 48
|
|
var linesOnPage = 0
|
|
|
|
var content = PDPageContentStream(document, page)
|
|
content.beginText()
|
|
content.setFont(PDType1Font.HELVETICA, 11f)
|
|
content.newLineAtOffset(marginX, y)
|
|
|
|
fun newLine() {
|
|
content.newLineAtOffset(0f, -lineHeight)
|
|
y -= lineHeight
|
|
linesOnPage++
|
|
if (linesOnPage >= maxLines) {
|
|
content.endText()
|
|
content.close()
|
|
page = PDPage(PDRectangle.LETTER)
|
|
document.addPage(page)
|
|
content = PDPageContentStream(document, page)
|
|
content.beginText()
|
|
content.setFont(PDType1Font.HELVETICA, 11f)
|
|
y = 730f
|
|
linesOnPage = 0
|
|
content.newLineAtOffset(marginX, y)
|
|
}
|
|
}
|
|
|
|
val lines = text.split("\n")
|
|
for (line in lines) {
|
|
val chunks = line.chunked(90)
|
|
for (chunk in chunks) {
|
|
content.showText(chunk)
|
|
newLine()
|
|
}
|
|
}
|
|
|
|
content.endText()
|
|
content.close()
|
|
}
|
|
|
|
fun storeEml(propertyId: UUID?, messageId: String?, rawBytes: ByteArray): String {
|
|
val dir = if (propertyId != null) {
|
|
Paths.get(rootPath, propertyId.toString(), "raw")
|
|
} else {
|
|
Paths.get(rootPath, "unassigned", "raw")
|
|
}
|
|
Files.createDirectories(dir)
|
|
val safeName = (messageId ?: UUID.randomUUID().toString()).replace(Regex("[^A-Za-z0-9._-]"), "_")
|
|
val fileName = "${safeName}_${OffsetDateTime.now().toEpochSecond()}.eml"
|
|
val path = dir.resolve(fileName).normalize()
|
|
val tmp = dir.resolve("${fileName}.tmp").normalize()
|
|
Files.write(tmp, rawBytes)
|
|
atomicMove(tmp, path)
|
|
return path.toString()
|
|
}
|
|
|
|
fun storeUploadedPdf(propertyId: UUID, originalName: String?, bytes: ByteArray): String {
|
|
val dir = Paths.get(rootPath, propertyId.toString(), "manual")
|
|
Files.createDirectories(dir)
|
|
val safeName = (originalName ?: UUID.randomUUID().toString()).replace(Regex("[^A-Za-z0-9._-]"), "_")
|
|
val fileName = "${safeName}_${OffsetDateTime.now().toEpochSecond()}.pdf"
|
|
val path = dir.resolve(fileName).normalize()
|
|
val tmp = dir.resolve("${fileName}.tmp").normalize()
|
|
Files.write(tmp, bytes)
|
|
atomicMove(tmp, path)
|
|
return path.toString()
|
|
}
|
|
|
|
private fun atomicMove(tmp: Path, target: Path) {
|
|
try {
|
|
Files.move(tmp, target, java.nio.file.StandardCopyOption.ATOMIC_MOVE, java.nio.file.StandardCopyOption.REPLACE_EXISTING)
|
|
} catch (_: Exception) {
|
|
Files.move(tmp, target, java.nio.file.StandardCopyOption.REPLACE_EXISTING)
|
|
}
|
|
}
|
|
}
|