Provide tasks with ability to return data and human message

To allow better communication from background tasks, tasks can return
not only data (json), but also a human readable message which is send
via notification channels
This commit is contained in:
eikek
2022-03-11 22:56:14 +01:00
parent c1ce0769eb
commit 290b4ca58b
16 changed files with 250 additions and 76 deletions

View File

@ -6,7 +6,7 @@
package docspell.notification.impl
import docspell.notification.api.EventContext
import docspell.notification.api.{EventContext, EventMessage}
import yamusca.circe._
import yamusca.implicits._
@ -24,17 +24,17 @@ abstract class AbstractEventContext extends EventContext {
def renderHtml(template: Template): String =
Markdown.toHtml(render(template))
lazy val defaultTitle: Either[String, String] =
titleTemplate.map(render)
lazy val defaultMessage: Either[String, EventMessage] =
for {
title <- titleTemplate.map(render)
body <- bodyTemplate.map(render)
} yield EventMessage(title, body)
lazy val defaultTitleHtml: Either[String, String] =
titleTemplate.map(renderHtml)
lazy val defaultBody: Either[String, String] =
bodyTemplate.map(render)
lazy val defaultBodyHtml: Either[String, String] =
bodyTemplate.map(renderHtml)
lazy val defaultMessageHtml: Either[String, EventMessage] =
for {
title <- titleTemplate.map(renderHtml)
body <- bodyTemplate.map(renderHtml)
} yield EventMessage(title, body)
lazy val defaultBoth: Either[String, String] =
for {

View File

@ -18,8 +18,9 @@ trait EventContextSyntax {
implicit final class EventContextOps(self: EventContext) {
def withDefault[F[_]](logger: Logger[F])(f: (String, String) => F[Unit]): F[Unit] =
(for {
tt <- self.defaultTitle
tb <- self.defaultBody
dm <- self.defaultMessage
tt = dm.title
tb = dm.body
} yield f(tt, tb)).fold(logError(logger), identity)
def withJsonMessage[F[_]](logger: Logger[F])(f: Json => F[Unit]): F[Unit] =

View File

@ -23,9 +23,14 @@ final case class JobDoneCtx(event: Event.JobDone, data: JobDoneCtx.Data)
val content = data.asJson
val titleTemplate = Right(mustache"{{eventType}} (by *{{account.user}}*)")
val bodyTemplate = Right(
mustache"""{{#content}}_'{{subject}}'_ finished {{/content}}"""
)
val bodyTemplate =
data.resultMsg match {
case None =>
Right(mustache"""{{#content}}_'{{subject}}'_ finished {{/content}}""")
case Some(msg) =>
val tpl = s"""{{#content}}$msg{{/content}}"""
yamusca.imports.mustache.parse(tpl).left.map(_._2)
}
}
object JobDoneCtx {
@ -46,7 +51,8 @@ object JobDoneCtx {
state: JobState,
subject: String,
submitter: Ident,
result: Json
resultData: Json,
resultMsg: Option[String]
)
object Data {
implicit val jsonEncoder: Encoder[Data] =
@ -61,7 +67,8 @@ object JobDoneCtx {
ev.state,
ev.subject,
ev.submitter,
ev.result
ev.resultData,
ev.resultMsg
)
}
}

View File

@ -46,9 +46,10 @@ class TagsChangedCtxTest extends FunSuite {
TagsChangedCtx.Data(account, List(item), List(tag), Nil, url.some.map(_.asString))
)
assertEquals(ctx.defaultTitle.toOption.get, "TagsChanged (by *user2*)")
val dm = ctx.defaultMessage.toOption.get
assertEquals(dm.title, "TagsChanged (by *user2*)")
assertEquals(
ctx.defaultBody.toOption.get,
dm.body,
"Adding *tag-red* on [`Report 2`](http://test/item-1)."
)
}
@ -65,9 +66,10 @@ class TagsChangedCtxTest extends FunSuite {
)
)
assertEquals(ctx.defaultTitle.toOption.get, "TagsChanged (by *user2*)")
val dm = ctx.defaultMessage.toOption.get
assertEquals(dm.title, "TagsChanged (by *user2*)")
assertEquals(
ctx.defaultBody.toOption.get,
dm.body,
"Adding *tag-red*; Removing *tag-blue* on [`Report 2`](http://test/item-1)."
)
}