Skip to content

Commit cbca2d6

Browse files
brandonchinn178ysangkok
authored andcommitted
Add markup to emails
1 parent f39dd8a commit cbca2d6

File tree

1 file changed

+48
-32
lines changed

1 file changed

+48
-32
lines changed

src/Distribution/Server/Features/UserNotify.hs

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ import Data.Time.Format.Internal (buildTime)
6969
import Data.Typeable (Typeable)
7070
import Distribution.Text (display)
7171
import Network.Mail.Mime
72-
import Network.URI(uriAuthority, uriRegName, uriToString)
72+
import Network.URI (uriAuthority, uriPath, uriRegName)
7373
import Text.CSV (CSV, Record)
7474
import Text.PrettyPrint hiding ((<>))
7575
import Text.XHtml hiding (base, text, (</>))
@@ -683,19 +683,19 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
683683

684684
revisionsAndUploads <- collectRevisionsAndUploads trimLastTime now
685685
revisionUploadNotifications <- foldM (genRevUploadList notifyPrefs) Map.empty revisionsAndUploads
686-
let revisionUploadEmails = map (describeRevision users trimLastTime now) <$> revisionUploadNotifications
686+
let revisionUploadEmails = foldMap (describeRevision users trimLastTime now) <$> revisionUploadNotifications
687687

688688
groupActions <- collectAdminActions trimLastTime now
689689
groupActionNotifications <- foldM (genGroupUploadList notifyPrefs) Map.empty groupActions
690-
let groupActionEmails = mapMaybe (describeGroupAction users) <$> groupActionNotifications
690+
let groupActionEmails = mconcat . mapMaybe (describeGroupAction users) <$> groupActionNotifications
691691

692692
docReports <- collectDocReport trimLastTime now
693693
docReportNotifications <- foldM (genDocReportList notifyPrefs) Map.empty docReports
694-
let docReportEmails = map describeDocReport <$> docReportNotifications
694+
let docReportEmails = foldMap describeDocReport <$> docReportNotifications
695695

696696
tagProposals <- collectTagProposals
697697
tagProposalNotifications <- foldM (genTagProposalList notifyPrefs) Map.empty tagProposals
698-
let tagProposalEmails = map describeTagProposal <$> tagProposalNotifications
698+
let tagProposalEmails = foldMap describeTagProposal <$> tagProposalNotifications
699699

700700
idx <- queryGetPackageIndex
701701
revIdx <- liftIO queryReverseIndex
@@ -704,7 +704,7 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
704704

705705
-- Concat the constituent email parts such that only one email is sent per user
706706
mapM_ (sendNotifyEmailAndDelay users) . Map.toList $
707-
fmap ("Maintainer Notifications",) . foldr1 (Map.unionWith (++)) $
707+
fmap ("Maintainer Notifications",) . foldr1 (Map.unionWith (<>)) $
708708
[ revisionUploadEmails
709709
, groupActionEmails
710710
, docReportEmails
@@ -719,6 +719,13 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
719719

720720
updateState notifyState (SetNotifyTime now)
721721

722+
renderPkgLink pkg =
723+
EmailContentLink
724+
(T.pack $ display pkg)
725+
serverBaseURI
726+
{ uriPath = "/package/" <> display (packageName pkg) <> "-" <> display (packageVersion pkg)
727+
}
728+
722729
formatTimeUser users t u =
723730
EmailContentText . T.pack $
724731
display (Users.userIdToName users u) ++ " [" ++
@@ -810,21 +817,24 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
810817

811818
describeRevision users earlier now pkg
812819
| pkgNumRevisions pkg <= 1 =
813-
"Package upload, " <> emailContentDisplay (packageName pkg) <> ", by " <>
820+
EmailContentParagraph $
821+
"Package upload, " <> renderPkgLink (pkgInfoId pkg) <> ", by " <>
814822
formatTimeUser users (pkgLatestUploadTime pkg) (pkgLatestUploadUser pkg)
815823
| otherwise =
816-
"Package metadata revision(s), " <> emailContentDisplay (packageName pkg) <> ":" <> EmailContentSoftBreak
817-
<> foldMap (<> EmailContentSoftBreak) (map (uncurry (formatTimeUser users) . snd) recentRevs)
824+
EmailContentParagraph ("Package metadata revision(s), " <> renderPkgLink (pkgInfoId pkg) <> ":")
825+
<> EmailContentList (map (uncurry (formatTimeUser users) . snd) recentRevs)
818826
where
819827
revs = reverse $ Vec.toList (pkgMetadataRevisions pkg)
820828
recentRevs = filter ((\x -> x > earlier && x <= now) . fst . snd) revs
821829

822830
describeGroupAction users (time, uid, act, reason) =
823831
fmap
824832
( \message ->
825-
"Group modified by " <> formatTimeUser users time uid <> ":" <> EmailContentSoftBreak
826-
<> message <> EmailContentSoftBreak
827-
<> "Reason: " <> emailContentLBS reason
833+
EmailContentParagraph ("Group modified by " <> formatTimeUser users time uid <> ":")
834+
<> EmailContentList
835+
[ message
836+
, "Reason: " <> emailContentLBS reason
837+
]
828838
)
829839
$ case act of
830840
(Admin_GroupAddUser tn (MaintainerGroup pkg)) ->
@@ -840,28 +850,32 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
840850
_ -> Nothing
841851

842852
describeDocReport (pkg, success) =
843-
"Package doc build for " <> emailContentDisplay (packageName pkg) <> ":" <> EmailContentSoftBreak <>
844-
if success
845-
then "Build successful."
846-
else "Build failed."
853+
EmailContentParagraph $
854+
"Package doc build for " <> emailContentDisplay (packageName pkg) <> ":" <> EmailContentSoftBreak <>
855+
if success
856+
then "Build successful."
857+
else "Build failed."
847858

848859
describeTagProposal (pkgName, (addTags, delTags)) =
849-
"Pending tag proposal for " <> emailContentDisplay pkgName <> ":" <> EmailContentSoftBreak
850-
<> "Additions: " <> showTags addTags <> EmailContentSoftBreak
851-
<> "Deletions: " <> showTags delTags
860+
EmailContentParagraph ("Pending tag proposal for " <> emailContentDisplay pkgName <> ":")
861+
<> EmailContentList
862+
[ "Additions: " <> showTags addTags
863+
, "Deletions: " <> showTags delTags
864+
]
852865
where
853866
showTags = emailContentIntercalate ", " . map emailContentDisplay . Set.toList
854867

855868
describeDependencyUpdate (uId, dep) revDeps = do
856869
mPrefs <- queryGetUserNotifyPref uId
857870
pure $
858871
case mPrefs of
859-
Nothing -> []
872+
Nothing -> mempty
860873
Just NotifyPref{notifyDependencyTriggerBounds} ->
861874
let depName = emailContentDisplay (packageName dep)
862875
depVersion = emailContentDisplay (packageVersion dep)
863876
in
864-
[ "The dependency " <> emailContentDisplay dep <> " has been uploaded or revised."
877+
foldMap EmailContentParagraph
878+
[ "The dependency " <> renderPkgLink dep <> " has been uploaded or revised."
865879
, case notifyDependencyTriggerBounds of
866880
Always ->
867881
"You have requested to be notified for each upload or revision \
@@ -880,9 +894,9 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
880894
<> " but don't accept " <> depVersion
881895
<> " (they do accept the second-highest version):"
882896
]
883-
++ map emailContentDisplay revDeps
897+
<> EmailContentList (map renderPkgLink revDeps)
884898

885-
sendNotifyEmailAndDelay :: Users.Users -> (UserId, (T.Text, [EmailContent])) -> IO ()
899+
sendNotifyEmailAndDelay :: Users.Users -> (UserId, (T.Text, EmailContent)) -> IO ()
886900
sendNotifyEmailAndDelay users (uid, (subject, emailContent)) = do
887901
mudetails <- queryUserDetails uid
888902
case mudetails of
@@ -894,9 +908,7 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
894908
mailTo = [Address (Just aname) eml],
895909
mailHeaders = [(BSS.pack "Subject", "[Hackage] " <> subject)],
896910
mailParts =
897-
[ fromEmailContent $
898-
foldMap EmailContentParagraph $
899-
emailContent <> [updatePreferencesText]
911+
[ fromEmailContent $ emailContent <> updatePreferencesText
900912
]
901913
}
902914
Just ourHost = uriAuthority serverBaseURI
@@ -906,10 +918,14 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
906918
threadDelay 250000
907919
where
908920
updatePreferencesText =
921+
EmailContentParagraph $
909922
"You can adjust your notification preferences at" <> EmailContentSoftBreak
910-
<> (EmailContentText . T.pack)
911-
( uriToString id serverBaseURI ""
912-
<> "/user/"
913-
<> display (Users.userIdToName users uid)
914-
<> "/notify"
915-
)
923+
<> emailContentUrl
924+
serverBaseURI
925+
{ uriPath =
926+
concatMap ("/" <>)
927+
[ "user"
928+
, display $ Users.userIdToName users uid
929+
, "notify"
930+
]
931+
}

0 commit comments

Comments
 (0)