Merge pull request #1279 from eikek/gotify-priority

Add priority to gotify channel
This commit is contained in:
mergify[bot]
2022-01-12 20:17:11 +00:00
committed by GitHub
15 changed files with 118 additions and 38 deletions

View File

@ -255,7 +255,7 @@ object ONotification {
r.fold( r.fold(
mail => mail =>
Channel.Mail(mail.id, mail.connection, Nel.fromListUnsafe(mail.recipients)), Channel.Mail(mail.id, mail.connection, Nel.fromListUnsafe(mail.recipients)),
gotify => Channel.Gotify(r.id, gotify.url, gotify.appKey), gotify => Channel.Gotify(r.id, gotify.url, gotify.appKey, gotify.priority),
matrix => matrix =>
Channel.Matrix(r.id, matrix.homeServer, matrix.roomId, matrix.accessToken), Channel.Matrix(r.id, matrix.homeServer, matrix.roomId, matrix.accessToken),
http => Channel.Http(r.id, http.url) http => Channel.Http(r.id, http.url)
@ -296,9 +296,9 @@ object ONotification {
time time
).vary ).vary
} yield rec } yield rec
case Channel.Gotify(_, url, appKey) => case Channel.Gotify(_, url, appKey, prio) =>
OptionT.pure[F]( OptionT.pure[F](
RNotificationChannelGotify(id, userId, url, appKey, time).vary RNotificationChannelGotify(id, userId, url, appKey, prio, time).vary
) )
case Channel.Matrix(_, homeServer, roomId, accessToken) => case Channel.Matrix(_, homeServer, roomId, accessToken) =>
OptionT.pure[F]( OptionT.pure[F](

View File

@ -53,7 +53,12 @@ object Channel {
deriveConfiguredEncoder[Mail] deriveConfiguredEncoder[Mail]
} }
final case class Gotify(id: Ident, url: LenientUri, appKey: Password) extends Channel { final case class Gotify(
id: Ident,
url: LenientUri,
appKey: Password,
priority: Option[Int]
) extends Channel {
val channelType = ChannelType.Gotify val channelType = ChannelType.Gotify
def fold[A]( def fold[A](
f1: Mail => A, f1: Mail => A,

View File

@ -30,7 +30,8 @@ object NotificationChannel {
headers: Map[String, String] headers: Map[String, String]
) extends NotificationChannel ) extends NotificationChannel
final case class Gotify(url: LenientUri, appKey: Password) extends NotificationChannel final case class Gotify(url: LenientUri, appKey: Password, priority: Option[Int])
extends NotificationChannel
final case class Matrix( final case class Matrix(
homeServer: LenientUri, homeServer: LenientUri,

View File

@ -35,6 +35,7 @@ final class GotifyBackend[F[_]: Async](
val req = POST( val req = POST(
Json.obj( Json.obj(
"title" -> Json.fromString(title), "title" -> Json.fromString(title),
"priority" -> Json.fromInt(channel.priority.getOrElse(0)),
"message" -> Json.fromString(body), "message" -> Json.fromString(body),
"extras" -> Json.obj( "extras" -> Json.obj(
"client::display" -> Json.obj( "client::display" -> Json.obj(

View File

@ -5523,6 +5523,11 @@ components:
appKey: appKey:
type: string type: string
format: password format: password
priority:
type: integer
format: int32
description: |
A priority number [0-10]
NotificationHttp: NotificationHttp:
description: | description: |
A notification channel for receiving a generic http request. A notification channel for receiving a generic http request.

View File

@ -74,7 +74,8 @@ object NotificationChannel {
.flatMap(_.toRight("No recipients given!")) .flatMap(_.toRight("No recipients given!"))
.leftMap(new IllegalArgumentException(_)) .leftMap(new IllegalArgumentException(_))
.map(rec => Channel.Mail(mail.id, mail.connection, rec)), .map(rec => Channel.Mail(mail.id, mail.connection, rec)),
gotify => Right(Channel.Gotify(gotify.id, gotify.url, gotify.appKey)), gotify =>
Right(Channel.Gotify(gotify.id, gotify.url, gotify.appKey, gotify.priority)),
matrix => matrix =>
Right( Right(
Channel Channel
@ -94,7 +95,8 @@ object NotificationChannel {
m.recipients.toList.map(_.displayString) m.recipients.toList.map(_.displayString)
) )
}, },
g => gotify(NotificationGotify(g.id, ChannelType.Gotify, g.url, g.appKey)), g =>
gotify(NotificationGotify(g.id, ChannelType.Gotify, g.url, g.appKey, g.priority)),
m => m =>
matrix( matrix(
NotificationMatrix( NotificationMatrix(

View File

@ -53,7 +53,34 @@ class NotificationCodecTest extends FunSuite {
id(""), id(""),
ChannelType.Gotify, ChannelType.Gotify,
LenientUri.unsafe("http://test.gotify.com"), LenientUri.unsafe("http://test.gotify.com"),
Password("abcde") Password("abcde"),
None
)
)
)
)
}
test("decode with gotify data with prio") {
val json = """{"id":"",
"enabled": true,
"channel": {"id":"", "channelType":"gotify", "url":"http://test.gotify.com", "appKey": "abcde", "priority":9},
"allEvents": false,
"eventFilter": null,
"events": ["TagsChanged", "SetFieldValue"]
}"""
val hook = parse[NotificationHook](json)
assertEquals(hook.enabled, true)
assertEquals(
hook.channel,
Right(
NotificationChannel.Gotify(
NotificationGotify(
id(""),
ChannelType.Gotify,
LenientUri.unsafe("http://test.gotify.com"),
Password("abcde"),
Some(9)
) )
) )
) )

View File

@ -0,0 +1,2 @@
ALTER TABLE "notification_channel_gotify"
ADD COLUMN "priority" integer;

View File

@ -0,0 +1,2 @@
ALTER TABLE `notification_channel_gotify`
ADD COLUMN `priority` tinyint unsigned;

View File

@ -0,0 +1,2 @@
ALTER TABLE "notification_channel_gotify"
ADD COLUMN "priority" smallint;

View File

@ -26,7 +26,7 @@ object ChannelMap {
def readGotify( def readGotify(
r: RNotificationChannelGotify r: RNotificationChannelGotify
): ConnectionIO[Vector[NotificationChannel]] = ): ConnectionIO[Vector[NotificationChannel]] =
pure(NotificationChannel.Gotify(r.url, r.appKey)) pure(NotificationChannel.Gotify(r.url, r.appKey, r.priority))
def readMatrix( def readMatrix(
r: RNotificationChannelMatrix r: RNotificationChannelMatrix

View File

@ -20,6 +20,7 @@ final case class RNotificationChannelGotify(
uid: Ident, uid: Ident,
url: LenientUri, url: LenientUri,
appKey: Password, appKey: Password,
priority: Option[Int],
created: Timestamp created: Timestamp
) { ) {
def vary: RNotificationChannel = def vary: RNotificationChannel =
@ -35,10 +36,11 @@ object RNotificationChannelGotify {
val uid = Column[Ident]("uid", this) val uid = Column[Ident]("uid", this)
val url = Column[LenientUri]("url", this) val url = Column[LenientUri]("url", this)
val appKey = Column[Password]("app_key", this) val appKey = Column[Password]("app_key", this)
val priority = Column[Int]("priority", this)
val created = Column[Timestamp]("created", this) val created = Column[Timestamp]("created", this)
val all: NonEmptyList[Column[_]] = val all: NonEmptyList[Column[_]] =
NonEmptyList.of(id, uid, url, appKey, created) NonEmptyList.of(id, uid, url, appKey, priority, created)
} }
val T: Table = Table(None) val T: Table = Table(None)
@ -49,7 +51,11 @@ object RNotificationChannelGotify {
run(select(T.all), from(T), T.id === id).query[RNotificationChannelGotify].option run(select(T.all), from(T), T.id === id).query[RNotificationChannelGotify].option
def insert(r: RNotificationChannelGotify): ConnectionIO[Int] = def insert(r: RNotificationChannelGotify): ConnectionIO[Int] =
DML.insert(T, T.all, sql"${r.id},${r.uid},${r.url},${r.appKey},${r.created}") DML.insert(
T,
T.all,
sql"${r.id},${r.uid},${r.url},${r.appKey},${r.priority},${r.created}"
)
def update(r: RNotificationChannelGotify): ConnectionIO[Int] = def update(r: RNotificationChannelGotify): ConnectionIO[Int] =
DML.update( DML.update(
@ -57,7 +63,8 @@ object RNotificationChannelGotify {
T.id === r.id && T.uid === r.uid, T.id === r.id && T.uid === r.uid,
DML.set( DML.set(
T.url.setTo(r.url), T.url.setTo(r.url),
T.appKey.setTo(r.appKey) T.appKey.setTo(r.appKey),
T.priority.setTo(r.priority)
) )
) )

View File

@ -149,16 +149,3 @@ view cfg model =
[ Maybe.withDefault "" model.error |> text [ Maybe.withDefault "" model.error |> text
] ]
] ]
viewWithInfo2 : String -> String -> Maybe Int -> String -> Model -> Html Msg
viewWithInfo2 label info nval classes model =
let
cfg =
{ label = label
, info = info
, number = nval
, classes = classes
}
in
view cfg model

View File

@ -9,6 +9,8 @@ module Comp.NotificationGotifyForm exposing (Model, Msg, init, initWith, update,
import Api.Model.NotificationGotify exposing (NotificationGotify) import Api.Model.NotificationGotify exposing (NotificationGotify)
import Comp.Basic as B import Comp.Basic as B
import Comp.FixedDropdown
import Data.DropdownStyle
import Data.NotificationChannel import Data.NotificationChannel
import Html exposing (..) import Html exposing (..)
import Html.Attributes exposing (..) import Html.Attributes exposing (..)
@ -19,24 +21,28 @@ import Styles as S
type alias Model = type alias Model =
{ hook : NotificationGotify { hook : NotificationGotify
, prioModel : Comp.FixedDropdown.Model Int
} }
init : Model init : Model
init = init =
{ hook = Data.NotificationChannel.setTypeGotify Api.Model.NotificationGotify.empty { hook = Data.NotificationChannel.setTypeGotify Api.Model.NotificationGotify.empty
, prioModel = Comp.FixedDropdown.init (List.range 0 10)
} }
initWith : NotificationGotify -> Model initWith : NotificationGotify -> Model
initWith hook = initWith hook =
{ hook = Data.NotificationChannel.setTypeGotify hook { hook = Data.NotificationChannel.setTypeGotify hook
, prioModel = Comp.FixedDropdown.init (List.range 0 10)
} }
type Msg type Msg
= SetUrl String = SetUrl String
| SetAppKey String | SetAppKey String
| PrioMsg (Comp.FixedDropdown.Msg Int)
@ -46,10 +52,25 @@ type Msg
update : Msg -> Model -> ( Model, Maybe NotificationGotify ) update : Msg -> Model -> ( Model, Maybe NotificationGotify )
update msg model = update msg model =
let let
newHook = hook =
updateHook msg model.hook model.hook
newModel =
case msg of
SetUrl s ->
{ model | hook = { hook | url = s } }
SetAppKey s ->
{ model | hook = { hook | appKey = s } }
PrioMsg lm ->
let
( m, sel ) =
Comp.FixedDropdown.update lm model.prioModel
in
{ model | hook = { hook | priority = sel }, prioModel = m }
in in
( { model | hook = newHook }, check newHook ) ( newModel, check newModel.hook )
check : NotificationGotify -> Maybe NotificationGotify check : NotificationGotify -> Maybe NotificationGotify
@ -57,22 +78,20 @@ check hook =
Just hook Just hook
updateHook : Msg -> NotificationGotify -> NotificationGotify
updateHook msg hook =
case msg of
SetUrl s ->
{ hook | url = s }
SetAppKey s ->
{ hook | appKey = s }
--- View --- View
view : Texts -> Model -> Html Msg view : Texts -> Model -> Html Msg
view texts model = view texts model =
let
cfg =
{ display = String.fromInt
, icon = \n -> Nothing
, selectPlaceholder = texts.priority
, style = Data.DropdownStyle.mainStyle
}
in
div [] div []
[ div [ div
[ class "mb-2" [ class "mb-2"
@ -114,4 +133,18 @@ view texts model =
] ]
[] []
] ]
, div
[ class "mb-2"
]
[ label
[ for "prio"
, class S.inputLabel
]
[ text texts.priority
]
, Html.map PrioMsg (Comp.FixedDropdown.viewStyled2 cfg False model.hook.priority model.prioModel)
, span [ class "text-sm opacity-75" ]
[ text texts.priorityInfo
]
]
] ]

View File

@ -18,6 +18,8 @@ type alias Texts =
{ basics : Messages.Basics.Texts { basics : Messages.Basics.Texts
, gotifyUrl : String , gotifyUrl : String
, appKey : String , appKey : String
, priority : String
, priorityInfo : String
} }
@ -26,6 +28,8 @@ gb =
{ basics = Messages.Basics.gb { basics = Messages.Basics.gb
, gotifyUrl = "Gotify URL" , gotifyUrl = "Gotify URL"
, appKey = "App Key" , appKey = "App Key"
, priority = "Priority"
, priorityInfo = "A number denoting the importance of a message controlling notification behaviour. The higher the more important."
} }
@ -34,4 +38,6 @@ de =
{ basics = Messages.Basics.de { basics = Messages.Basics.de
, gotifyUrl = "Gotify URL" , gotifyUrl = "Gotify URL"
, appKey = "App Key" , appKey = "App Key"
, priority = "Priorität"
, priorityInfo = "Eine Zahl, um die Wichtigkeit anzugeben (je höher desto wichtiger). Es steuert, wie eine Notifizierung erscheint."
} }