def get_participants_for_release( projects: Iterable[Project], organization: Organization, user_ids: Set[int]) -> Mapping[ExternalProviders, Mapping[User, int]]: # Collect all users with verified emails on a team in the related projects. users = list( 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_users_by_parent( NotificationSettingTypes.DEPLOY, users=users, parent=organization, ) notification_settings_by_user = transform_to_notification_settings_by_user( notification_settings, users) # Map users to their setting value. Prioritize user/org specific, then # user default, then product default. users_to_reasons_by_provider: MutableMapping[ ExternalProviders, MutableMapping[User, int]] = defaultdict(dict) for user in users: notification_settings_by_scope = notification_settings_by_user.get( user, {}) values_by_provider = get_deploy_values_by_provider( notification_settings_by_scope, notification_providers()) for provider, value in values_by_provider.items(): reason_option = get_reason(user, value, user_ids) if reason_option: users_to_reasons_by_provider[provider][user] = reason_option return users_to_reasons_by_provider
def _get_setting_mapping_from_mapping( notification_settings_by_recipient: Mapping[ Team | User, Mapping[NotificationScopeType, Mapping[ExternalProviders, NotificationSettingOptionValues]], ], recipient: Team | User, type: NotificationSettingTypes, ) -> Mapping[ExternalProviders, NotificationSettingOptionValues]: """ XXX(CEO): may not respect granularity of a setting for Slack a setting for email but we'll worry about that later since we don't have a FE for it yet. """ from sentry.notifications.notify import notification_providers # Fill in with the fallback values. notification_setting_option = { provider: _get_notification_setting_default(provider, type) for provider in notification_providers() } notification_settings_mapping = notification_settings_by_recipient.get(recipient, {}) for scope in [NotificationScopeType.USER, NotificationScopeType.TEAM, get_scope_type(type)]: notification_setting_option.update(notification_settings_mapping.get(scope, {})) return notification_setting_option
def _get_setting_mapping_from_mapping( notification_settings_by_recipient: Mapping[ Union["Team", "User"], Mapping[NotificationScopeType, Mapping[ExternalProviders, NotificationSettingOptionValues]], ], recipient: Union["Team", "User"], type: NotificationSettingTypes, should_use_slack_automatic: bool = False, ) -> Mapping[ExternalProviders, NotificationSettingOptionValues]: # XXX(CEO): may not respect granularity of a setting for Slack a setting for email # but we'll worry about that later since we don't have a FE for it yet from sentry.notifications.notify import notification_providers specific_scope = get_scope_type(type) notification_settings_mapping = notification_settings_by_recipient.get(recipient) if notification_settings_mapping: notification_setting_option = ( notification_settings_mapping.get(specific_scope) or notification_settings_mapping.get(NotificationScopeType.USER) or notification_settings_mapping.get(NotificationScopeType.TEAM) ) if notification_setting_option: return notification_setting_option return { provider: _get_notification_setting_default( provider, type, should_use_slack_automatic=should_use_slack_automatic ) for provider in notification_providers() }
def test_get_deploy_values_by_provider_empty_settings(self): values_by_provider = get_values_by_provider_by_type( {}, notification_providers(), NotificationSettingTypes.DEPLOY ) assert values_by_provider == { ExternalProviders.EMAIL: NotificationSettingOptionValues.COMMITTED_ONLY, ExternalProviders.SLACK: NotificationSettingOptionValues.NEVER, }
def test_get_deploy_values_by_provider(self): notification_settings_by_scope = { NotificationScopeType.ORGANIZATION: { ExternalProviders.EMAIL: NotificationSettingOptionValues.COMMITTED_ONLY }, NotificationScopeType.USER: { ExternalProviders.EMAIL: NotificationSettingOptionValues.ALWAYS }, } values_by_provider = get_deploy_values_by_provider( notification_settings_by_scope, notification_providers()) assert values_by_provider == { ExternalProviders.EMAIL: NotificationSettingOptionValues.COMMITTED_ONLY, ExternalProviders.SLACK: NotificationSettingOptionValues.COMMITTED_ONLY, }
def get_notification_providers(self) -> Iterable[ExternalProviders]: # subclass this method to limit notifications to specific providers from sentry.notifications.notify import notification_providers return notification_providers()