mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-21 18:08:25 +00:00
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:
@ -204,7 +204,8 @@ object Event {
|
||||
state: JobState,
|
||||
subject: String,
|
||||
submitter: Ident,
|
||||
result: Json
|
||||
resultData: Json,
|
||||
resultMsg: Option[String]
|
||||
) extends Event {
|
||||
val eventType = JobDone
|
||||
val baseUrl = None
|
||||
@ -222,7 +223,8 @@ object Event {
|
||||
JobState.running,
|
||||
"Process 3 files",
|
||||
account.user,
|
||||
Json.Null
|
||||
Json.Null,
|
||||
None
|
||||
)
|
||||
} yield ev
|
||||
}
|
||||
|
@ -31,30 +31,25 @@ trait EventContext {
|
||||
"content" -> content
|
||||
)
|
||||
|
||||
def defaultTitle: Either[String, String]
|
||||
def defaultTitleHtml: Either[String, String]
|
||||
|
||||
def defaultBody: Either[String, String]
|
||||
def defaultBodyHtml: Either[String, String]
|
||||
def defaultMessage: Either[String, EventMessage]
|
||||
def defaultMessageHtml: Either[String, EventMessage]
|
||||
|
||||
def defaultBoth: Either[String, String]
|
||||
def defaultBothHtml: Either[String, String]
|
||||
|
||||
lazy val asJsonWithMessage: Either[String, Json] =
|
||||
for {
|
||||
tt1 <- defaultTitle
|
||||
tb1 <- defaultBody
|
||||
tt2 <- defaultTitleHtml
|
||||
tb2 <- defaultBodyHtml
|
||||
dm1 <- defaultMessage
|
||||
dm2 <- defaultMessageHtml
|
||||
data = asJson
|
||||
msg = Json.obj(
|
||||
"message" -> Json.obj(
|
||||
"title" -> tt1.asJson,
|
||||
"body" -> tb1.asJson
|
||||
"title" -> dm1.title.asJson,
|
||||
"body" -> dm1.body.asJson
|
||||
),
|
||||
"messageHtml" -> Json.obj(
|
||||
"title" -> tt2.asJson,
|
||||
"body" -> tb2.asJson
|
||||
"title" -> dm2.title.asJson,
|
||||
"body" -> dm2.body.asJson
|
||||
)
|
||||
)
|
||||
} yield data.withObject(o1 => msg.withObject(o2 => o1.deepMerge(o2).asJson))
|
||||
@ -65,10 +60,8 @@ object EventContext {
|
||||
new EventContext {
|
||||
val event = ev
|
||||
def content = Json.obj()
|
||||
def defaultTitle = Right("")
|
||||
def defaultTitleHtml = Right("")
|
||||
def defaultBody = Right("")
|
||||
def defaultBodyHtml = Right("")
|
||||
def defaultMessage = Right(EventMessage.empty)
|
||||
def defaultMessageHtml = Right(EventMessage.empty)
|
||||
def defaultBoth = Right("")
|
||||
def defaultBothHtml = Right("")
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2020 Eike K. & Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package docspell.notification.api
|
||||
|
||||
final case class EventMessage(title: String, body: String)
|
||||
|
||||
object EventMessage {
|
||||
val empty: EventMessage = EventMessage("", "")
|
||||
}
|
@ -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 {
|
||||
|
@ -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] =
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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)."
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user