1
0
Fork 0
mirror of https://code.sup39.dev/repos/Wqawg synced 2024-12-28 07:14:50 +09:00

When sending ticket comment in regular Vervis UI, deliver it using ActivityPub

This commit is contained in:
fr33domlover 2019-04-20 21:34:45 +00:00
parent 4f5c6532ee
commit f7f15e0f63
3 changed files with 130 additions and 74 deletions

View file

@ -27,13 +27,15 @@ import Prelude
import Control.Monad
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Except
import Data.Maybe
import Data.Time.Clock (getCurrentTime)
import Database.Persist
import Database.Persist.Sql
import Data.Traversable
import Text.Blaze.Html (Html)
import Yesod.Auth (requireAuthId)
import Data.Text (Text)
import Yesod.Auth
import Yesod.Core
import Yesod.Core.Handler
import Yesod.Form.Functions (runFormPost)
@ -42,6 +44,7 @@ import Yesod.Persist.Core (runDB, get404, getBy404)
import Network.FedURI
import Web.ActivityPub
import Yesod.Auth.Unverified
import Yesod.FedURI
import Yesod.Hashids
@ -50,6 +53,7 @@ import Yesod.Persist.Local
import Vervis.Discussion
import Vervis.Form.Discussion
import Vervis.Federation
import Vervis.Foundation
import Vervis.Model
import Vervis.Model.Ident
@ -157,38 +161,51 @@ getTopReply replyP = do
defaultLayout $(widgetFile "discussion/top-reply")
postTopReply
:: Route App
:: Text
-> [Route App]
-> Route App
-> Route App
-> (LocalMessageId -> Route App)
-> AppDB DiscussionId
-> Handler Html
postTopReply replyP after getdid = do
postTopReply hDest recips context replyP after = do
((result, widget), enctype) <- runFormPost newMessageForm
elmid <- runExceptT $ do
msg <- case result of
FormMissing -> throwE "Field(s) missing."
FormFailure _l -> throwE "Message submission failed, see errors below."
FormSuccess nm -> return $ nmContent nm
encodeRouteFed <- getEncodeRouteFed
encodeRouteLocal <- getEncodeRouteLocal
let encodeRecipRoute = l2f hDest . encodeRouteLocal
now <- liftIO getCurrentTime
case result of
FormSuccess nm -> do
author <- requireAuthId
mnum <- runDB $ do
did <- getdid
mid <- insert Message
{ messageCreated = now
, messageContent = nmContent nm
, messageParent = Nothing
, messageRoot = did
shrAuthor <- do
Entity _ p <- requireVerifiedAuth
lift $ runDB $ sharerIdent <$> get404 (personIdent p)
let (hLocal, luAuthor) = f2l $ encodeRouteFed $ SharerR shrAuthor
uContext = encodeRecipRoute context
note = Note
{ noteId = Nothing
, noteAttrib = luAuthor
, noteAudience = Audience
{ audienceTo = map encodeRecipRoute recips
, audienceBto = []
, audienceCc = []
, audienceBcc = []
, audienceGeneral = []
}
lmid <- insert LocalMessage
{ localMessageAuthor = author
, localMessageRest = mid
, localMessageUnlinkedParent = Nothing
, noteReplyTo = Just uContext
, noteContext = Just uContext
, notePublished = Just now
, noteContent = msg
}
return lmid
ExceptT $ handleOutboxNote hLocal note
case elmid of
Left e -> do
setMessage $ toHtml e
defaultLayout $(widgetFile "discussion/top-reply")
Right lmid -> do
setMessage "Message submitted."
redirect $ after mnum
FormMissing -> do
setMessage "Field(s) missing."
defaultLayout $(widgetFile "discussion/top-reply")
FormFailure _l -> do
setMessage "Message submission failed, see errors below."
defaultLayout $(widgetFile "discussion/top-reply")
redirect $ after lmid
getReply
:: (MessageId -> Route App)
@ -196,50 +213,76 @@ getReply
-> AppDB DiscussionId
-> MessageId
-> Handler Html
getReply replyG replyP getdid mid = do
mtn <- runDB $ getNode getdid mid
getReply replyG replyP getdid midParent = do
mtn <- runDB $ getNode getdid midParent
now <- liftIO getCurrentTime
((_result, widget), enctype) <- runFormPost newMessageForm
defaultLayout $(widgetFile "discussion/reply")
postReply
:: (MessageId -> Route App)
:: Text
-> [Route App]
-> Route App
-> (MessageId -> Route App)
-> (MessageId -> Route App)
-> (LocalMessageId -> Route App)
-> AppDB DiscussionId
-> MessageId
-> Handler Html
postReply replyG replyP after getdid mid = do
postReply hDest recips context replyG replyP after getdid midParent = do
((result, widget), enctype) <- runFormPost newMessageForm
elmid <- runExceptT $ do
msg <- case result of
FormMissing -> throwE "Field(s) missing."
FormFailure _l -> throwE "Message submission failed, see errors below."
FormSuccess nm -> return $ nmContent nm
encodeRouteFed <- getEncodeRouteFed
encodeRouteLocal <- getEncodeRouteLocal
let encodeRecipRoute = l2f hDest . encodeRouteLocal
now <- liftIO getCurrentTime
case result of
FormSuccess nm -> do
author <- requireAuthId
msgid <- runDB $ do
did <- getdid
parent <- do
message <- get404 mid
unless (messageRoot message == did) notFound
return mid
mid <- insert Message
{ messageCreated = now
, messageContent = nmContent nm
, messageParent = Just parent
, messageRoot = did
(shrAuthor, uParent) <- do
Entity _ p <- requireVerifiedAuth
lift $ runDB $ do
_m <- get404 midParent
shr <- sharerIdent <$> get404 (personIdent p)
mlocal <- getBy $ UniqueLocalMessage midParent
mremote <- getValBy $ UniqueRemoteMessage midParent
parent <- case (mlocal, mremote) of
(Nothing, Nothing) -> error "Message with no author"
(Just _, Just _) -> error "Message used as both local and remote"
(Just (Entity lmidParent lm), Nothing) -> do
p <- getJust $ localMessageAuthor lm
s <- getJust $ personIdent p
lmkhid <- encodeKeyHashid lmidParent
return $ encodeRouteFed $ MessageR (sharerIdent s) lmkhid
(Nothing, Just rm) -> do
i <- getJust $ remoteMessageInstance rm
return $ l2f (instanceHost i) (remoteMessageIdent rm)
return (shr, parent)
let (hLocal, luAuthor) = f2l $ encodeRouteFed $ SharerR shrAuthor
uContext = encodeRecipRoute context
note = Note
{ noteId = Nothing
, noteAttrib = luAuthor
, noteAudience = Audience
{ audienceTo = map encodeRecipRoute recips
, audienceBto = []
, audienceCc = []
, audienceBcc = []
, audienceGeneral = []
}
lmid <- insert LocalMessage
{ localMessageAuthor = author
, localMessageRest = mid
, localMessageUnlinkedParent = Nothing
, noteReplyTo = Just uParent
, noteContext = Just uContext
, notePublished = Just now
, noteContent = msg
}
return lmid
ExceptT $ handleOutboxNote hLocal note
case elmid of
Left e -> do
setMessage $ toHtml e
mtn <- runDB $ getNode getdid midParent
now <- liftIO getCurrentTime
defaultLayout $(widgetFile "discussion/reply")
Right lmid -> do
setMessage "Message submitted."
redirect $ after msgid
FormMissing -> do
setMessage "Field(s) missing."
mtn <- runDB $ getNode getdid mid
defaultLayout $(widgetFile "discussion/reply")
FormFailure _l -> do
setMessage "Message submission failed, see errors below."
mtn <- runDB $ getNode getdid mid
defaultLayout $(widgetFile "discussion/reply")
redirect $ after lmid

View file

@ -97,7 +97,7 @@ import Vervis.Model.Ident
import Vervis.Model.Ticket
import Vervis.Model.Workflow
import Vervis.Render (renderSourceT)
import Vervis.Settings (widgetFile)
import Vervis.Settings
import Vervis.Style
import Vervis.Ticket
import Vervis.TicketFilter (filterTickets)
@ -644,11 +644,17 @@ getTicketDiscussionR shar proj num = do
(selectDiscussionId shar proj num)
postTicketDiscussionR :: ShrIdent -> PrjIdent -> Int -> Handler Html
postTicketDiscussionR shar proj num =
postTicketDiscussionR shr prj num = do
hLocal <- getsYesod $ appInstanceHost . appSettings
postTopReply
(TicketDiscussionR shar proj num)
(const $ TicketR shar proj num)
(selectDiscussionId shar proj num)
hLocal
[ ProjectR shr prj
, TicketParticipantsR shr prj num
, TicketTeamR shr prj num
]
(TicketR shr prj num)
(TicketDiscussionR shr prj num)
(const $ TicketR shr prj num)
getMessageR :: ShrIdent -> KeyHashid LocalMessage -> Handler TypedContent
getMessageR shr hid = do
@ -656,14 +662,21 @@ getMessageR shr hid = do
getDiscussionMessage shr lmid
postTicketMessageR :: ShrIdent -> PrjIdent -> Int -> KeyHashid Message -> Handler Html
postTicketMessageR shar proj tnum hid = do
postTicketMessageR shr prj num mkhid = do
encodeHid <- getEncodeKeyHashid
mid <- decodeKeyHashid404 hid
mid <- decodeKeyHashid404 mkhid
hLocal <- getsYesod $ appInstanceHost . appSettings
postReply
(TicketReplyR shar proj tnum . encodeHid)
(TicketMessageR shar proj tnum . encodeHid)
(const $ TicketR shar proj tnum)
(selectDiscussionId shar proj tnum)
hLocal
[ ProjectR shr prj
, TicketParticipantsR shr prj num
, TicketTeamR shr prj num
]
(TicketR shr prj num)
(TicketReplyR shr prj num . encodeHid)
(TicketMessageR shr prj num . encodeHid)
(const $ TicketR shr prj num)
(selectDiscussionId shr prj num)
mid
getTicketTopReplyR :: ShrIdent -> PrjIdent -> Int -> Handler Html

View file

@ -14,6 +14,6 @@ $# <http://creativecommons.org/publicdomain/zero/1.0/>.
^{messageW now mtn replyG}
<form method=POST action=@{replyP mid} enctype=#{enctype}>
<form method=POST action=@{replyP midParent} enctype=#{enctype}>
^{widget}
<input type=submit>