Amend source form with tags and file-filter

Allow to define tags and a file filter per source.
This commit is contained in:
Eike Kettner
2020-11-12 21:40:53 +01:00
parent 4fd6e02ec0
commit 04ba14f802
18 changed files with 498 additions and 122 deletions

View File

@ -4,44 +4,50 @@ import cats.effect.{Effect, Resource}
import cats.implicits._
import docspell.common.{AccountId, Ident}
import docspell.store.UpdateResult
import docspell.store.records.RSource
import docspell.store.records.SourceData
import docspell.store.{AddResult, Store}
trait OSource[F[_]] {
def findAll(account: AccountId): F[Vector[RSource]]
def findAll(account: AccountId): F[Vector[SourceData]]
def add(s: RSource): F[AddResult]
def add(s: RSource, tags: List[String]): F[AddResult]
def update(s: RSource): F[AddResult]
def update(s: RSource, tags: List[String]): F[AddResult]
def delete(id: Ident, collective: Ident): F[AddResult]
def delete(id: Ident, collective: Ident): F[UpdateResult]
}
object OSource {
def apply[F[_]: Effect](store: Store[F]): Resource[F, OSource[F]] =
Resource.pure[F, OSource[F]](new OSource[F] {
def findAll(account: AccountId): F[Vector[RSource]] =
store.transact(RSource.findAll(account.collective, _.abbrev))
def findAll(account: AccountId): F[Vector[SourceData]] =
store
.transact(SourceData.findAll(account.collective, _.abbrev))
.compile
.to(Vector)
def add(s: RSource): F[AddResult] = {
def insert = RSource.insert(s)
def add(s: RSource, tags: List[String]): F[AddResult] = {
def insert = SourceData.insert(s, tags)
def exists = RSource.existsByAbbrev(s.cid, s.abbrev)
val msg = s"A source with abbrev '${s.abbrev}' already exists"
store.add(insert, exists).map(_.fold(identity, _.withMsg(msg), identity))
}
def update(s: RSource): F[AddResult] = {
def insert = RSource.updateNoCounter(s)
def update(s: RSource, tags: List[String]): F[AddResult] = {
def insert = SourceData.update(s, tags)
def exists = RSource.existsByAbbrev(s.cid, s.abbrev)
val msg = s"A source with abbrev '${s.abbrev}' already exists"
store.add(insert, exists).map(_.fold(identity, _.withMsg(msg), identity))
}
def delete(id: Ident, collective: Ident): F[AddResult] =
store.transact(RSource.delete(id, collective)).attempt.map(AddResult.fromUpdate)
def delete(id: Ident, collective: Ident): F[UpdateResult] =
UpdateResult.fromUpdate(store.transact(SourceData.delete(id, collective)))
})
}

View File

@ -4,6 +4,7 @@ import cats.effect.{Effect, Resource}
import cats.implicits._
import docspell.common.{AccountId, Ident}
import docspell.store.records.RTagSource
import docspell.store.records.{RTag, RTagItem}
import docspell.store.{AddResult, Store}
@ -49,8 +50,9 @@ object OTag {
val io = for {
optTag <- RTag.findByIdAndCollective(id, collective)
n0 <- optTag.traverse(t => RTagItem.deleteTag(t.tagId))
n1 <- optTag.traverse(t => RTag.delete(t.tagId, collective))
} yield n0.getOrElse(0) + n1.getOrElse(0)
n1 <- optTag.traverse(t => RTagSource.deleteTag(t.tagId))
n2 <- optTag.traverse(t => RTag.delete(t.tagId, collective))
} yield (n0 |+| n1 |+| n2).getOrElse(0)
store.transact(io).attempt.map(AddResult.fromUpdate)
}

View File

@ -25,6 +25,11 @@ trait OUpload[F[_]] {
itemId: Option[Ident]
): F[OUpload.UploadResult]
/** Submit files via a given source identifier. The source is looked
* up to identify the collective the files belong to. Metadata
* defined in the source is used as a fallback to those specified
* here (in UploadData).
*/
def submit(
data: OUpload.UploadData[F],
sourceId: Ident,
@ -153,15 +158,19 @@ object OUpload {
itemId: Option[Ident]
): F[OUpload.UploadResult] =
(for {
src <- OptionT(store.transact(RSource.findEnabled(sourceId)))
src <- OptionT(store.transact(SourceData.findEnabled(sourceId)))
updata = data.copy(
meta = data.meta.copy(
sourceAbbrev = src.abbrev,
folderId = data.meta.folderId.orElse(src.folderId)
sourceAbbrev = src.source.abbrev,
folderId = data.meta.folderId.orElse(src.source.folderId),
fileFilter =
if (data.meta.fileFilter == Glob.all) src.source.fileFilterOrAll
else data.meta.fileFilter,
tags = (data.meta.tags ++ src.tags.map(_.tagId.id)).distinct
),
priority = src.priority
priority = src.source.priority
)
accId = AccountId(src.cid, src.sid)
accId = AccountId(src.source.cid, src.source.sid)
result <- OptionT.liftF(submit(updata, accId, notifyJoex, itemId))
} yield result).getOrElse(UploadResult.noSource)