Adds files to document display.

This commit is contained in:
Stefan Schallerl 2025-02-03 16:38:53 +01:00
parent 68cbb94977
commit afa2ffb481
3 changed files with 166 additions and 33 deletions

View file

@ -3,6 +3,7 @@ package net.h34t.filemure.repository
import net.h34t.filemure.ExtId import net.h34t.filemure.ExtId
import net.h34t.filemure.LimboFile import net.h34t.filemure.LimboFile
import net.h34t.filemure.core.entity.Document import net.h34t.filemure.core.entity.Document
import net.h34t.filemure.core.entity.FileRef
import net.h34t.filemure.core.entity.Tag import net.h34t.filemure.core.entity.Tag
import java.io.InputStream import java.io.InputStream
import java.sql.Connection import java.sql.Connection
@ -129,7 +130,9 @@ class SqliteRepository(url: String) {
extId = res.getString(3), extId = res.getString(3),
title = res.getString(4), title = res.getString(4),
description = res.getString(5), description = res.getString(5),
tags = res.getString(6).split(",").map { Tag(it) }, tags = res.getString(6)
?.let { if (it.isNotBlank()) it.split(",").map { tag -> Tag(tag) } else emptyList() }
?: emptyList(),
created = LocalDateTime.parse(res.getString(7), dtf), created = LocalDateTime.parse(res.getString(7), dtf),
referenceDate = LocalDateTime.parse(res.getString(8), dtf), referenceDate = LocalDateTime.parse(res.getString(8), dtf),
files = emptyList() files = emptyList()
@ -143,12 +146,42 @@ class SqliteRepository(url: String) {
} }
fun getDocumentById(accountId: Long, id: Long): Document { fun getDocumentById(accountId: Long, id: Long): Document {
return connection.prepareStatement("""SELECT d.id, d.account_id, d.ext_id, d.title, d.description, d.tags, d.created, d.reference_date FROM document d WHERE id=? AND account_id=?""") return connection.prepareStatement(
"""
SELECT
d.id,
d.account_id,
d.ext_id,
d.title,
d.description,
d.tags,
d.created,
d.reference_date,
f.id,
f.ext_id,
f.filename,
f.content_type,
f.content_extracted,
f.file_size
f.created
FROM
document d LEFT OUTER JOIN file f ON (d.id = f.document_id)
WHERE
id=? AND
account_id=?
""".trimIndent()
)
.use { stmt -> .use { stmt ->
stmt.setLong(1, id) stmt.setLong(1, id)
stmt.setLong(2, accountId) stmt.setLong(2, accountId)
val res = stmt.executeQuery() val res = stmt.executeQuery()
Document(
var document: Document? = null
val files = mutableListOf<FileRef>()
while (res.next()) {
if (document == null) {
document = Document(
id = res.getLong(1), id = res.getLong(1),
extId = res.getString(3), extId = res.getString(3),
title = res.getString(4), title = res.getString(4),
@ -156,29 +189,96 @@ class SqliteRepository(url: String) {
tags = res.getString(6).split(",").map { Tag(it) }, tags = res.getString(6).split(",").map { Tag(it) },
created = LocalDateTime.parse(res.getString(7), dtf), created = LocalDateTime.parse(res.getString(7), dtf),
referenceDate = LocalDateTime.parse(res.getString(8), dtf), referenceDate = LocalDateTime.parse(res.getString(8), dtf),
// TODO load files
files = emptyList() files = emptyList()
) )
val id = res.getLong(9)
if (!res.wasNull()) {
files.add(
FileRef(
id = id,
extId = res.getString(10),
filename = res.getString(11),
contentType = res.getString(12),
contentExtracted = res.getString(13),
fileSize = res.getLong(14),
created = LocalDateTime.parse(res.getString(15), dtf)
)
)
}
}
}
document?.copy(files = files) ?: throw IllegalStateException("Document is null")
} }
} }
fun getDocumentByExtId(accountId: Long, extId: String): Document { fun getDocumentByExtId(accountId: Long, extId: String): Document {
return connection.prepareStatement("""SELECT d.id, d.account_id, d.ext_id, d.title, d.description, d.tags, d.created, d.reference_date FROM document d WHERE ext_id=? AND account_id=?""") return connection.prepareStatement(
"""
SELECT
d.id,
d.account_id,
d.ext_id,
d.title,
d.description,
d.tags,
d.created,
d.reference_date,
f.id,
f.ext_id,
f.filename,
f.content_type,
f.content_extracted,
f.file_size,
f.created
FROM
document d LEFT OUTER JOIN file f ON (d.id = f.document_id)
WHERE
d.ext_id=? AND
d.account_id=?
""".trimIndent()
)
.use { stmt -> .use { stmt ->
stmt.setString(1, extId) stmt.setString(1, extId)
stmt.setLong(2, accountId) stmt.setLong(2, accountId)
val res = stmt.executeQuery() val res = stmt.executeQuery()
Document( var document: Document? = null
val files = mutableListOf<FileRef>()
while (res.next()) {
if (document == null) {
document = Document(
id = res.getLong(1), id = res.getLong(1),
extId = res.getString(3), extId = res.getString(3),
title = res.getString(4), title = res.getString(4),
description = res.getString(5), description = res.getString(5),
tags = res.getString(6).split(",").map { Tag(it) }, tags = Tag.parse(res.getString(6)),
created = LocalDateTime.parse(res.getString(7), dtf), created = LocalDateTime.parse(res.getString(7), dtf),
referenceDate = LocalDateTime.parse(res.getString(8), dtf), referenceDate = LocalDateTime.parse(res.getString(8), dtf),
// TODO load files
files = emptyList() files = emptyList()
) )
val fid: Long = res.getLong(9)
if (!res.wasNull()) {
files.add(
FileRef(
id = fid,
extId = res.getString(10),
filename = res.getString(11),
contentType = res.getString(12),
contentExtracted = res.getString(13),
fileSize = res.getLong(14),
created = LocalDateTime.parse(res.getString(15), dtf)
)
)
}
}
}
requireNotNull(document)
document.copy(files = files)
} }
} }
} }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{*$title}</title> <title>{*$title} :: Filemure</title>
<link rel="stylesheet" type="text/css" href="/filemure.css"> <link rel="stylesheet" type="text/css" href="/filemure.css">
<script src="/filemure.js"></script> <script src="/filemure.js"></script>
</head> </head>

View file

@ -2,7 +2,7 @@ package net.h34t.filemure.core.entity
import java.time.LocalDateTime import java.time.LocalDateTime
class Document( data class Document(
val id: Long, val id: Long,
val extId: String, val extId: String,
val title: String, val title: String,
@ -14,13 +14,18 @@ class Document(
) )
@JvmInline @JvmInline
value class Tag(val value: String) value class Tag(val value: String) {
@JvmInline
value class MimeType(val value: String) {
init { init {
// TODO validate mime type // TODO proper validation
// require(value) require(value.isNotBlank())
}
companion object {
fun parse(ser: String?): List<Tag> {
return ser?.let { if (it.isNotBlank()) it.split(",").map { Tag(it) } else emptyList() } ?: emptyList()
}
fun List<Tag>.serialize() = if (this.isEmpty()) "" else this.joinToString(",") { it.value }
} }
} }
@ -29,6 +34,34 @@ data class FileRef(
val extId: String, val extId: String,
val filename: String, val filename: String,
val contentType: String?, val contentType: String?,
val contentExtracted: String?,
val fileSize: Long,
val created: LocalDateTime, val created: LocalDateTime,
) )
data class FileContent(
val id: Long,
val extId: String,
val content: ByteArray,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as FileContent
if (id != other.id) return false
if (extId != other.extId) return false
if (!content.contentEquals(other.content)) return false
return true
}
override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + extId.hashCode()
result = 31 * result + content.contentHashCode()
return result
}
}