Skip to content

Commit b896c75

Browse files
brandonchinn178ysangkok
authored andcommitted
Move describeRevision into getNotificationEmails
1 parent 9da933c commit b896c75

File tree

1 file changed

+92
-32
lines changed

1 file changed

+92
-32
lines changed

src/Distribution/Server/Features/UserNotify.hs

Lines changed: 92 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -686,8 +686,7 @@ userNotifyFeature serverEnv@ServerEnv{serverBaseURI, serverCron}
686686
users <- queryGetUserDb
687687

688688
revisionsAndUploads <- collectRevisionsAndUploads trimLastTime now
689-
revisionUploadNotifications <- foldM (genRevUploadList notifyPrefs) Map.empty revisionsAndUploads
690-
let revisionUploadEmails = foldMap (describeRevision users trimLastTime now) <$> revisionUploadNotifications
689+
revisionUploadNotifications <- concatMapM (genRevUploadList notifyPrefs trimLastTime now) revisionsAndUploads
691690

692691
groupActions <- collectAdminActions trimLastTime now
693692
groupActionNotifications <- foldM (genGroupUploadList notifyPrefs) Map.empty groupActions
@@ -709,13 +708,15 @@ userNotifyFeature serverEnv@ServerEnv{serverBaseURI, serverCron}
709708
emails <-
710709
getNotificationEmails serverEnv userDetailsFeature users
711710
( foldr1 (Map.unionWith (<>))
712-
[ revisionUploadEmails
713-
, groupActionEmails
711+
[ groupActionEmails
714712
, docReportEmails
715713
, tagProposalEmails
716714
]
717715
, dependencyEmails
718-
)
716+
) $
717+
concat
718+
[ revisionUploadNotifications
719+
]
719720
mapM_ sendNotifyEmailAndDelay emails
720721

721722
updateState notifyState (SetNotifyTime now)
@@ -762,25 +763,39 @@ userNotifyFeature serverEnv@ServerEnv{serverBaseURI, serverCron}
762763
writeMemState tagProposalLog Map.empty
763764
pure $ Map.toList logs
764765

765-
genRevUploadList notifyPrefs mp pkg = do
766+
genRevUploadList notifyPrefs earlier now pkg = do
766767
pkgIndex <- queryGetPackageIndex
767768
let actor = pkgLatestUploadUser pkg
768769
isRevision = pkgNumRevisions pkg > 1
769770
pkgName = packageName . pkgInfoId $ pkg
770771
mbLatest = listToMaybe . take 1 . reverse $ PackageIndex.lookupPackageName pkgIndex pkgName
771772
isLatestVersion = maybe False (\x -> pkgInfoId pkg == pkgInfoId x) mbLatest
772-
addNotification uid m =
773-
if not (notifyOptOut npref) &&
774-
(isRevision &&
775-
( notifyRevisionRange npref == NotifyAllVersions ||
776-
((notifyRevisionRange npref == NotifyNewestVersion) && isLatestVersion))
777-
||
778-
not isRevision && notifyUpload npref)
779-
then Map.insertWith (++) uid [pkg] m
780-
else m
781-
where npref = fromMaybe defaultNotifyPrefs (Map.lookup uid notifyPrefs)
782773
maintainers <- queryUserGroup $ maintainersGroup (packageName . pkgInfoId $ pkg)
783-
return $ foldr addNotification mp (toList (delete actor maintainers))
774+
pure . flip mapMaybe (toList maintainers) $ \uid ->
775+
fmap (uid,) $ do
776+
let NotifyPref{..} = fromMaybe defaultNotifyPrefs (Map.lookup uid notifyPrefs)
777+
guard $ uid /= actor
778+
guard $ not notifyOptOut
779+
if isRevision
780+
then do
781+
guard $
782+
notifyRevisionRange == NotifyAllVersions ||
783+
(notifyRevisionRange == NotifyNewestVersion && isLatestVersion)
784+
Just
785+
NotifyNewRevision
786+
{ notifyPackageId = pkgInfoId pkg
787+
, notifyRevisions =
788+
filter (\(t, _) -> earlier < t && t <= now)
789+
. map snd
790+
. Vec.toList
791+
$ pkgMetadataRevisions pkg
792+
}
793+
else do
794+
guard notifyUpload
795+
Just
796+
NotifyNewVersion
797+
{ notifyPackageInfo = pkg
798+
}
784799

785800
genGroupUploadList notifyPrefs mp ga =
786801
let (actor,gdesc) = case ga of (_,uid,Admin_GroupAddUser _ gd,_) -> (uid, gd)
@@ -817,18 +832,6 @@ userNotifyFeature serverEnv@ServerEnv{serverBaseURI, serverCron}
817832
Map.mapKeys (, pid) <$>
818833
getUserNotificationsOnRelease (queryUserGroup . maintainersGroup) idx revIdx queryGetUserNotifyPref pid
819834

820-
describeRevision users earlier now pkg
821-
| pkgNumRevisions pkg <= 1 =
822-
EmailContentParagraph $
823-
"Package upload, " <> renderPkgLink (pkgInfoId pkg) <> ", by " <>
824-
formatTimeUser users (pkgLatestUploadTime pkg) (pkgLatestUploadUser pkg)
825-
| otherwise =
826-
EmailContentParagraph ("Package metadata revision(s), " <> renderPkgLink (pkgInfoId pkg) <> ":")
827-
<> EmailContentList (map (uncurry (formatTimeUser users) . snd) recentRevs)
828-
where
829-
revs = reverse $ Vec.toList (pkgMetadataRevisions pkg)
830-
recentRevs = filter ((\x -> x > earlier && x <= now) . fst . snd) revs
831-
832835
describeGroupAction users (time, uid, act, reason) =
833836
fmap
834837
( \message ->
@@ -906,6 +909,15 @@ userNotifyFeature serverEnv@ServerEnv{serverBaseURI, serverCron}
906909
-- delay sending out emails, because ???
907910
threadDelay 250000
908911

912+
data Notification
913+
= NotifyNewVersion
914+
{ notifyPackageInfo :: PkgInfo
915+
}
916+
| NotifyNewRevision
917+
{ notifyPackageId :: PackageId
918+
, notifyRevisions :: [UploadInfo]
919+
}
920+
909921
-- | Notifications in the same group are batched in the same email.
910922
--
911923
-- TODO: How often do multiple notifications come in at once? Maybe it's
@@ -921,14 +933,17 @@ getNotificationEmails
921933
-> UserDetailsFeature
922934
-> Users.Users
923935
-> (Map UserId EmailContent, Map (UserId, PackageId) EmailContent)
936+
-> [(UserId, Notification)]
924937
-> IO [Mail]
925938
getNotificationEmails
926939
ServerEnv{serverBaseURI}
927940
UserDetailsFeature{queryUserDetails}
928941
allUsers
929-
(generalEmails, dependencyUpdateEmails) = do
930-
let userIds = Set.fromList . Map.keys $ generalEmails <> Map.mapKeys fst dependencyUpdateEmails
931-
userIdToDetails <- Map.mapMaybe id <$> fromSetM queryUserDetails userIds
942+
(generalEmails, dependencyUpdateEmails)
943+
notifications = do
944+
let userIds = Set.fromList $ map fst notifications
945+
let userIds' = Set.fromList . Map.keys $ generalEmails <> Map.mapKeys fst dependencyUpdateEmails
946+
userIdToDetails <- Map.mapMaybe id <$> fromSetM queryUserDetails (userIds <> userIds')
932947

933948
pure $
934949
let emails =
@@ -940,6 +955,8 @@ getNotificationEmails
940955
. Map.mapKeys fst
941956
. Map.mapWithKey (\(_, pkg) emailContent -> (emailContent, DependencyNotification pkg))
942957
$ dependencyUpdateEmails
958+
, flip mapMaybe notifications $ \(uid, notif) ->
959+
fmap (uid,) $ renderNotification notif
943960
]
944961
in flip mapMaybe (Map.toList emails) $ \((uid, group), emailContent) ->
945962
case uid `Map.lookup` userIdToDetails of
@@ -994,7 +1011,50 @@ getNotificationEmails
9941011
]
9951012
}
9961013

1014+
{----- Render notifications -----}
1015+
1016+
renderNotification :: Notification -> Maybe (EmailContent, NotificationGroup)
1017+
renderNotification = \case
1018+
NotifyNewVersion{..} ->
1019+
generalNotification $
1020+
renderNotifyNewVersion
1021+
notifyPackageInfo
1022+
NotifyNewRevision{..} ->
1023+
generalNotification $
1024+
renderNotifyNewRevision
1025+
notifyPackageId
1026+
notifyRevisions
1027+
where
1028+
generalNotification emailContent = Just (emailContent, GeneralNotification)
1029+
1030+
renderNotifyNewVersion pkg =
1031+
EmailContentParagraph $
1032+
"Package upload, " <> renderPkgLink (pkgInfoId pkg) <> ", by " <>
1033+
renderUserTime (pkgLatestUploadUser pkg) (pkgLatestUploadTime pkg)
1034+
1035+
renderNotifyNewRevision pkg revs =
1036+
EmailContentParagraph ("Package metadata revision(s), " <> renderPkgLink pkg <> ":")
1037+
<> EmailContentList (map (uncurry $ flip renderUserTime) $ sortOn (Down . fst) revs)
1038+
1039+
{----- Rendering helpers -----}
1040+
1041+
renderPkgLink pkg =
1042+
EmailContentLink
1043+
(T.pack $ display pkg)
1044+
serverBaseURI
1045+
{ uriPath = "/package/" <> display (packageName pkg) <> "-" <> display (packageVersion pkg)
1046+
}
1047+
1048+
renderUser = emailContentDisplay . Users.userIdToName allUsers
1049+
1050+
renderTime = emailContentStr . formatTime defaultTimeLocale "%c"
1051+
1052+
renderUserTime u t = renderUser u <> " [" <> renderTime t <> "]"
1053+
9971054
{----- Utilities -----}
9981055

9991056
fromSetM :: Monad m => (k -> m v) -> Set k -> m (Map k v)
10001057
fromSetM f = traverse id . Map.fromSet f
1058+
1059+
concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b]
1060+
concatMapM f = fmap concat . mapM f

0 commit comments

Comments
 (0)