|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
|
|
|
import logging
|
|
|
from collections import defaultdict
|
|
|
-from typing import TYPE_CHECKING, Any, Iterable, Mapping, MutableMapping, Sequence
|
|
|
+from typing import TYPE_CHECKING, Any, Iterable, Mapping, MutableMapping, Sequence, Union
|
|
|
|
|
|
from sentry import features
|
|
|
from sentry.models import (
|
|
@@ -20,6 +20,7 @@ from sentry.models import (
|
|
|
UserOption,
|
|
|
)
|
|
|
from sentry.notifications.helpers import (
|
|
|
+ get_scope_type,
|
|
|
get_settings_by_provider,
|
|
|
get_values_by_provider_by_type,
|
|
|
transform_to_notification_settings_by_recipient,
|
|
@@ -85,34 +86,51 @@ def get_participants_for_group(
|
|
|
return participants_by_provider
|
|
|
|
|
|
|
|
|
-def get_reason(
|
|
|
- user: User, value: NotificationSettingOptionValues, user_ids: set[int]
|
|
|
-) -> int | None:
|
|
|
- # Members who opt into all deploy emails.
|
|
|
- if value == NotificationSettingOptionValues.ALWAYS:
|
|
|
- return GroupSubscriptionReason.deploy_setting
|
|
|
+ProviderNotificationValues = Mapping[ExternalProviders, NotificationSettingOptionValues]
|
|
|
|
|
|
- # Members which have been seen in the commit log.
|
|
|
- elif value == NotificationSettingOptionValues.COMMITTED_ONLY and user.id in user_ids:
|
|
|
- return GroupSubscriptionReason.committed
|
|
|
- return None
|
|
|
+ScopedProviderNotificationValues = Mapping[NotificationScopeType, ProviderNotificationValues]
|
|
|
+
|
|
|
+RecipientScopedProviderNotificationValues = Mapping[
|
|
|
+ Union[Team, User], ScopedProviderNotificationValues
|
|
|
+]
|
|
|
|
|
|
|
|
|
def get_participants_for_release(
|
|
|
- projects: Iterable[Project], organization: Organization, user_ids: set[int]
|
|
|
+ projects: Iterable[Project],
|
|
|
+ organization: Organization,
|
|
|
+ user_ids: set[int],
|
|
|
+ notification_setting_type: NotificationSettingTypes = NotificationSettingTypes.DEPLOY,
|
|
|
) -> Mapping[ExternalProviders, Mapping[Team | User, int]]:
|
|
|
# Collect all users with verified emails on a team in the related projects.
|
|
|
users = set(User.objects.get_team_members_with_verified_email_for_projects(projects))
|
|
|
|
|
|
- # Get all the involved users' settings for deploy-emails (including
|
|
|
- # users' organization-independent settings.)
|
|
|
- notification_settings = NotificationSetting.objects.get_for_recipient_by_parent(
|
|
|
- NotificationSettingTypes.DEPLOY,
|
|
|
- recipients=users,
|
|
|
- parent=organization,
|
|
|
- )
|
|
|
- notification_settings_by_recipient = transform_to_notification_settings_by_recipient(
|
|
|
- notification_settings, users
|
|
|
+ parent_specific_scope_type = get_scope_type(notification_setting_type)
|
|
|
+
|
|
|
+ def parent_notification_settings_by_recipient(
|
|
|
+ setting_type: NotificationSettingTypes,
|
|
|
+ parent: Iterable[Union[Project, Organization]],
|
|
|
+ recipients: Iterable[Team | User],
|
|
|
+ ) -> RecipientScopedProviderNotificationValues:
|
|
|
+ by_recipient: MutableMapping[Team | User, ScopedProviderNotificationValues] = {}
|
|
|
+ for project_or_org in parent:
|
|
|
+ notification_settings = NotificationSetting.objects.get_for_recipient_by_parent(
|
|
|
+ setting_type,
|
|
|
+ recipients=recipients,
|
|
|
+ parent=project_or_org,
|
|
|
+ )
|
|
|
+ by_recipient.update(
|
|
|
+ transform_to_notification_settings_by_recipient(notification_settings, recipients)
|
|
|
+ )
|
|
|
+ return by_recipient
|
|
|
+
|
|
|
+ # Get all the involved users' settings for deploy-emails or active-release emails
|
|
|
+ # (including users' organization-independent settings.)
|
|
|
+ notification_settings_by_recipient = (
|
|
|
+ parent_notification_settings_by_recipient(notification_setting_type, projects, users)
|
|
|
+ if parent_specific_scope_type == NotificationScopeType.PROJECT
|
|
|
+ else parent_notification_settings_by_recipient(
|
|
|
+ notification_setting_type, [organization], users
|
|
|
+ )
|
|
|
)
|
|
|
|
|
|
# Map users to their setting value. Prioritize user/org specific, then
|
|
@@ -120,16 +138,38 @@ def get_participants_for_release(
|
|
|
users_to_reasons_by_provider: MutableMapping[
|
|
|
ExternalProviders, MutableMapping[Team | User, int]
|
|
|
] = defaultdict(dict)
|
|
|
+
|
|
|
+ def get_reason(
|
|
|
+ user: User,
|
|
|
+ value: NotificationSettingOptionValues,
|
|
|
+ user_ids: set[int],
|
|
|
+ notification_setting_type: NotificationSettingTypes,
|
|
|
+ ) -> int | None:
|
|
|
+ if notification_setting_type == NotificationSettingTypes.DEPLOY:
|
|
|
+ # Members who opt into all deploy emails.
|
|
|
+ if value == NotificationSettingOptionValues.ALWAYS:
|
|
|
+ return GroupSubscriptionReason.deploy_setting
|
|
|
+
|
|
|
+ # Members which have been seen in the commit log.
|
|
|
+ elif value == NotificationSettingOptionValues.COMMITTED_ONLY and user.id in user_ids:
|
|
|
+ return GroupSubscriptionReason.committed
|
|
|
+ elif notification_setting_type == NotificationSettingTypes.ACTIVE_RELEASE:
|
|
|
+ if value == NotificationSettingOptionValues.ALWAYS:
|
|
|
+ # user must be a committer and a part of this release
|
|
|
+ return GroupSubscriptionReason.committed
|
|
|
+
|
|
|
+ return None
|
|
|
+
|
|
|
for user in users:
|
|
|
notification_settings_by_scope = notification_settings_by_recipient.get(user, {})
|
|
|
values_by_provider = get_values_by_provider_by_type(
|
|
|
notification_settings_by_scope,
|
|
|
notification_providers(),
|
|
|
- NotificationSettingTypes.DEPLOY,
|
|
|
+ notification_setting_type,
|
|
|
user,
|
|
|
)
|
|
|
for provider, value in values_by_provider.items():
|
|
|
- reason_option = get_reason(user, value, user_ids)
|
|
|
+ reason_option = get_reason(user, value, user_ids, notification_setting_type)
|
|
|
if reason_option:
|
|
|
users_to_reasons_by_provider[provider][user] = reason_option
|
|
|
return users_to_reasons_by_provider
|