UI, S2S: Store errors in Errbox + display in notifications

This commit is contained in:
Pere Lev 2024-04-28 00:31:48 +03:00
parent a60b05b1ca
commit a428bd74ab
No known key found for this signature in database
GPG key ID: 5252C5C863E5E57D
15 changed files with 141 additions and 113 deletions

View file

@ -79,7 +79,7 @@ import Vervis.Data.Actor
import Vervis.Data.Collab import Vervis.Data.Collab
import Vervis.Data.Discussion import Vervis.Data.Discussion
import Vervis.FedURI import Vervis.FedURI
import Vervis.Federation.Util
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model import Vervis.Model
import Vervis.Persist.Actor import Vervis.Persist.Actor

View file

@ -66,7 +66,7 @@ import Vervis.Data.Collab
import Vervis.Data.Discussion import Vervis.Data.Discussion
import Vervis.Data.Ticket import Vervis.Data.Ticket
import Vervis.FedURI import Vervis.FedURI
import Vervis.Federation.Util
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model hiding (deckCreate) import Vervis.Model hiding (deckCreate)
import Vervis.Recipient (makeRecipientSet, LocalStageBy (..), Aud (..), collectAudience, localActorFollowers) import Vervis.Recipient (makeRecipientSet, LocalStageBy (..), Aud (..), collectAudience, localActorFollowers)
@ -1095,4 +1095,9 @@ deckBehavior now deckID (Left verse@(Verse _authorIdMsig body)) =
deckBehavior _ _ (Right _) = throwE "ClientMsgs aren't supported for Deck" deckBehavior _ _ (Right _) = throwE "ClientMsgs aren't supported for Deck"
instance VervisActor Deck where instance VervisActor Deck where
actorBehavior = deckBehavior actorBehavior now deckID ve = do
errboxID <- lift $ withDB $ do
resourceID <- deckResource <$> getJust deckID
Resource actorID <- getJust resourceID
actorErrbox <$> getJust actorID
adaptErrbox errboxID False deckBehavior now deckID ve

View file

@ -68,7 +68,7 @@ import Vervis.Data.Actor
import Vervis.Data.Collab import Vervis.Data.Collab
import Vervis.Data.Discussion import Vervis.Data.Discussion
import Vervis.FedURI import Vervis.FedURI
import Vervis.Federation.Util
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model hiding (groupCreate) import Vervis.Model hiding (groupCreate)
import Vervis.Recipient (makeRecipientSet, LocalStageBy (..), Aud (..), collectAudience, localActorFollowers, renderLocalActor) import Vervis.Recipient (makeRecipientSet, LocalStageBy (..), Aud (..), collectAudience, localActorFollowers, renderLocalActor)
@ -977,4 +977,9 @@ groupBehavior now groupID (Left verse@(Verse _authorIdMsig body)) =
groupBehavior _ _ (Right _) = throwE "ClientMsgs aren't supported for Group" groupBehavior _ _ (Right _) = throwE "ClientMsgs aren't supported for Group"
instance VervisActor Group where instance VervisActor Group where
actorBehavior = groupBehavior actorBehavior now groupID ve = do
errboxID <- lift $ withDB $ do
resourceID <- groupResource <$> getJust groupID
Resource actorID <- getJust resourceID
actorErrbox <$> getJust actorID
adaptErrbox errboxID False groupBehavior now groupID ve

View file

@ -1,6 +1,6 @@
{- This file is part of Vervis. {- This file is part of Vervis.
- -
- Written in 2023 by fr33domlover <fr33domlover@riseup.net>. - Written in 2023, 2024 by fr33domlover <fr33domlover@riseup.net>.
- -
- Copying is an act of love. Please copy, reuse and share. - Copying is an act of love. Please copy, reuse and share.
- -
@ -70,7 +70,7 @@ import Vervis.Data.Collab
import Vervis.Data.Discussion import Vervis.Data.Discussion
import Vervis.Data.Ticket import Vervis.Data.Ticket
import Vervis.FedURI import Vervis.FedURI
import Vervis.Federation.Util
import Vervis.Fetch import Vervis.Fetch
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model hiding (deckCreate) import Vervis.Model hiding (deckCreate)
@ -578,4 +578,9 @@ loomBehavior now loomID (Left verse@(Verse _authorIdMsig body)) =
loomBehavior _ _ (Right _) = throwE "ClientMsgs aren't supported for Loom" loomBehavior _ _ (Right _) = throwE "ClientMsgs aren't supported for Loom"
instance VervisActor Loom where instance VervisActor Loom where
actorBehavior = loomBehavior actorBehavior now loomID ve = do
errboxID <- lift $ withDB $ do
resourceID <- loomResource <$> getJust loomID
Resource actorID <- getJust resourceID
actorErrbox <$> getJust actorID
adaptErrbox errboxID False loomBehavior now loomID ve

View file

@ -69,7 +69,7 @@ import Vervis.Data.Discussion
import Vervis.Data.Follow import Vervis.Data.Follow
import Vervis.Data.Ticket import Vervis.Data.Ticket
import Vervis.FedURI import Vervis.FedURI
import Vervis.Federation.Util
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model import Vervis.Model
import Vervis.Persist.Actor import Vervis.Persist.Actor
@ -1340,4 +1340,8 @@ personBehavior now personID (Left verse@(Verse _authorIdMsig body)) =
personBehavior now personID (Right msg) = clientBehavior now personID msg personBehavior now personID (Right msg) = clientBehavior now personID msg
instance VervisActor Person where instance VervisActor Person where
actorBehavior = personBehavior actorBehavior now personID ve = do
errboxID <- lift $ withDB $ do
actorID <- personActor <$> getJust personID
actorErrbox <$> getJust actorID
adaptErrbox errboxID True personBehavior now personID ve

View file

@ -69,7 +69,7 @@ import Vervis.Data.Actor
import Vervis.Data.Collab import Vervis.Data.Collab
import Vervis.Data.Discussion import Vervis.Data.Discussion
import Vervis.FedURI import Vervis.FedURI
import Vervis.Federation.Util
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model hiding (projectCreate) import Vervis.Model hiding (projectCreate)
import Vervis.Recipient (makeRecipientSet, LocalStageBy (..), Aud (..), collectAudience, localActorFollowers, renderLocalActor) import Vervis.Recipient (makeRecipientSet, LocalStageBy (..), Aud (..), collectAudience, localActorFollowers, renderLocalActor)
@ -5351,4 +5351,9 @@ projectBehavior now projectID (Left verse@(Verse _authorIdMsig body)) =
projectBehavior _ _ (Right _) = throwE "ClientMsgs aren't supported for Project" projectBehavior _ _ (Right _) = throwE "ClientMsgs aren't supported for Project"
instance VervisActor Project where instance VervisActor Project where
actorBehavior = projectBehavior actorBehavior now projectID ve = do
errboxID <- lift $ withDB $ do
resourceID <- projectResource <$> getJust projectID
Resource actorID <- getJust resourceID
actorErrbox <$> getJust actorID
adaptErrbox errboxID False projectBehavior now projectID ve

View file

@ -1,6 +1,6 @@
{- This file is part of Vervis. {- This file is part of Vervis.
- -
- Written in 2023 by fr33domlover <fr33domlover@riseup.net>. - Written in 2023, 2024 by fr33domlover <fr33domlover@riseup.net>.
- -
- Copying is an act of love. Please copy, reuse and share. - Copying is an act of love. Please copy, reuse and share.
- -
@ -46,9 +46,10 @@ import Vervis.Actor
import Vervis.Cloth import Vervis.Cloth
import Vervis.Data.Discussion import Vervis.Data.Discussion
import Vervis.FedURI import Vervis.FedURI
import Vervis.Federation.Util
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model import Vervis.Model
import Vervis.Persist.Actor
import Vervis.Persist.Discussion import Vervis.Persist.Discussion
import Vervis.Ticket import Vervis.Ticket
@ -59,4 +60,9 @@ repoBehavior now repoID (Left _verse@(Verse _authorIdMsig body)) =
repoBehavior _ _ (Right _) = throwE "ClientMsgs aren't supported for Repo" repoBehavior _ _ (Right _) = throwE "ClientMsgs aren't supported for Repo"
instance VervisActor Repo where instance VervisActor Repo where
actorBehavior = repoBehavior actorBehavior now repoID ve = do
errboxID <- lift $ withDB $ do
resourceID <- repoResource <$> getJust repoID
Resource actorID <- getJust resourceID
actorErrbox <$> getJust actorID
adaptErrbox errboxID False repoBehavior now repoID ve

View file

@ -72,7 +72,7 @@ import Vervis.Cloth
import Vervis.Data.Discussion import Vervis.Data.Discussion
import Vervis.FedURI import Vervis.FedURI
import Vervis.Federation.Auth import Vervis.Federation.Auth
import Vervis.Federation.Util
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model import Vervis.Model
import Vervis.Model.Ident import Vervis.Model.Ident

View file

@ -86,7 +86,7 @@ import Vervis.Cloth
import Vervis.Data.Actor import Vervis.Data.Actor
import Vervis.FedURI import Vervis.FedURI
import Vervis.Federation.Auth import Vervis.Federation.Auth
import Vervis.Federation.Util
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model import Vervis.Model
import Vervis.Model.Ident import Vervis.Model.Ident

View file

@ -98,7 +98,7 @@ import Vervis.Data.Ticket
import Vervis.Darcs import Vervis.Darcs
import Vervis.Web.Delivery import Vervis.Web.Delivery
import Vervis.Federation.Auth import Vervis.Federation.Auth
import Vervis.Federation.Util
import Vervis.FedURI import Vervis.FedURI
import Vervis.Fetch import Vervis.Fetch
import Vervis.Foundation import Vervis.Foundation

View file

@ -1,80 +0,0 @@
{- This file is part of Vervis.
-
- Written in 2019, 2020, 2023, 2024 by fr33domlover <fr33domlover@riseup.net>.
-
- Copying is an act of love. Please copy, reuse and share.
-
- The author(s) have dedicated all copyright and related and neighboring
- rights to this software to the public domain worldwide. This software is
- distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along
- with this software. If not, see
- <http://creativecommons.org/publicdomain/zero/1.0/>.
-}
module Vervis.Federation.Util
( insertToInbox
)
where
import Control.Monad.IO.Class
import Control.Monad.Trans.Reader
import Data.ByteString (ByteString)
import Data.Either
import Data.Time.Clock
import Database.Persist
import Database.Persist.Sql
import Database.Persist.JSON
import Network.FedURI
import Database.Persist.Local
import Vervis.Actor
import Vervis.Federation.Auth
import Vervis.Foundation
import Vervis.Model
-- | Insert an activity delivered to us into our inbox. Return its
-- database ID if the activity wasn't already in our inbox.
insertToInbox
:: UTCTime
-> Either
(LocalActorBy Key, ActorId, OutboxItemId)
(RemoteAuthor, LocalURI, Maybe ByteString)
-> ActivityBody
-> InboxId
-> Bool
-> ActDB
(Maybe
( InboxItemId
, Either
(LocalActorBy Key, ActorId, OutboxItemId)
(RemoteAuthor, LocalURI, RemoteActivityId)
)
)
insertToInbox now (Left a@(_, _, outboxItemID)) _body inboxID unread = do
inboxItemID <- insert $ InboxItem unread now "No result yet"
maybeItem <- insertUnique $ InboxItemLocal inboxID outboxItemID inboxItemID
case maybeItem of
Nothing -> do
delete inboxItemID
return Nothing
Just _ -> return $ Just (inboxItemID, Left a)
insertToInbox now (Right (author, luAct, _)) body inboxID unread = do
let iidAuthor = remoteAuthorInstance author
roid <-
either entityKey id <$> insertBy' (RemoteObject iidAuthor luAct)
ractid <- either entityKey id <$> insertBy' RemoteActivity
{ remoteActivityIdent = roid
, remoteActivityContent = persistJSONFromBL $ actbBL body
, remoteActivityReceived = now
}
ibiid <- insert $ InboxItem unread now "No result yet"
mibrid <- insertUnique $ InboxItemRemote inboxID ractid ibiid
case mibrid of
Nothing -> do
delete ibiid
return Nothing
Just _ -> return $ Just (ibiid, Right (author, luAct, ractid))

View file

@ -532,13 +532,16 @@ getNotificationsR = do
Entity _ viewer <- requireVerifiedAuth Entity _ viewer <- requireVerifiedAuth
items <- runDB $ do items <- runDB $ do
inboxID <- actorInbox <$> getJust (personActor viewer) actor <- getJust $ personActor viewer
map adaptItem <$> getItems inboxID map adaptItem <$>
liftA2 (++)
(getItems $ actorErrbox actor)
(getItems $ actorInbox actor)
notifications <- for items $ \ (ibiid, activity) -> do notifications <- for items $ \ (ibiid, activity, result) -> do
((_result, widget), enctype) <- ((_result, widget), enctype) <-
runFormPost $ notificationForm $ Just $ Just (ibiid, False) runFormPost $ notificationForm $ Just $ Just (ibiid, False)
return (activity, widget, enctype) return (activity, result, widget, enctype)
((_result, widgetAll), enctypeAll) <- ((_result, widgetAll), enctypeAll) <-
runFormPost $ notificationForm $ Just Nothing runFormPost $ notificationForm $ Just Nothing
@ -570,18 +573,19 @@ getNotificationsR = do
, ob E.?. OutboxItemPublished , ob E.?. OutboxItemPublished
, ract E.?. RemoteActivityContent , ract E.?. RemoteActivityContent
, ract E.?. RemoteActivityReceived , ract E.?. RemoteActivityReceived
, ib E.^. InboxItemResult
) )
adaptItem adaptItem
(E.Value ibid, E.Value mact, E.Value mpub, E.Value mobj, E.Value mrec) = (E.Value ibid, E.Value mact, E.Value mpub, E.Value mobj, E.Value mrec, E.Value result) =
case (mact, mpub, mobj, mrec) of case (mact, mpub, mobj, mrec) of
(Nothing, Nothing, Nothing, Nothing) -> (Nothing, Nothing, Nothing, Nothing) ->
error $ ibiidString ++ " neither local nor remote" error $ ibiidString ++ " neither local nor remote"
(Just _, Just _, Just _, Just _) -> (Just _, Just _, Just _, Just _) ->
error $ ibiidString ++ " both local and remote" error $ ibiidString ++ " both local and remote"
(Just act, Just pub, Nothing, Nothing) -> (Just act, Just pub, Nothing, Nothing) ->
(ibid, (persistJSONObject act, (pub, False))) (ibid, (persistJSONObject act, (pub, False)), result)
(Nothing, Nothing, Just obj, Just rec) -> (Nothing, Nothing, Just obj, Just rec) ->
(ibid, (persistJSONObject obj, (rec, True))) (ibid, (persistJSONObject obj, (rec, True)), result)
_ -> error $ "Unexpected query result for " ++ ibiidString _ -> error $ "Unexpected query result for " ++ ibiidString
where where
ibiidString = "InboxItem #" ++ show (E.fromSqlKey ibid) ibiidString = "InboxItem #" ++ show (E.fromSqlKey ibid)
@ -598,10 +602,12 @@ postNotificationsR = do
setMessage $ toHtml $ "Marking as read failed:" <> T.pack (show l) setMessage $ toHtml $ "Marking as read failed:" <> T.pack (show l)
FormSuccess mitem -> do FormSuccess mitem -> do
(multi, markedUnread) <- runDB $ do (multi, markedUnread) <- runDB $ do
inboxID <- actorInbox <$> getJust (personActor poster) actor <- getJust $ personActor poster
let inboxID = actorInbox actor
errboxID = actorErrbox actor
case mitem of case mitem of
Nothing -> do Nothing -> do
ibiids <- map E.unValue <$> getItems inboxID ibiids <- map E.unValue <$> liftA2 (++) (getItems errboxID) (getItems inboxID)
updateWhere updateWhere
[InboxItemId <-. ibiids] [InboxItemId <-. ibiids]
[InboxItemUnread =. False] [InboxItemUnread =. False]
@ -616,9 +622,9 @@ postNotificationsR = do
let samePid = let samePid =
case mib of case mib of
Left ibl -> Left ibl ->
inboxItemLocalInbox ibl == inboxID inboxItemLocalInbox ibl == inboxID || inboxItemLocalInbox ibl == errboxID
Right ibr -> Right ibr ->
inboxItemRemoteInbox ibr == inboxID inboxItemRemoteInbox ibr == inboxID || inboxItemRemoteInbox ibr == errboxID
if samePid if samePid
then do then do
update ibiid [InboxItemUnread =. unread] update ibiid [InboxItemUnread =. unread]

View file

@ -1,6 +1,7 @@
{- This file is part of Vervis. {- This file is part of Vervis.
- -
- Written in 2022, 2023, 2024 by fr33domlover <fr33domlover@riseup.net>. - Written in 2019, 2020, 2022, 2023, 2024
- by fr33domlover <fr33domlover@riseup.net>.
- -
- Copying is an act of love. Please copy, reuse and share. - Copying is an act of love. Please copy, reuse and share.
- -
@ -38,6 +39,8 @@ module Vervis.Persist.Actor
, getRemoteActorM , getRemoteActorM
, getRemoteActorE , getRemoteActorE
, doneDB , doneDB
, insertToInbox
, adaptErrbox
) )
where where
@ -50,8 +53,10 @@ import Control.Monad.Trans.Maybe
import Control.Monad.Trans.Reader import Control.Monad.Trans.Reader
import Data.Aeson import Data.Aeson
import Data.Barbie import Data.Barbie
import Data.ByteString (ByteString)
import Data.Bitraversable import Data.Bitraversable
import Data.Text (Text) import Data.Text (Text)
import Data.Time.Clock
import Data.Traversable import Data.Traversable
import Database.Persist import Database.Persist
import Database.Persist.Sql import Database.Persist.Sql
@ -323,3 +328,63 @@ doneDB :: InboxItemId -> Text -> VA.ActE (Text, VA.Act (), Next)
doneDB itemID msg = do doneDB itemID msg = do
lift $ VA.withDB $ update itemID [InboxItemResult =. msg] lift $ VA.withDB $ update itemID [InboxItemResult =. msg]
done msg done msg
-- | Insert an activity delivered to us into our inbox. Return its
-- database ID if the activity wasn't already in our inbox.
insertToInbox
:: UTCTime
-> Either
(LocalActorBy Key, ActorId, OutboxItemId)
(VA.RemoteAuthor, LocalURI, Maybe ByteString)
-> VA.ActivityBody
-> InboxId
-> Bool
-> VA.ActDB
(Maybe
( InboxItemId
, Either
(LocalActorBy Key, ActorId, OutboxItemId)
(VA.RemoteAuthor, LocalURI, RemoteActivityId)
)
)
insertToInbox now (Left a@(_, _, outboxItemID)) _body inboxID unread = do
inboxItemID <- insert $ InboxItem unread now "No result yet"
maybeItem <- insertUnique $ InboxItemLocal inboxID outboxItemID inboxItemID
case maybeItem of
Nothing -> do
delete inboxItemID
return Nothing
Just _ -> return $ Just (inboxItemID, Left a)
insertToInbox now (Right (author, luAct, _)) body inboxID unread = do
let iidAuthor = VA.remoteAuthorInstance author
roid <-
either entityKey id <$> insertBy' (RemoteObject iidAuthor luAct)
ractid <- either entityKey id <$> insertBy' RemoteActivity
{ remoteActivityIdent = roid
, remoteActivityContent = persistJSONFromBL $ VA.actbBL body
, remoteActivityReceived = now
}
ibiid <- insert $ InboxItem unread now "No result yet"
mibrid <- insertUnique $ InboxItemRemote inboxID ractid ibiid
case mibrid of
Nothing -> do
delete ibiid
return Nothing
Just _ -> return $ Just (ibiid, Right (author, luAct, ractid))
adaptErrbox
:: InboxId
-> Bool
-> (UTCTime -> Key a -> VA.VerseExt -> VA.ActE (Text, VA.Act (), Next))
-> UTCTime -> Key a -> VA.VerseExt -> VA.ActE (Text, VA.Act (), Next)
adaptErrbox _ _ behavior now key ve@(Right _) = behavior now key ve
adaptErrbox inboxID unread behavior now key ve@(Left (VA.Verse authorIdMsig body)) = do
result <- lift $ runExceptT $ behavior now key ve
case result of
Right success -> return success
Left err -> do
_ <- lift $ VA.withDB $ runMaybeT $ do
_ <- MaybeT $ get inboxID
(itemID, _) <- MaybeT $ insertToInbox now authorIdMsig body inboxID unread
lift $ update itemID [InboxItemResult =. err]
throwE err

View file

@ -1,6 +1,6 @@
$# This file is part of Vervis. $# This file is part of Vervis.
$# $#
$# Written in 2019, 2022 by fr33domlover <fr33domlover@riseup.net>. $# Written in 2019, 2022, 2024 by fr33domlover <fr33domlover@riseup.net>.
$# $#
$# ♡ Copying is an act of love. Please copy, reuse and share. $# ♡ Copying is an act of love. Please copy, reuse and share.
$# $#
@ -22,7 +22,7 @@ $else
<input type="submit" value="Mark all as read"> <input type="submit" value="Mark all as read">
<div> <div>
$forall ((obj, (time, isRemote)), widget, enctype) <- notifications $forall ((obj, (time, isRemote)), result, widget, enctype) <- notifications
<div> <div>
$if isRemote $if isRemote
Received # Received #
@ -31,6 +31,14 @@ $else
<a href="#{objectId obj}"> <a href="#{objectId obj}">
#{showTime time} #{showTime time}
<div>
Result:
<i>
$if T.null result
[None]
$else
#{result}
$maybe summary <- objectSummary obj $maybe summary <- objectSummary obj
<div> <div>
^{preEscapedToHtml summary} ^{preEscapedToHtml summary}

View file

@ -175,7 +175,6 @@ library
Vervis.Federation.Offer Vervis.Federation.Offer
--Vervis.Federation.Push --Vervis.Federation.Push
Vervis.Federation.Ticket Vervis.Federation.Ticket
Vervis.Federation.Util
Vervis.FedURI Vervis.FedURI
Vervis.Fetch Vervis.Fetch
Vervis.Field.Key Vervis.Field.Key