mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-22 02:18:26 +00:00
Add support for more generic notification
This is a start to have different kinds of notifications. It is possible to be notified via e-mail, matrix or gotify. It also extends the current "periodic query" for due items by allowing notification over different channels. A "generic periodic query" variant is added as well.
This commit is contained in:
@ -6,6 +6,8 @@
|
||||
|
||||
package docspell.common
|
||||
|
||||
import io.circe.{Decoder, Encoder}
|
||||
|
||||
final case class ItemQueryString(query: String) {
|
||||
def isEmpty: Boolean =
|
||||
query.isEmpty
|
||||
@ -15,4 +17,9 @@ object ItemQueryString {
|
||||
|
||||
def apply(qs: Option[String]): ItemQueryString =
|
||||
ItemQueryString(qs.getOrElse(""))
|
||||
|
||||
implicit val jsonEncoder: Encoder[ItemQueryString] =
|
||||
Encoder.encodeString.contramap(_.query)
|
||||
implicit val jsonDecoder: Decoder[ItemQueryString] =
|
||||
Decoder.decodeString.map(ItemQueryString.apply)
|
||||
}
|
||||
|
@ -103,6 +103,8 @@ case class LenientUri(
|
||||
val fragPart = fragment.map(f => s"#$f").getOrElse("")
|
||||
s"$schemePart:$authPart$pathPart$queryPart$fragPart"
|
||||
}
|
||||
override def toString(): String =
|
||||
asString
|
||||
}
|
||||
|
||||
object LenientUri {
|
||||
|
@ -6,8 +6,11 @@
|
||||
|
||||
package docspell.common
|
||||
|
||||
import java.io.{PrintWriter, StringWriter}
|
||||
|
||||
import cats.Applicative
|
||||
import cats.effect.Sync
|
||||
import cats.effect.{Ref, Sync}
|
||||
import cats.implicits._
|
||||
import fs2.Stream
|
||||
|
||||
import docspell.common.syntax.all._
|
||||
@ -42,6 +45,28 @@ trait Logger[F[_]] { self =>
|
||||
def error(ex: Throwable)(msg: => String): Stream[F, Unit] =
|
||||
Stream.eval(self.error(ex)(msg))
|
||||
}
|
||||
def andThen(other: Logger[F])(implicit F: Sync[F]): Logger[F] = {
|
||||
val self = this
|
||||
new Logger[F] {
|
||||
def trace(msg: => String) =
|
||||
self.trace(msg) >> other.trace(msg)
|
||||
|
||||
override def debug(msg: => String) =
|
||||
self.debug(msg) >> other.debug(msg)
|
||||
|
||||
override def info(msg: => String) =
|
||||
self.info(msg) >> other.info(msg)
|
||||
|
||||
override def warn(msg: => String) =
|
||||
self.warn(msg) >> other.warn(msg)
|
||||
|
||||
override def error(ex: Throwable)(msg: => String) =
|
||||
self.error(ex)(msg) >> other.error(ex)(msg)
|
||||
|
||||
override def error(msg: => String) =
|
||||
self.error(msg) >> other.error(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Logger {
|
||||
@ -88,4 +113,31 @@ object Logger {
|
||||
log.ferror(msg)
|
||||
}
|
||||
|
||||
def buffer[F[_]: Sync](): F[(Ref[F, Vector[String]], Logger[F])] =
|
||||
for {
|
||||
buffer <- Ref.of[F, Vector[String]](Vector.empty[String])
|
||||
logger = new Logger[F] {
|
||||
def trace(msg: => String) =
|
||||
buffer.update(_.appended(s"TRACE $msg"))
|
||||
|
||||
def debug(msg: => String) =
|
||||
buffer.update(_.appended(s"DEBUG $msg"))
|
||||
|
||||
def info(msg: => String) =
|
||||
buffer.update(_.appended(s"INFO $msg"))
|
||||
|
||||
def warn(msg: => String) =
|
||||
buffer.update(_.appended(s"WARN $msg"))
|
||||
|
||||
def error(ex: Throwable)(msg: => String) = {
|
||||
val ps = new StringWriter()
|
||||
ex.printStackTrace(new PrintWriter(ps))
|
||||
buffer.update(_.appended(s"ERROR $msg:\n$ps"))
|
||||
}
|
||||
|
||||
def error(msg: => String) =
|
||||
buffer.update(_.appended(s"ERROR $msg"))
|
||||
}
|
||||
} yield (buffer, logger)
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ case class NotifyDueItemsArgs(
|
||||
daysBack: Option[Int],
|
||||
tagsInclude: List[Ident],
|
||||
tagsExclude: List[Ident]
|
||||
) {}
|
||||
)
|
||||
|
||||
object NotifyDueItemsArgs {
|
||||
|
||||
|
Reference in New Issue
Block a user