@@ -47,6 +47,8 @@ import Distribution.Server.Features.Upload
47
47
import Distribution.Server.Features.UserDetails
48
48
import Distribution.Server.Features.Users
49
49
50
+ import Distribution.Server.Util.Email
51
+
50
52
import qualified Data.Map as Map
51
53
import qualified Data.Set as Set
52
54
@@ -59,7 +61,6 @@ import Data.Bimap (lookup, lookupR)
59
61
import Data.Graph (Vertex )
60
62
import Data.Hashable (Hashable (.. ))
61
63
import Data.List (maximumBy , sortOn )
62
- import Data.List (intercalate )
63
64
import Data.Maybe (fromJust , fromMaybe , listToMaybe , mapMaybe , maybeToList )
64
65
import Data.Ord (Down (.. ), comparing )
65
66
import Data.SafeCopy (Migrate (migrate ), MigrateFrom , base , deriveSafeCopy , extension )
@@ -713,12 +714,13 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
713
714
-- Dependency email notifications consist of multiple paragraphs, so it would be confusing if concatenated.
714
715
-- So they're sent independently.
715
716
mapM_ (sendNotifyEmailAndDelay users) . Map. toList $
716
- Map. mapKeys fst . Map. mapWithKey (\ (_, dep) ebody -> (" Dependency Update: " <> T. pack (display dep), ebody )) $
717
+ Map. mapKeys fst . Map. mapWithKey (\ (_, dep) emailContent -> (" Dependency Update: " <> T. pack (display dep), emailContent )) $
717
718
dependencyEmails
718
719
719
720
updateState notifyState (SetNotifyTime now)
720
721
721
722
formatTimeUser users t u =
723
+ EmailContentText . T. pack $
722
724
display (Users. userIdToName users u) ++ " [" ++
723
725
(formatTime defaultTimeLocale " %c" t) ++ " ]"
724
726
@@ -808,58 +810,58 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
808
810
809
811
describeRevision users earlier now pkg
810
812
| pkgNumRevisions pkg <= 1 =
811
- " Package upload, " ++ display (packageName pkg) ++ " , by " ++
812
- formatTimeUser users (pkgLatestUploadTime pkg) (pkgLatestUploadUser pkg)
813
+ " Package upload, " <> emailContentDisplay (packageName pkg) <> " , by " <>
814
+ formatTimeUser users (pkgLatestUploadTime pkg) (pkgLatestUploadUser pkg)
813
815
| otherwise =
814
- " Package metadata revision(s), " ++ display (packageName pkg) ++ " :\n " ++
815
- unlines (map (uncurry (formatTimeUser users) . snd ) recentRevs)
816
+ " Package metadata revision(s), " <> emailContentDisplay (packageName pkg) <> " :" <> EmailContentSoftBreak
817
+ <> foldMap ( <> EmailContentSoftBreak ) (map (uncurry (formatTimeUser users) . snd ) recentRevs)
816
818
where
817
819
revs = reverse $ Vec. toList (pkgMetadataRevisions pkg)
818
820
recentRevs = filter ((\ x -> x > earlier && x <= now) . fst . snd ) revs
819
821
820
822
describeGroupAction users (time, uid, act, reason) =
821
823
fmap
822
824
( \ message ->
823
- " Group modified by " ++ formatTimeUser users time uid ++ " :\n "
824
- ++ message ++ " \n "
825
- ++ " Reason: " ++ BS. unpack reason
825
+ " Group modified by " <> formatTimeUser users time uid <> " :" <> EmailContentSoftBreak
826
+ <> message <> EmailContentSoftBreak
827
+ <> " Reason: " <> emailContentLBS reason
826
828
)
827
829
$ case act of
828
830
(Admin_GroupAddUser tn (MaintainerGroup pkg)) ->
829
831
Just $
830
- display (Users. userIdToName users tn)
832
+ emailContentDisplay (Users. userIdToName users tn)
831
833
<> " added to maintainers for "
832
- <> BS. unpack pkg
834
+ <> emailContentLBS pkg
833
835
(Admin_GroupDelUser tn (MaintainerGroup pkg)) ->
834
836
Just $
835
- display (Users. userIdToName users tn)
837
+ emailContentDisplay (Users. userIdToName users tn)
836
838
<> " removed from maintainers for "
837
- <> BS. unpack pkg
839
+ <> emailContentLBS pkg
838
840
_ -> Nothing
839
841
840
842
describeDocReport (pkg, success) =
841
- " Package doc build for " ++ display (packageName pkg) ++ " :\n " ++
843
+ " Package doc build for " <> emailContentDisplay (packageName pkg) <> " :" <> EmailContentSoftBreak <>
842
844
if success
843
845
then " Build successful."
844
846
else " Build failed."
845
847
846
848
describeTagProposal (pkgName, (addTags, delTags)) =
847
- " Pending tag proposal for " ++ display pkgName ++ " :\n " ++
848
- " Additions: " ++ showTags addTags ++ " \n " ++
849
- " Deletions: " ++ showTags delTags
849
+ " Pending tag proposal for " <> emailContentDisplay pkgName <> " :" <> EmailContentSoftBreak
850
+ <> " Additions: " <> showTags addTags <> EmailContentSoftBreak
851
+ <> " Deletions: " <> showTags delTags
850
852
where
851
- showTags = intercalate " , " . map display . Set. toList
853
+ showTags = emailContentIntercalate " , " . map emailContentDisplay . Set. toList
852
854
853
855
describeDependencyUpdate (uId, dep) revDeps = do
854
856
mPrefs <- queryGetUserNotifyPref uId
855
857
pure $
856
858
case mPrefs of
857
859
Nothing -> []
858
860
Just NotifyPref {notifyDependencyTriggerBounds} ->
859
- let depName = display (packageName dep)
860
- depVersion = display (packageVersion dep)
861
+ let depName = emailContentDisplay (packageName dep)
862
+ depVersion = emailContentDisplay (packageVersion dep)
861
863
in
862
- [ " The dependency " <> display dep <> " has been uploaded or revised."
864
+ [ " The dependency " <> emailContentDisplay dep <> " has been uploaded or revised."
863
865
, case notifyDependencyTriggerBounds of
864
866
Always ->
865
867
" You have requested to be notified for each upload or revision \
@@ -878,10 +880,10 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
878
880
<> " but don't accept " <> depVersion
879
881
<> " (they do accept the second-highest version):"
880
882
]
881
- ++ map display revDeps
883
+ ++ map emailContentDisplay revDeps
882
884
883
- sendNotifyEmailAndDelay :: Users. Users -> (UserId , (T. Text , [String ])) -> IO ()
884
- sendNotifyEmailAndDelay users (uid, (subject, ebody )) = do
885
+ sendNotifyEmailAndDelay :: Users. Users -> (UserId , (T. Text , [EmailContent ])) -> IO ()
886
+ sendNotifyEmailAndDelay users (uid, (subject, emailContent )) = do
885
887
mudetails <- queryUserDetails uid
886
888
case mudetails of
887
889
Nothing -> return ()
@@ -891,22 +893,23 @@ userNotifyFeature ServerEnv{serverBaseURI, serverCron}
891
893
mail = (emptyMail mailFrom) {
892
894
mailTo = [Address (Just aname) eml],
893
895
mailHeaders = [(BSS. pack " Subject" , " [Hackage] " <> subject)],
894
- mailParts = [[Part (T. pack " text/plain; charset=utf-8" )
895
- None DefaultDisposition []
896
- (PartContent $ BS. pack $
897
- intercalate " \n\n " (ebody <> [adjustmentLinkParagraph])
898
- )
899
- ]]
896
+ mailParts =
897
+ [ fromEmailContent $
898
+ foldMap EmailContentParagraph $
899
+ emailContent <> [updatePreferencesText]
900
+ ]
900
901
}
901
902
Just ourHost = uriAuthority serverBaseURI
902
903
903
904
renderSendMail mail -- TODO: if we need any configuration of
904
905
-- sendmail stuff, has to go here
905
906
threadDelay 250000
906
907
where
907
- adjustmentLinkParagraph =
908
- " You can adjust your notification preferences at\n "
909
- <> uriToString id serverBaseURI " "
910
- <> " /user/"
911
- <> display (Users. userIdToName users uid)
912
- <> " /notify"
908
+ updatePreferencesText =
909
+ " 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
+ )
0 commit comments