#NEWLINE# def build_recipients( user , review_request , extra_recipients = None , limit_recipients_to = None ) : #NEWLINE# #INDENT# 'Build the recipient sets for an e-mail.\n\n    By default, the user sending the e-mail, the review request submitter (if\n    they are active), all active reviewers, and all active members of review\n    groups will be recipients of the e-mail.\n\n    If the ``limit_recipients_to`` parameter is provided, the given ``user``\n    and the review request submitter (if active) will still be recipients of\n    the e-mail, but all reviewers and members of review groups will not.\n    Instead, the recipients given in ``limit_recipients_to`` will be used.\n\n    Args:\n        user (django.contrib.auth.models.User):\n            The user sending the e-mail.\n\n        review_request (reviewboard.reviews.models.ReviewRequest):\n            The review request the e-mail corresponds to.\n\n        extra_recipients (list):\n            An optional list of extra recipients as\n            :py:class:`Users <django.contrib.auth.models.User>` and\n            :py:class:`Groups <reviewboard.reviews.models.Group>` that will\n            receive the e-mail.\n\n        limit_recipients_to (list):\n            An optional list of recipients as\n            :py:class:`Users <django.contrib.auth.models.User>` and\n            :py:class:`Groups <reviewboard.reviews.models.Group>` who will\n            receive the e-mail in place of the normal recipients.\n\n    Returns:\n        tuple: A 2-tuple of the To field and the CC field, as sets of\n        :py:class:`Users <django.contrib.auth.models.User>` and\n        :py:class:`Groups <reviewboard.reviews.models.Group>`.\n    ' #NEWLINE# recipients = set ( ) #NEWLINE# to_field = set ( ) #NEWLINE# local_site = review_request . local_site_id #NEWLINE# submitter = review_request . submitter #NEWLINE# target_people = review_request . target_people . filter ( is_active = True ) . extra ( select = { #NEWLINE# #INDENT# 'visibility' : '\n                SELECT accounts_reviewrequestvisit.visibility\n                  FROM accounts_reviewrequestvisit\n                 WHERE accounts_reviewrequestvisit.review_request_id =\n                       reviews_reviewrequest_target_people.reviewrequest_id\n                   AND accounts_reviewrequestvisit.user_id =\n                       reviews_reviewrequest_target_people.user_id\n            ' , #NEWLINE# #UNINDENT# } ) #NEWLINE# starred_users = User . objects . filter ( is_active = True , profile__starred_review_requests = review_request , profile__should_send_email = True ) #NEWLINE# local_site_q = Q ( ) #NEWLINE# if local_site : #NEWLINE# #INDENT# local_site_q = ( Q ( local_site = local_site ) | Q ( local_site_admins = local_site ) ) #NEWLINE# target_people = target_people . filter ( local_site_q ) #NEWLINE# starred_users = starred_users . filter ( local_site_q ) #NEWLINE# #UNINDENT# if ( not extra_recipients ) : #NEWLINE# #INDENT# extra_recipients = User . objects . none ( ) #NEWLINE# #UNINDENT# if user . should_send_email ( ) : #NEWLINE# #INDENT# recipients . add ( user ) #NEWLINE# #UNINDENT# try : #NEWLINE# #INDENT# changedesc = review_request . changedescs . latest ( ) #NEWLINE# #UNINDENT# except ChangeDescription . DoesNotExist : #NEWLINE# #INDENT# pass #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if changedesc . fields_changed : #NEWLINE# #INDENT# submitter_info = changedesc . fields_changed . get ( 'submitter' ) #NEWLINE# if submitter_info : #NEWLINE# #INDENT# prev_submitter_pk = submitter_info [ 'old' ] [ 0 ] [ 2 ] #NEWLINE# prev_submitter = User . objects . get ( pk = prev_submitter_pk ) #NEWLINE# if ( prev_submitter . is_active and prev_submitter . should_send_email ( ) ) : #NEWLINE# #INDENT# recipients . add ( prev_submitter ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# if ( submitter . is_active and submitter . should_send_email ( ) ) : #NEWLINE# #INDENT# recipients . add ( submitter ) #NEWLINE# #UNINDENT# recipients . update ( starred_users ) #NEWLINE# def _filter_recipients( to_filter ) : #NEWLINE# #INDENT# 'Filter the given recipients.\n\n        All groups will be added to the resulting recipients. Only users with a\n        matching local site will be added to the resulting recipients.\n\n        Args:\n            to_filter (list):\n                A list of recipients as\n                :py:class:`Users <django.contrib.auth.models.User>` and\n                :py:class:`Groups <reviewboard.reviews.models.Group>`.\n        ' #NEWLINE# pks = set ( ) #NEWLINE# for recipient in to_filter : #NEWLINE# #INDENT# if isinstance ( recipient , User ) : #NEWLINE# #INDENT# pks . add ( recipient . pk ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if isinstance ( recipient , Group ) : #NEWLINE# #INDENT# recipients . add ( recipient ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# logging . error ( 'Unexpected e-mail recipient %r; expected django.contrib.auth.models.User or reviewboard.reviews.models.Group.' , recipient ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# if pks : #NEWLINE# #INDENT# filtered_users = User . objects . filter ( Q ( is_active = True , pk__in = pks ) , local_site_q ) #NEWLINE# recipients . update ( ( recipient for recipient in filtered_users . select_related ( 'Profile' ) if recipient . should_send_email ( ) ) ) #NEWLINE# #UNINDENT# #UNINDENT# if ( limit_recipients_to is not None ) : #NEWLINE# #INDENT# _filter_recipients ( limit_recipients_to ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# _filter_recipients ( extra_recipients ) #NEWLINE# target_people = target_people . filter ( is_active = True ) #NEWLINE# to_field . update ( ( recipient for recipient in target_people . select_related ( 'Profile' ) if ( recipient . should_send_email ( ) and ( local_site_q . visibility != ReviewRequestVisit . MUTED ) ) ) ) #NEWLINE# recipients . update ( to_field ) #NEWLINE# recipients . update ( review_request . target_groups . all ( ) ) #NEWLINE# #UNINDENT# if ( not user . should_send_own_updates ( ) ) : #NEWLINE# #INDENT# recipients . discard ( user ) #NEWLINE# to_field . discard ( user ) #NEWLINE# #UNINDENT# if to_field : #NEWLINE# #INDENT# cc_field = recipients . symmetric_difference ( to_field ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# to_field = recipients #NEWLINE# cc_field = set ( ) #NEWLINE# #UNINDENT# return ( to_field , cc_field )