mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-03-28 17:55:06 +00:00
First sketch for custom data threaded through item processing
Refs: #2334
This commit is contained in:
parent
fe72fbee8a
commit
83ad2c5044
modules
addonlib/src/main/scala/docspell/addons/out
backend/src/main/scala/docspell/backend/ops
common/src/main/scala/docspell/common
joex/src/main/scala/docspell/joex
addon
process
scanmailbox
restapi/src/main/resources
restserver/src/main/scala/docspell/restserver/conv
store/src/main/scala/db/migration/common
@ -15,10 +15,10 @@ import docspell.common.ProcessItemArgs.ProcessMeta
|
||||
import docspell.common.{CollectiveId, Ident, Language}
|
||||
import docspell.logging.Logger
|
||||
|
||||
import io.circe.Codec
|
||||
import io.circe.generic.extras.Configuration
|
||||
import io.circe.generic.extras.semiauto.deriveConfiguredCodec
|
||||
import io.circe.generic.semiauto.deriveCodec
|
||||
import io.circe.{Codec, Json}
|
||||
|
||||
case class NewFile(metadata: Meta = Meta.empty, file: String) {
|
||||
|
||||
@ -41,7 +41,8 @@ object NewFile {
|
||||
case class Meta(
|
||||
language: Option[Language],
|
||||
skipDuplicate: Option[Boolean],
|
||||
attachmentsOnly: Option[Boolean]
|
||||
attachmentsOnly: Option[Boolean],
|
||||
customData: Option[Json]
|
||||
) {
|
||||
|
||||
def toProcessMeta(
|
||||
@ -62,12 +63,13 @@ object NewFile {
|
||||
fileFilter = None,
|
||||
tags = None,
|
||||
reprocess = false,
|
||||
attachmentsOnly = attachmentsOnly
|
||||
attachmentsOnly = attachmentsOnly,
|
||||
customData = customData
|
||||
)
|
||||
}
|
||||
|
||||
object Meta {
|
||||
val empty = Meta(None, None, None)
|
||||
val empty = Meta(None, None, None, None)
|
||||
implicit val jsonCodec: Codec[Meta] = deriveCodec
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ import docspell.common._
|
||||
import docspell.logging.Logger
|
||||
|
||||
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
|
||||
import io.circe.{Decoder, Encoder}
|
||||
import io.circe.{Decoder, Encoder, Json}
|
||||
|
||||
case class NewItem(metadata: Option[Meta], files: List[String]) {
|
||||
|
||||
@ -25,7 +25,7 @@ case class NewItem(metadata: Option[Meta], files: List[String]) {
|
||||
sourceAbbrev: String
|
||||
): ProcessItemArgs.ProcessMeta =
|
||||
metadata
|
||||
.getOrElse(Meta(None, None, None, None, None, None, None))
|
||||
.getOrElse(Meta.empty)
|
||||
.toProcessArgs(cid, collLang, sourceAbbrev)
|
||||
|
||||
def resolveFiles[F[_]: Files: Monad](
|
||||
@ -58,7 +58,8 @@ object NewItem {
|
||||
source: Option[String],
|
||||
skipDuplicate: Option[Boolean],
|
||||
tags: Option[List[String]],
|
||||
attachmentsOnly: Option[Boolean]
|
||||
attachmentsOnly: Option[Boolean],
|
||||
customData: Option[Json]
|
||||
) {
|
||||
|
||||
def toProcessArgs(
|
||||
@ -78,11 +79,14 @@ object NewItem {
|
||||
fileFilter = None,
|
||||
tags = tags,
|
||||
reprocess = false,
|
||||
attachmentsOnly = attachmentsOnly
|
||||
attachmentsOnly = attachmentsOnly,
|
||||
customData = customData
|
||||
)
|
||||
}
|
||||
|
||||
object Meta {
|
||||
val empty: Meta = Meta(None, None, None, None, None, None, None, None)
|
||||
|
||||
implicit val jsonEncoder: Encoder[Meta] = deriveEncoder
|
||||
implicit val jsonDecoder: Decoder[Meta] = deriveDecoder
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ import docspell.scheduler.{Job, JobStore}
|
||||
import docspell.store.Store
|
||||
import docspell.store.records._
|
||||
|
||||
import io.circe.Json
|
||||
|
||||
trait OUpload[F[_]] {
|
||||
|
||||
def submit(
|
||||
@ -69,7 +71,8 @@ object OUpload {
|
||||
tags: List[String],
|
||||
language: Option[Language],
|
||||
attachmentsOnly: Option[Boolean],
|
||||
flattenArchives: Option[Boolean]
|
||||
flattenArchives: Option[Boolean],
|
||||
customData: Option[Json]
|
||||
)
|
||||
|
||||
case class UploadData[F[_]](
|
||||
@ -157,7 +160,8 @@ object OUpload {
|
||||
data.meta.fileFilter.some,
|
||||
data.meta.tags.some,
|
||||
false,
|
||||
data.meta.attachmentsOnly
|
||||
data.meta.attachmentsOnly,
|
||||
data.meta.customData
|
||||
)
|
||||
args = ProcessItemArgs(meta, files.toList)
|
||||
jobs <- right(
|
||||
|
@ -54,7 +54,8 @@ object ProcessItemArgs {
|
||||
fileFilter: Option[Glob],
|
||||
tags: Option[List[String]],
|
||||
reprocess: Boolean,
|
||||
attachmentsOnly: Option[Boolean]
|
||||
attachmentsOnly: Option[Boolean],
|
||||
customData: Option[Json]
|
||||
)
|
||||
|
||||
object ProcessMeta {
|
||||
|
@ -75,6 +75,7 @@ object ItemAddonTask extends AddonTaskExtension {
|
||||
givenMeta = proposals,
|
||||
tags = tags.map(_.name).toList,
|
||||
classifyProposals = MetaProposalList.empty,
|
||||
classifyTags = Nil
|
||||
classifyTags = Nil,
|
||||
customData = None // can't retain this information from a final item. TODO
|
||||
)
|
||||
}
|
||||
|
@ -112,7 +112,8 @@ object CreateItem {
|
||||
MetaProposalList.empty,
|
||||
Nil,
|
||||
MetaProposalList.empty,
|
||||
Nil
|
||||
Nil,
|
||||
ctx.args.meta.customData
|
||||
)
|
||||
}
|
||||
|
||||
@ -175,7 +176,8 @@ object CreateItem {
|
||||
MetaProposalList.empty,
|
||||
Nil,
|
||||
MetaProposalList.empty,
|
||||
Nil
|
||||
Nil,
|
||||
ctx.args.meta.customData
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -46,7 +46,8 @@ case class ItemData(
|
||||
tags: List[String],
|
||||
// proposals obtained from the classifier
|
||||
classifyProposals: MetaProposalList,
|
||||
classifyTags: List[String]
|
||||
classifyTags: List[String],
|
||||
customData: Option[Json]
|
||||
) {
|
||||
|
||||
/** sort by weight; order of equal weights is not important, just choose one others are
|
||||
@ -121,6 +122,7 @@ object ItemData {
|
||||
)
|
||||
)
|
||||
.asJson,
|
||||
"customData" -> data.customData.asJson,
|
||||
"tags" -> data.tags.asJson,
|
||||
"assumedTags" -> data.classifyTags.asJson,
|
||||
"assumedCorrOrg" -> data.finalProposals
|
||||
|
@ -101,7 +101,8 @@ object ReProcessItem {
|
||||
MetaProposalList.empty,
|
||||
Nil,
|
||||
MetaProposalList.empty,
|
||||
Nil
|
||||
Nil,
|
||||
None // cannot retain customData from an already existing item
|
||||
)).getOrElseF(
|
||||
Sync[F].raiseError(new Exception(s"Item not found: ${ctx.args.itemId.id}"))
|
||||
)
|
||||
@ -134,7 +135,8 @@ object ReProcessItem {
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
None // attachOnly (not used when reprocessing attachments)
|
||||
None, // attachOnly (not used when reprocessing attachments)
|
||||
None // cannot retain customData from an already existing item
|
||||
),
|
||||
Nil
|
||||
).pure[F]
|
||||
|
@ -328,6 +328,7 @@ object ScanMailboxTask {
|
||||
args.tags.getOrElse(Nil),
|
||||
args.language,
|
||||
args.attachmentsOnly,
|
||||
None,
|
||||
None
|
||||
)
|
||||
data = OUpload.UploadData(
|
||||
|
@ -8250,6 +8250,14 @@ components:
|
||||
attachments of the e-mail are imported and the e-mail body
|
||||
is discarded. E-mails that don't have any attachments are
|
||||
skipped.
|
||||
customData:
|
||||
type: string
|
||||
format: json
|
||||
default: null
|
||||
description: |
|
||||
Custom user data that gets threaded through the processing. Docspell
|
||||
ignores it completely, but will pass it to the outcome of processing
|
||||
to be able to react on it in addons or other ways.
|
||||
|
||||
Collective:
|
||||
description: |
|
||||
|
@ -32,6 +32,7 @@ import docspell.store.queries.{
|
||||
import docspell.store.records._
|
||||
import docspell.store.{AddResult, UpdateResult}
|
||||
|
||||
import io.circe.Json
|
||||
import org.http4s.headers.`Content-Type`
|
||||
import org.http4s.multipart.Multipart
|
||||
import org.log4s.Logger
|
||||
@ -315,7 +316,8 @@ trait Conversions {
|
||||
m.tags.map(_.items).getOrElse(Nil),
|
||||
m.language,
|
||||
m.attachmentsOnly,
|
||||
m.flattenArchives
|
||||
m.flattenArchives,
|
||||
m.customData.map(Json.fromString) // TODO fix openapi spec
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -333,6 +335,7 @@ trait Conversions {
|
||||
Nil,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None
|
||||
)
|
||||
)
|
||||
|
@ -348,7 +348,8 @@ object MigrateCollectiveIdTaskArgs extends TransactorSupport {
|
||||
fileFilter = oldArgs.meta.fileFilter,
|
||||
tags = oldArgs.meta.tags,
|
||||
reprocess = oldArgs.meta.reprocess,
|
||||
attachmentsOnly = oldArgs.meta.attachmentsOnly
|
||||
attachmentsOnly = oldArgs.meta.attachmentsOnly,
|
||||
customData = None
|
||||
),
|
||||
oldArgs.files.map(f =>
|
||||
ProcessItemArgs
|
||||
|
Loading…
x
Reference in New Issue
Block a user