mirror of
https://code.sup39.dev/repos/Wqawg
synced 2024-12-27 15:14:50 +09:00
When sending ticket comment in regular Vervis UI, deliver it using ActivityPub
This commit is contained in:
parent
4f5c6532ee
commit
f7f15e0f63
3 changed files with 130 additions and 74 deletions
|
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
}
|
||||
return lmid
|
||||
, noteReplyTo = Just uContext
|
||||
, noteContext = Just uContext
|
||||
, notePublished = Just now
|
||||
, noteContent = msg
|
||||
}
|
||||
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
|
||||
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
|
||||
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
|
||||
(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
|
||||
}
|
||||
return lmid
|
||||
, noteReplyTo = Just uParent
|
||||
, noteContext = Just uContext
|
||||
, notePublished = Just now
|
||||
, noteContent = msg
|
||||
}
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue