mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-05 22:55:58 +00:00
Check for an existing item before attempting to add files
This commit is contained in:
parent
075b665c68
commit
f519a8effa
@ -1,7 +1,8 @@
|
||||
package docspell.backend.ops
|
||||
|
||||
import bitpeace.MimetypeHint
|
||||
import cats.data.OptionT
|
||||
import cats.Functor
|
||||
import cats.data.{EitherT, OptionT}
|
||||
import cats.effect._
|
||||
import cats.implicits._
|
||||
import docspell.backend.Config
|
||||
@ -10,7 +11,7 @@ import docspell.common._
|
||||
import docspell.common.syntax.all._
|
||||
import docspell.store.Store
|
||||
import docspell.store.queue.JobQueue
|
||||
import docspell.store.records.{RCollective, RJob, RSource}
|
||||
import docspell.store.records._
|
||||
import org.log4s._
|
||||
|
||||
trait OUpload[F[_]] {
|
||||
@ -55,11 +56,32 @@ object OUpload {
|
||||
|
||||
sealed trait UploadResult
|
||||
object UploadResult {
|
||||
|
||||
/** File(s) have been successfully submitted. */
|
||||
case object Success extends UploadResult
|
||||
|
||||
def success: UploadResult = Success
|
||||
|
||||
/** There were no files to submit. */
|
||||
case object NoFiles extends UploadResult
|
||||
|
||||
def noFiles: UploadResult = NoFiles
|
||||
|
||||
/** A source (`RSource') could not be found for a given source-id. */
|
||||
case object NoSource extends UploadResult
|
||||
|
||||
def noSource: UploadResult = NoSource
|
||||
|
||||
/** When adding files to an item, no item was found using the given
|
||||
* item-id. */
|
||||
case object NoItem extends UploadResult
|
||||
|
||||
def noItem: UploadResult = NoItem
|
||||
}
|
||||
|
||||
private def right[F[_]: Functor, A](a: F[A]): EitherT[F, UploadResult, A] =
|
||||
EitherT.right(a)
|
||||
|
||||
def apply[F[_]: Sync](
|
||||
store: Store[F],
|
||||
queue: JobQueue[F],
|
||||
@ -74,10 +96,11 @@ object OUpload {
|
||||
notifyJoex: Boolean,
|
||||
itemId: Option[Ident]
|
||||
): F[OUpload.UploadResult] =
|
||||
for {
|
||||
files <- data.files.traverse(saveFile).map(_.flatten)
|
||||
pred <- checkFileList(files)
|
||||
lang <- store.transact(RCollective.findLanguage(account.collective))
|
||||
(for {
|
||||
_ <- checkExistingItem(itemId, account.collective)
|
||||
files <- right(data.files.traverse(saveFile).map(_.flatten))
|
||||
_ <- checkFileList(files)
|
||||
lang <- right(store.transact(RCollective.findLanguage(account.collective)))
|
||||
meta = ProcessItemArgs.ProcessMeta(
|
||||
account.collective,
|
||||
itemId,
|
||||
@ -89,13 +112,15 @@ object OUpload {
|
||||
args =
|
||||
if (data.multiple) files.map(f => ProcessItemArgs(meta, List(f)))
|
||||
else Vector(ProcessItemArgs(meta, files.toList))
|
||||
job <- pred.traverse(_ => makeJobs(args, account, data.priority, data.tracker))
|
||||
_ <- logger.fdebug(s"Storing jobs: $job")
|
||||
res <- job.traverse(submitJobs(notifyJoex))
|
||||
_ <- store.transact(
|
||||
jobs <- right(makeJobs(args, account, data.priority, data.tracker))
|
||||
_ <- right(logger.fdebug(s"Storing jobs: $jobs"))
|
||||
res <- right(submitJobs(notifyJoex)(jobs))
|
||||
_ <- right(
|
||||
store.transact(
|
||||
RSource.incrementCounter(data.meta.sourceAbbrev, account.collective)
|
||||
)
|
||||
} yield res.fold(identity, identity)
|
||||
)
|
||||
} yield res).fold(identity, identity)
|
||||
|
||||
def submit(
|
||||
data: OUpload.UploadData[F],
|
||||
@ -111,7 +136,7 @@ object OUpload {
|
||||
)
|
||||
accId = AccountId(src.cid, src.sid)
|
||||
result <- OptionT.liftF(submit(updata, accId, notifyJoex, itemId))
|
||||
} yield result).getOrElse(UploadResult.NoSource)
|
||||
} yield result).getOrElse(UploadResult.noSource)
|
||||
|
||||
private def submitJobs(
|
||||
notifyJoex: Boolean
|
||||
@ -122,6 +147,7 @@ object OUpload {
|
||||
_ <- if (notifyJoex) joex.notifyAllNodes else ().pure[F]
|
||||
} yield UploadResult.Success
|
||||
|
||||
/** Saves the file into the database. */
|
||||
private def saveFile(file: File[F]): F[Option[ProcessItemArgs.File]] =
|
||||
logger.finfo(s"Receiving file $file") *>
|
||||
store.bitpeace
|
||||
@ -140,10 +166,24 @@ object OUpload {
|
||||
)
|
||||
)
|
||||
|
||||
private def checkExistingItem(
|
||||
itemId: Option[Ident],
|
||||
coll: Ident
|
||||
): EitherT[F, UploadResult, Unit] =
|
||||
itemId match {
|
||||
case None =>
|
||||
right(().pure[F])
|
||||
case Some(id) =>
|
||||
OptionT(store.transact(RItem.findByIdAndCollective(id, coll)))
|
||||
.toRight(UploadResult.noItem)
|
||||
.map(_ => ())
|
||||
}
|
||||
|
||||
private def checkFileList(
|
||||
files: Seq[ProcessItemArgs.File]
|
||||
): F[Either[UploadResult, Unit]] =
|
||||
Sync[F].pure(if (files.isEmpty) Left(UploadResult.NoFiles) else Right(()))
|
||||
): EitherT[F, UploadResult, Unit] =
|
||||
if (files.isEmpty) EitherT.left(UploadResult.noFiles.pure[F])
|
||||
else right(().pure[F])
|
||||
|
||||
private def makeJobs(
|
||||
args: Vector[ProcessItemArgs],
|
||||
|
@ -470,6 +470,7 @@ trait Conversions {
|
||||
case UploadResult.Success => BasicResult(true, "Files submitted.")
|
||||
case UploadResult.NoFiles => BasicResult(false, "There were no files to submit.")
|
||||
case UploadResult.NoSource => BasicResult(false, "The source id is not valid.")
|
||||
case UploadResult.NoItem => BasicResult(false, "The item could not be found.")
|
||||
}
|
||||
|
||||
def basicResult(cr: PassChangeResult): BasicResult =
|
||||
|
Loading…
x
Reference in New Issue
Block a user