def build_recipients(user, review_request, extra_recipients=None,
                     limit_recipients_to=None):
    recipients = set()
    to_field = set()

    local_site = review_request.local_site_id
    submitter = review_request.submitter

    target_people = review_request.target_people.filter(is_active=True).extra(
        select={
            'visibility': """
                SELECT accounts_reviewrequestvisit.visibility
                  FROM accounts_reviewrequestvisit
                 WHERE accounts_reviewrequestvisit.review_request_id =
                       reviews_reviewrequest_target_people.reviewrequest_id
                   AND accounts_reviewrequestvisit.user_id =
                       reviews_reviewrequest_target_people.user_id
            """
        })

    starred_users = User.objects.filter(
        is_active=True,
        profile__starred_review_requests=review_request,
        profile__should_send_email=True)

    local_site_q = Q()

    if local_site:
        # Filter out users who are on the reviewer list in some form or have
        # starred the review request but are no longer part of the LocalSite.
        local_site_q = (Q(local_site=local_site) |
                        Q(local_site_admins=local_site))

        target_people = target_people.filter(local_site_q)

        starred_users = starred_users.filter(local_site_q)

    if not extra_recipients:
        extra_recipients = User.objects.none()

    if user.should_send_email():
        recipients.add(user)

    try:
        changedesc = review_request.changedescs.latest()
    except ChangeDescription.DoesNotExist:
        pass
    else:
        # If the submitter has changed and the person sending this e-mail is
        # not the original submitter, then we should include them in the list
        # of recipients.
        if changedesc.fields_changed:
            submitter_info = changedesc.fields_changed.get('submitter')

            if submitter_info:
                prev_submitter_pk = submitter_info['old'][0][2]
                prev_submitter = User.objects.get(pk=prev_submitter_pk)

                if (prev_submitter.is_active and
                    prev_submitter.should_send_email()):
                    recipients.add(prev_submitter)

    if submitter.is_active and submitter.should_send_email():
        recipients.add(submitter)

    recipients.update(starred_users)

    def _filter_recipients(to_filter):
        """Filter the given recipients.

        All groups will be added to the resulting recipients. Only users with a
        matching local site will be added to the resulting recipients.

        Args:
            to_filter (list):
                A list of recipients as
                :py:class:`Users <django.contrib.auth.models.User>` and
                :py:class:`Groups <reviewboard.reviews.models.Group>`.
        """
        pks = set()

        for recipient in to_filter:
            if isinstance(recipient, User):
                pks.add(recipient.pk)
            elif isinstance(recipient, Group):
                recipients.add(recipient)
            else:
                logging.error(
                    'Unexpected e-mail recipient %r; expected '
                    'django.contrib.auth.models.User or '
                    'reviewboard.reviews.models.Group.',
                    recipient)
        if pks:
            filtered_users = User.objects.filter(
                Q(is_active=True, pk__in=pks),
                local_site_q)

            recipients.update(
                recipient
                for recipient in filtered_users.select_related('Profile')
                if recipient.should_send_email()
            )

    if limit_recipients_to is not None:
        _filter_recipients(limit_recipients_to)
    else:
        _filter_recipients(extra_recipients)

        target_people = target_people.filter(is_active=True)

        to_field.update(
            recipient
            for recipient in target_people.select_related('Profile')
            if (recipient.should_send_email() and
                recipient.visibility != ReviewRequestVisit.MUTED)
        )

        recipients.update(to_field)
        recipients.update(review_request.target_groups.all())

    if not user.should_send_own_updates():
        recipients.discard(user)
        to_field.discard(user)

    if to_field:
        cc_field = recipients.symmetric_difference(to_field)
    else:
        to_field = recipients
        cc_field = set()

    return to_field, cc_field
Build the recipient sets for an e-mail.
dataset/ETHPy150Open reviewboard/reviewboard/reviewboard/notifications/email.py/build_recipients