<s> import dbutils <EOL> import gitutils <EOL> from dbutils import * <EOL> from itertools import izip , repeat , chain <EOL> import htmlutils <EOL> import configuration <EOL> import mail <EOL> import diff <EOL> import changeset . utils as changeset_utils <EOL> import changeset . load as changeset_load <EOL> import reviewing . comment <EOL> import reviewing . filters <EOL> import log . commitset as log_commitset <EOL> import extensions . role . filterhook <EOL> from operation import OperationError , OperationFailure <EOL> from filters import Filters <EOL> def getFileIdsFromChangesets ( changesets ) : <EOL> file_ids = set ( ) <EOL> for changeset in changesets : <EOL> file_ids . update ( changed_file . id for changed_file in changeset . files ) <EOL> return file_ids <EOL> def getReviewersAndWatchers ( db , repository , commits = None , changesets = None , reviewfilters = None , <EOL> applyfilters = True , applyparentfilters = False ) : <EOL> """<STR_LIT>""" <EOL> if changesets is None : <EOL> changesets = [ ] <EOL> changeset_utils . createChangesets ( db , repository , commits ) <EOL> for commit in commits : <EOL> changesets . extend ( changeset_utils . createChangeset ( db , None , repository , commit , do_highlight = False ) ) <EOL> cursor = db . cursor ( ) <EOL> filters = Filters ( ) <EOL> filters . setFiles ( db , list ( getFileIdsFromChangesets ( changesets ) ) ) <EOL> if applyfilters : <EOL> filters . load ( db , repository = repository , recursive = applyparentfilters ) <EOL> if reviewfilters : <EOL> filters . addFilters ( reviewfilters ) <EOL> reviewers = { } <EOL> watchers = { } <EOL> for changeset in changesets : <EOL> author_user_ids = changeset . child . author . getUserIds ( db ) if changeset . child else set ( ) <EOL> cursor . execute ( "<STR_LIT>" , ( changeset . id , ) ) <EOL> for ( file_id , ) in cursor : <EOL> reviewers_found = False <EOL> for user_id , ( filter_type , delegate ) in filters . listUsers ( file_id ) . items ( ) : <EOL> if filter_type == '<STR_LIT>' : <EOL> if user_id not in author_user_ids : <EOL> reviewer_user_ids = [ user_id ] <EOL> elif delegate : <EOL> reviewer_user_ids = [ ] <EOL> for delegate_user_name in delegate . split ( "<STR_LIT:U+002C>" ) : <EOL> delegate_user = dbutils . User . fromName ( db , delegate_user_name ) <EOL> reviewer_user_ids . append ( delegate_user . id ) <EOL> else : <EOL> reviewer_user_ids = [ ] <EOL> for reviewer_user_id in reviewer_user_ids : <EOL> reviewers . setdefault ( file_id , { } ) . setdefault ( reviewer_user_id , set ( ) ) . add ( changeset . id ) <EOL> reviewers_found = True <EOL> else : <EOL> watchers . setdefault ( file_id , { } ) . setdefault ( user_id , set ( ) ) . add ( changeset . id ) <EOL> if not reviewers_found : <EOL> reviewers . setdefault ( file_id , { } ) . setdefault ( None , set ( ) ) . add ( changeset . id ) <EOL> return reviewers , watchers <EOL> def getReviewedReviewers ( db , review ) : <EOL> """<STR_LIT>""" <EOL> cursor = db . cursor ( ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( review . id , ) ) <EOL> reviewers = { } <EOL> for user_id , changeset_id , file_id in cursor . fetchall ( ) : <EOL> reviewers . setdefault ( file_id , { } ) . setdefault ( user_id , set ( ) ) . add ( changeset_id ) <EOL> return reviewers <EOL> def getPendingReviewers ( db , review ) : <EOL> """<STR_LIT>""" <EOL> cursor = db . cursor ( ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( review . id , ) ) <EOL> reviewers = { } <EOL> for user_id , changeset_id , file_id in cursor . fetchall ( ) : <EOL> reviewers . setdefault ( file_id , { } ) . setdefault ( user_id , set ( ) ) . add ( changeset_id ) <EOL> return reviewers <EOL> def collectReviewTeams ( reviewers ) : <EOL> """<STR_LIT>""" <EOL> teams = { } <EOL> for file_id , file_reviewers in reviewers . items ( ) : <EOL> if None in file_reviewers : <EOL> teams . setdefault ( None , set ( ) ) . add ( file_id ) <EOL> team = frozenset ( filter ( None , file_reviewers . keys ( ) ) ) <EOL> if team : teams . setdefault ( team , set ( ) ) . add ( file_id ) <EOL> return teams <EOL> def assignChanges ( db , user , review , commits = None , changesets = None , update = False ) : <EOL> cursor = db . cursor ( ) <EOL> if changesets is None : <EOL> assert commits is not None <EOL> changesets = [ ] <EOL> for commit in commits : <EOL> changesets . extend ( changeset_utils . createChangeset ( db , user , review . repository , commit ) ) <EOL> applyfilters = review . applyfilters <EOL> applyparentfilters = review . applyparentfilters <EOL> reviewers , watchers = getReviewersAndWatchers ( db , review . repository , changesets = changesets , reviewfilters = review . getReviewFilters ( db ) , <EOL> applyfilters = applyfilters , applyparentfilters = applyparentfilters ) <EOL> cursor . execute ( "<STR_LIT>" , ( review . id , ) ) <EOL> reviewusers = set ( [ user_id for ( user_id , ) in cursor ] ) <EOL> reviewusers_values = set ( ) <EOL> reviewuserfiles_values = set ( ) <EOL> reviewuserfiles_existing = { } <EOL> if update : <EOL> cursor . execute ( """<STR_LIT>""" , ( review . id , ) ) <EOL> for user_id , changeset_id , file_id in cursor : <EOL> reviewuserfiles_existing [ ( user_id , changeset_id , file_id ) ] = True <EOL> new_reviewers = set ( ) <EOL> new_watchers = set ( ) <EOL> cursor . execute ( """<STR_LIT>""" , ( review . id , ) ) <EOL> old_reviewers = set ( [ user_id for ( user_id , ) in cursor ] ) <EOL> for file_id , file_users in reviewers . items ( ) : <EOL> for user_id , user_changesets in file_users . items ( ) : <EOL> if user_id : <EOL> new_reviewers . add ( user_id ) <EOL> if user_id not in reviewusers : <EOL> reviewusers . add ( user_id ) <EOL> reviewusers_values . add ( ( review . id , user_id ) ) <EOL> for changeset_id in user_changesets : <EOL> if ( user_id , changeset_id , file_id ) not in reviewuserfiles_existing : <EOL> reviewuserfiles_values . add ( ( user_id , review . id , changeset_id , file_id ) ) <EOL> for file_id , file_users in watchers . items ( ) : <EOL> for user_id , user_changesets in file_users . items ( ) : <EOL> if user_id : <EOL> if user_id not in reviewusers : <EOL> new_watchers . add ( user_id ) <EOL> reviewusers . add ( user_id ) <EOL> reviewusers_values . add ( ( review . id , user_id ) ) <EOL> new_reviewers -= old_reviewers <EOL> new_watchers -= old_reviewers | new_reviewers <EOL> cursor . executemany ( "<STR_LIT>" , reviewusers_values ) <EOL> cursor . executemany ( "<STR_LIT>" , reviewuserfiles_values ) <EOL> if configuration . extensions . ENABLED : <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( review . repository . id , ) ) <EOL> rows = cursor . fetchall ( ) <EOL> if rows : <EOL> if commits is None : <EOL> commits = set ( ) <EOL> for changeset in changesets : <EOL> commits . add ( changeset . child ) <EOL> commits = list ( commits ) <EOL> filters = Filters ( ) <EOL> filters . setFiles ( db , list ( getFileIdsFromChangesets ( changesets ) ) ) <EOL> for filter_id , user_id , extension_id , path in rows : <EOL> filters . addFilter ( user_id , path , None , None , filter_id ) <EOL> for filter_id , file_ids in filters . matched_files . items ( ) : <EOL> extensions . role . filterhook . queueFilterHookEvent ( <EOL> db , filter_id , review , user , commits , file_ids ) <EOL> return new_reviewers , new_watchers <EOL> def createChangesetsForCommits ( db , commits , silent_if_empty = set ( ) , full_merges = set ( ) , replayed_rebases = { } ) : <EOL> repository = commits [ <NUM_LIT:0> ] . repository <EOL> changesets = [ ] <EOL> silent_commits = set ( ) <EOL> silent_changesets = set ( ) <EOL> simple_commits = [ ] <EOL> for commit in commits : <EOL> if commit not in full_merges and commit not in replayed_rebases : <EOL> simple_commits . append ( commit ) <EOL> if simple_commits : <EOL> changeset_utils . createChangesets ( db , repository , simple_commits ) <EOL> for commit in commits : <EOL> if commit in full_merges : <EOL> commit_changesets = changeset_utils . createFullMergeChangeset ( <EOL> db , user , repository , commit , do_highlight = False ) <EOL> elif commit in replayed_rebases : <EOL> commit_changesets = changeset_utils . createChangeset ( <EOL> db , user , repository , <EOL> from_commit = commit , to_commit = replayed_rebases [ commit ] , <EOL> conflicts = True , do_highlight = False ) <EOL> else : <EOL> commit_changesets = changeset_utils . createChangeset ( <EOL> db , user , repository , commit , do_highlight = False ) <EOL> if commit in silent_if_empty : <EOL> for commit_changeset in commit_changesets : <EOL> if commit_changeset . files : <EOL> break <EOL> else : <EOL> silent_commits . add ( commit ) <EOL> silent_changesets . update ( commit_changesets ) <EOL> changesets . extend ( commit_changesets ) <EOL> return changesets , silent_commits , silent_changesets <EOL> def addCommitsToReview ( db , user , review , commits , new_review = False , commitset = None , pending_mails = None , silent_if_empty = set ( ) , full_merges = set ( ) , replayed_rebases = { } , tracked_branch = False ) : <EOL> cursor = db . cursor ( ) <EOL> if not new_review : <EOL> import index <EOL> new_commits = log_commitset . CommitSet ( commits ) <EOL> old_commits = log_commitset . CommitSet ( review . branch . getCommits ( db ) ) <EOL> merges = new_commits . getMerges ( ) <EOL> for merge in merges : <EOL> if not merge in new_commits : continue <EOL> tails = filter ( lambda sha1 : sha1 not in old_commits and sha1 not in merge . parents , new_commits . getTailsFrom ( merge ) ) <EOL> if tails : <EOL> if tracked_branch : <EOL> raise index . IndexException ( """<STR_LIT>""" % merge . sha1 [ : <NUM_LIT:8> ] ) <EOL> cursor . execute ( "<STR_LIT>" , ( review . id , user . id , merge . getId ( db ) ) ) <EOL> row = cursor . fetchone ( ) <EOL> if not row or not row [ <NUM_LIT:1> ] : <EOL> if not row : <EOL> cursor . execute ( "<STR_LIT>" , ( review . id , user . id , merge . getId ( db ) ) ) <EOL> confirmation_id = cursor . fetchone ( ) [ <NUM_LIT:0> ] <EOL> merged = set ( ) <EOL> for tail_sha1 in tails : <EOL> children = new_commits . getChildren ( tail_sha1 ) <EOL> while children : <EOL> child = children . pop ( ) <EOL> if child not in merged and new_commits . isAncestorOf ( child , merge ) : <EOL> merged . add ( child ) <EOL> children . update ( new_commits . getChildren ( child ) - merged ) <EOL> merged_values = [ ( confirmation_id , commit . getId ( db ) ) for commit in merged ] <EOL> cursor . executemany ( "<STR_LIT>" , merged_values ) <EOL> db . commit ( ) <EOL> else : <EOL> confirmation_id = row [ <NUM_LIT:0> ] <EOL> message = "<STR_LIT>" % merge . sha1 [ : <NUM_LIT:8> ] <EOL> for tail_sha1 in tails : <EOL> for parent_sha1 in merge . parents : <EOL> if parent_sha1 in new_commits : <EOL> parent = new_commits . get ( parent_sha1 ) <EOL> if tail_sha1 in new_commits . getTailsFrom ( parent ) : <EOL> message += "<STR_LIT>" % ( tail_sha1 [ : <NUM_LIT:8> ] , parent_sha1 [ : <NUM_LIT:8> ] ) <EOL> message += """<STR_LIT>""" % ( dbutils . getURLPrefix ( db , user ) , confirmation_id ) <EOL> raise index . IndexException ( message ) <EOL> elif row [ <NUM_LIT:2> ] is not None : <EOL> if row [ <NUM_LIT:2> ] == merge . getId ( db ) : <EOL> cursor . execute ( "<STR_LIT>" , <EOL> ( row [ <NUM_LIT:0> ] , ) ) <EOL> for ( merged_id , ) in cursor : <EOL> merged = gitutils . Commit . fromId ( db , review . repository , merged_id ) <EOL> if merged . sha1 in merge . parents : <EOL> new_commits = new_commits . without ( [ merged ] ) <EOL> break <EOL> else : <EOL> tail = gitutils . Commit . fromId ( db , review . repository , row [ <NUM_LIT:2> ] ) <EOL> cut = [ gitutils . Commit . fromSHA1 ( db , review . repository , sha1 ) <EOL> for sha1 in tail . parents if sha1 in new_commits ] <EOL> new_commits = new_commits . without ( cut ) <EOL> if commitset : <EOL> commitset &= set ( new_commits ) <EOL> commits = [ commit for commit in commits if commit in commitset ] <EOL> changesets , silent_commits , silent_changesets = createChangesetsForCommits ( db , commits , silent_if_empty , full_merges , replayed_rebases ) <EOL> if not new_review : <EOL> print "<STR_LIT>" % ( len ( commits ) , len ( commits ) > <NUM_LIT:1> and "<STR_LIT:s>" or "<STR_LIT>" , review . getURL ( db ) ) <EOL> reviewchangesets_values = [ ( review . id , changeset . id ) for changeset in changesets ] <EOL> cursor . executemany ( """<STR_LIT>""" , reviewchangesets_values ) <EOL> cursor . executemany ( """<STR_LIT>""" , <EOL> reviewchangesets_values ) <EOL> new_reviewers , new_watchers = assignChanges ( db , user , review , changesets = changesets ) <EOL> cursor . execute ( "<STR_LIT>" , ( review . id , ) ) <EOL> try : opt_out = cursor . fetchone ( ) [ <NUM_LIT:0> ] is True <EOL> except : opt_out = True <EOL> if not new_review : <EOL> for user_id in new_reviewers : <EOL> new_reviewuser = dbutils . User . fromId ( db , user_id ) <EOL> print "<STR_LIT>" % ( new_reviewuser . fullname , new_reviewuser . email ) <EOL> if opt_out : <EOL> cursor . execute ( "<STR_LIT>" , ( review . id , user_id ) ) <EOL> for user_id in new_watchers : <EOL> new_reviewuser = dbutils . User . fromId ( db , user_id ) <EOL> print "<STR_LIT>" % ( new_reviewuser . fullname , new_reviewuser . email ) <EOL> review . incrementSerial ( db ) <EOL> reviewing . comment . propagateCommentChains ( db , user , review , new_commits , replayed_rebases ) <EOL> if pending_mails is None : pending_mails = [ ] <EOL> notify_commits = filter ( lambda commit : commit not in silent_commits , commits ) <EOL> notify_changesets = filter ( lambda changeset : changeset not in silent_changesets , changesets ) <EOL> if not new_review and notify_changesets : <EOL> recipients = review . getRecipients ( db ) <EOL> for to_user in recipients : <EOL> pending_mails . extend ( mail . sendReviewAddedCommits ( <EOL> db , user , to_user , recipients , review , notify_commits , <EOL> notify_changesets , tracked_branch = tracked_branch ) ) <EOL> mail . sendPendingMails ( pending_mails ) <EOL> review . reviewers . extend ( [ User . fromId ( db , user_id ) for user_id in new_reviewers ] ) <EOL> for user_id in new_watchers : <EOL> review . watchers [ User . fromId ( db , user_id ) ] = "<STR_LIT>" <EOL> return True <EOL> def createReview ( db , user , repository , commits , branch_name , summary , description , from_branch_name = None , via_push = False , reviewfilters = None , applyfilters = True , applyparentfilters = False , recipientfilters = None ) : <EOL> cursor = db . cursor ( ) <EOL> if via_push : <EOL> applyparentfilters = bool ( user . getPreference ( db , '<STR_LIT>' ) ) <EOL> branch = dbutils . Branch . fromName ( db , repository , branch_name ) <EOL> if branch is not None : <EOL> raise OperationFailure ( <EOL> code = "<STR_LIT>" , <EOL> title = "<STR_LIT>" , <EOL> message = """<STR_LIT>""" <EOL> % ( htmlutils . htmlify ( branch_name ) , htmlutils . htmlify ( branch_name ) ) , <EOL> is_html = True ) <EOL> if not commits : <EOL> raise OperationFailure ( <EOL> code = "<STR_LIT>" , <EOL> title = "<STR_LIT>" , <EOL> message = "<STR_LIT>" ) <EOL> commitset = log_commitset . CommitSet ( commits ) <EOL> heads = commitset . getHeads ( ) <EOL> if len ( heads ) != <NUM_LIT:1> : <EOL> raise OperationFailure ( <EOL> code = "<STR_LIT>" , <EOL> title = "<STR_LIT>" , <EOL> message = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) ) <EOL> head = heads . pop ( ) <EOL> if len ( commitset . getTails ( ) ) != <NUM_LIT:1> : <EOL> tail_id = None <EOL> else : <EOL> tail_id = gitutils . Commit . fromSHA1 ( db , repository , commitset . getTails ( ) . pop ( ) ) . getId ( db ) <EOL> if not via_push : <EOL> try : <EOL> repository . createBranch ( branch_name , head . sha1 ) <EOL> except gitutils . GitCommandError as error : <EOL> raise OperationFailure ( <EOL> code = "<STR_LIT>" , <EOL> title = "<STR_LIT>" , <EOL> message = ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> % htmlutils . htmlify ( error . output ) ) , <EOL> is_html = True ) <EOL> createChangesetsForCommits ( db , commits ) <EOL> try : <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( repository . id , branch_name , head . getId ( db ) , tail_id ) ) <EOL> branch_id = cursor . fetchone ( ) [ <NUM_LIT:0> ] <EOL> reachable_values = [ ( branch_id , commit . getId ( db ) ) for commit in commits ] <EOL> cursor . executemany ( """<STR_LIT>""" , <EOL> reachable_values ) <EOL> from_branch_id = None <EOL> if from_branch_name is not None : <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( repository . id , from_branch_name ) ) <EOL> row = cursor . fetchone ( ) <EOL> if row : <EOL> from_branch_id = row [ <NUM_LIT:0> ] <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( branch_id , from_branch_id , <EOL> summary , description , <EOL> applyfilters , applyparentfilters ) ) <EOL> review = dbutils . Review . fromId ( db , cursor . fetchone ( ) [ <NUM_LIT:0> ] ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( review . id , user . id ) ) <EOL> if reviewfilters is not None : <EOL> cursor . executemany ( """<STR_LIT>""" , <EOL> [ ( review . id , filter_user_id , filter_path , filter_type , user . id ) <EOL> for filter_user_id , filter_path , filter_type , filter_delegate in reviewfilters ] ) <EOL> is_opt_in = False <EOL> if recipientfilters is not None : <EOL> cursor . executemany ( <EOL> """<STR_LIT>""" , <EOL> [ ( review . id , filter_user_id , filter_include ) <EOL> for filter_user_id , filter_include in recipientfilters ] ) <EOL> for filter_user_id , filter_include in recipientfilters : <EOL> if filter_user_id is None and not filter_include : <EOL> is_opt_in = True <EOL> addCommitsToReview ( db , user , review , commits , new_review = True ) <EOL> review = dbutils . Review . fromId ( db , review . id ) <EOL> pending_mails = [ ] <EOL> recipients = review . getRecipients ( db ) <EOL> for to_user in recipients : <EOL> pending_mails . extend ( mail . sendReviewCreated ( db , user , to_user , recipients , review ) ) <EOL> if not is_opt_in : <EOL> recipient_by_id = dict ( ( to_user . id , to_user ) for to_user in recipients ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( recipient_by_id . keys ( ) , repository . id , repository . id ) ) <EOL> user_settings = { } <EOL> has_filter_settings = False <EOL> for user_id , repository_id , filter_id , integer in cursor : <EOL> settings = user_settings . setdefault ( user_id , [ None , None , { } ] ) <EOL> value = bool ( integer ) <EOL> if repository_id is None and filter_id is None : <EOL> settings [ <NUM_LIT:0> ] = value <EOL> elif repository_id is not None : <EOL> settings [ <NUM_LIT:1> ] = value <EOL> else : <EOL> settings [ <NUM_LIT:2> ] [ filter_id ] = value <EOL> has_filter_settings = True <EOL> if has_filter_settings : <EOL> filters = Filters ( ) <EOL> filters . setFiles ( db , review = review ) <EOL> for user_id , ( global_default , repository_default , filter_settings ) in user_settings . items ( ) : <EOL> to_user = recipient_by_id [ user_id ] <EOL> opt_out = None <EOL> if repository_default is not None : <EOL> opt_out = repository_default <EOL> elif global_default is not None : <EOL> opt_out = global_default <EOL> if filter_settings : <EOL> filters . load ( db , review = review , user = to_user ) <EOL> active_filters = filters . getActiveFilters ( to_user ) <EOL> for filter_id in active_filters : <EOL> if filter_id is None : <EOL> continue <EOL> elif filter_id in filter_settings : <EOL> if not filter_settings [ filter_id ] : <EOL> opt_out = False <EOL> break <EOL> else : <EOL> break <EOL> else : <EOL> if None not in active_filters : <EOL> opt_out = True <EOL> if opt_out : <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( review . id , to_user . id ) ) <EOL> db . commit ( ) <EOL> mail . sendPendingMails ( pending_mails ) <EOL> return review <EOL> except : <EOL> if not via_push : <EOL> repository . run ( "<STR_LIT>" , "<STR_LIT>" , branch_name ) <EOL> raise <EOL> def getDraftItems ( db , user , review ) : <EOL> return "<STR_LIT>" % review . getDraftStatus ( db , user ) <EOL> def renderDraftItems ( db , user , review , target ) : <EOL> items = review . getDraftStatus ( db , user ) <EOL> target . addExternalStylesheet ( "<STR_LIT>" ) <EOL> target . addExternalScript ( "<STR_LIT>" ) <EOL> div = target . div ( id = '<STR_LIT>' ) <EOL> if any ( items . values ( ) ) : <EOL> div . span ( '<STR_LIT>' ) . text ( "<STR_LIT>" ) <EOL> approved = items . pop ( "<STR_LIT>" , None ) <EOL> if approved : <EOL> div . text ( '<STR_LIT:U+0020>' ) <EOL> div . span ( '<STR_LIT>' ) . text ( "<STR_LIT>" % ( approved , approved > <NUM_LIT:1> and "<STR_LIT:s>" or "<STR_LIT>" ) ) <EOL> if any ( items . values ( ) ) : div . text ( '<STR_LIT:U+002C>' ) <EOL> disapproved = items . pop ( "<STR_LIT>" , None ) <EOL> if disapproved : <EOL> div . text ( '<STR_LIT:U+0020>' ) <EOL> div . span ( '<STR_LIT>' ) . text ( "<STR_LIT>" % ( disapproved , disapproved > <NUM_LIT:1> and "<STR_LIT:s>" or "<STR_LIT>" ) ) <EOL> if any ( items . values ( ) ) : div . text ( '<STR_LIT:U+002C>' ) <EOL> approved = items . pop ( "<STR_LIT>" , None ) <EOL> if approved : <EOL> div . text ( '<STR_LIT:U+0020>' ) <EOL> div . span ( '<STR_LIT>' ) . text ( "<STR_LIT>" % ( approved , approved > <NUM_LIT:1> and "<STR_LIT:s>" or "<STR_LIT>" ) ) <EOL> if any ( items . values ( ) ) : div . text ( '<STR_LIT:U+002C>' ) <EOL> disapproved = items . pop ( "<STR_LIT>" , None ) <EOL> if disapproved : <EOL> div . text ( '<STR_LIT:U+0020>' ) <EOL> div . span ( '<STR_LIT>' ) . text ( "<STR_LIT>" % ( disapproved , disapproved > <NUM_LIT:1> and "<STR_LIT:s>" or "<STR_LIT>" ) ) <EOL> if any ( items . values ( ) ) : div . text ( '<STR_LIT:U+002C>' ) <EOL> comments = items . pop ( "<STR_LIT>" , None ) <EOL> if comments : <EOL> div . text ( '<STR_LIT:U+0020>' ) <EOL> div . span ( '<STR_LIT>' ) . text ( "<STR_LIT>" % ( comments , comments > <NUM_LIT:1> and "<STR_LIT:s>" or "<STR_LIT>" ) ) <EOL> if any ( items . values ( ) ) : div . text ( '<STR_LIT:U+002C>' ) <EOL> reopened = items . pop ( "<STR_LIT>" , None ) <EOL> if reopened : <EOL> div . text ( '<STR_LIT:U+0020>' ) <EOL> div . span ( '<STR_LIT>' ) . text ( "<STR_LIT>" % ( reopened , reopened > <NUM_LIT:1> and "<STR_LIT:s>" or "<STR_LIT>" ) ) <EOL> if any ( items . values ( ) ) : div . text ( '<STR_LIT:U+002C>' ) <EOL> closed = items . pop ( "<STR_LIT>" , None ) <EOL> if closed : <EOL> div . text ( '<STR_LIT:U+0020>' ) <EOL> div . span ( '<STR_LIT>' ) . text ( "<STR_LIT>" % ( closed , closed > <NUM_LIT:1> and "<STR_LIT:s>" or "<STR_LIT>" ) ) <EOL> if any ( items . values ( ) ) : div . text ( '<STR_LIT:U+002C>' ) <EOL> morphed = items . pop ( "<STR_LIT>" , None ) <EOL> if morphed : <EOL> div . text ( '<STR_LIT:U+0020>' ) <EOL> div . span ( '<STR_LIT>' ) . text ( "<STR_LIT>" % ( morphed , morphed > <NUM_LIT:1> and "<STR_LIT:s>" or "<STR_LIT>" ) ) <EOL> if any ( items . values ( ) ) : div . text ( '<STR_LIT:U+002C>' ) <EOL> div . text ( '<STR_LIT:U+0020>' ) <EOL> buttons = div . span ( "<STR_LIT>" ) <EOL> buttons . button ( onclick = '<STR_LIT>' ) . text ( "<STR_LIT>" ) <EOL> buttons . button ( onclick = '<STR_LIT>' ) . text ( "<STR_LIT>" ) <EOL> buttons . button ( onclick = '<STR_LIT>' ) . text ( "<STR_LIT>" ) <EOL> return True <EOL> else : <EOL> return False <EOL> def addReviewFilters ( db , creator , user , review , reviewer_paths , watcher_paths ) : <EOL> cursor = db . cursor ( ) <EOL> cursor . execute ( "<STR_LIT>" , ( review . id , creator . id ) ) <EOL> transaction_id = cursor . fetchone ( ) [ <NUM_LIT:0> ] <EOL> def add ( filter_type , paths ) : <EOL> for path in paths : <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( review . id , user . id , path ) ) <EOL> row = cursor . fetchone ( ) <EOL> if row : <EOL> old_filter_id , old_filter_type = row <EOL> if old_filter_type == filter_type : <EOL> continue <EOL> else : <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( old_filter_id , ) ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( transaction_id , user . id , path , old_filter_type ) ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( review . id , user . id , path , filter_type , creator . id ) ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( transaction_id , user . id , path , filter_type ) ) <EOL> add ( "<STR_LIT>" , reviewer_paths ) <EOL> add ( "<STR_LIT>" , watcher_paths ) <EOL> filters = Filters ( ) <EOL> filters . setFiles ( db , review = review ) <EOL> filters . load ( db , review = review , user = user ) <EOL> if user not in review . reviewers and user not in review . watchers and user not in review . owners : <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( review . id , user . id , ) ) <EOL> delete_files = set ( ) <EOL> insert_files = set ( ) <EOL> if watcher_paths : <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( review . id , user . id ) ) <EOL> for review_file_id , file_id in cursor : <EOL> if not filters . isReviewer ( user . id , file_id ) : <EOL> delete_files . add ( review_file_id ) <EOL> if reviewer_paths : <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( user . id , user . id , review . id ) ) <EOL> for review_file_id , file_id in cursor : <EOL> if filters . isReviewer ( user . id , file_id ) : <EOL> insert_files . add ( review_file_id ) <EOL> if delete_files : <EOL> cursor . executemany ( "<STR_LIT>" , <EOL> izip ( delete_files , repeat ( user . id ) ) ) <EOL> cursor . executemany ( "<STR_LIT>" , <EOL> izip ( repeat ( transaction_id ) , delete_files , repeat ( user . id ) ) ) <EOL> if insert_files : <EOL> cursor . executemany ( "<STR_LIT>" , <EOL> izip ( insert_files , repeat ( user . id ) ) ) <EOL> cursor . executemany ( "<STR_LIT>" , <EOL> izip ( repeat ( transaction_id ) , insert_files , repeat ( user . id ) ) ) <EOL> return generateMailsForAssignmentsTransaction ( db , transaction_id ) <EOL> def parseReviewFilters ( db , data ) : <EOL> reviewfilters = [ ] <EOL> for filter_data in data : <EOL> filter_user = dbutils . User . fromName ( db , filter_data [ "<STR_LIT:username>" ] ) <EOL> filter_type = filter_data [ "<STR_LIT:type>" ] <EOL> filter_path = reviewing . filters . sanitizePath ( filter_data [ "<STR_LIT:path>" ] ) <EOL> try : <EOL> reviewing . filters . validatePattern ( filter_path ) <EOL> except reviewing . filters . PatternError as error : <EOL> raise OperationFailure ( code = "<STR_LIT>" , <EOL> title = "<STR_LIT>" , <EOL> message = "<STR_LIT>" % error . message ) <EOL> reviewfilters . append ( ( filter_user . id , filter_path , filter_type , None ) ) <EOL> return reviewfilters <EOL> def parseRecipientFilters ( db , data ) : <EOL> mode = data . get ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> included = data . get ( "<STR_LIT>" , [ ] ) <EOL> excluded = data . get ( "<STR_LIT>" , [ ] ) <EOL> recipientfilters = [ ] <EOL> if mode == "<STR_LIT>" : <EOL> recipientfilters . append ( ( None , False ) ) <EOL> filter_usernames = included <EOL> filter_include = True <EOL> else : <EOL> filter_usernames = excluded <EOL> filter_include = False <EOL> for filter_username in filter_usernames : <EOL> filter_user = dbutils . User . fromName ( db , filter_username ) <EOL> if not filter_user : <EOL> raise OperationError ( "<STR_LIT>" % filter_username ) <EOL> recipientfilters . append ( ( filter_user . id , filter_include ) ) <EOL> return recipientfilters <EOL> def queryFilters ( db , user , review , globalfilters = False , parentfilters = False ) : <EOL> cursor = db . cursor ( ) <EOL> if globalfilters : <EOL> cursor . execute ( "<STR_LIT>" , ( review . id , ) ) <EOL> review . applyfilters = True <EOL> if parentfilters : <EOL> cursor . execute ( "<STR_LIT>" , ( review . id , ) ) <EOL> review . applyparentfilters = True <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( review . id , ) ) <EOL> changesets = [ diff . Changeset . fromId ( db , review . repository , changeset_id ) <EOL> for ( changeset_id , ) in cursor ] <EOL> changeset_load . loadChangesets ( <EOL> db , review . repository , changesets , load_chunks = False ) <EOL> return assignChanges ( db , user , review , changesets = changesets , update = True ) <EOL> def applyFilters ( db , user , review , globalfilters = False , parentfilters = False ) : <EOL> new_reviewers , new_watchers = queryFilters ( db , user , review , globalfilters , parentfilters ) <EOL> pending_mails = [ ] <EOL> cursor = db . cursor ( ) <EOL> for user_id in new_reviewers : <EOL> new_reviewer = dbutils . User . fromId ( db , user_id ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( review . id , user_id ) ) <EOL> pending_mails . extend ( mail . sendFiltersApplied ( <EOL> db , user , new_reviewer , review , globalfilters , parentfilters , cursor . fetchall ( ) ) ) <EOL> for user_id in new_watchers : <EOL> new_watcher = dbutils . User . fromId ( db , user_id ) <EOL> pending_mails . extend ( mail . sendFiltersApplied ( <EOL> db , user , new_watcher , review , globalfilters , parentfilters , None ) ) <EOL> review . incrementSerial ( db ) <EOL> db . commit ( ) <EOL> mail . sendPendingMails ( pending_mails ) <EOL> def generateMailsForBatch ( db , batch_id , was_accepted , is_accepted , profiler = None ) : <EOL> cursor = db . cursor ( ) <EOL> cursor . execute ( "<STR_LIT>" , ( batch_id , ) ) <EOL> review_id , user_id = cursor . fetchone ( ) <EOL> review = dbutils . Review . fromId ( db , review_id ) <EOL> from_user = dbutils . User . fromId ( db , user_id ) <EOL> pending_mails = [ ] <EOL> recipients = review . getRecipients ( db ) <EOL> for to_user in recipients : <EOL> pending_mails . extend ( mail . sendReviewBatch ( db , from_user , to_user , recipients , review , batch_id , was_accepted , is_accepted , profiler = profiler ) ) <EOL> return pending_mails <EOL> def generateMailsForAssignmentsTransaction ( db , transaction_id ) : <EOL> cursor = db . cursor ( ) <EOL> cursor . execute ( "<STR_LIT>" , ( transaction_id , ) ) <EOL> review_id , assigner_id , note = cursor . fetchone ( ) <EOL> review = dbutils . Review . fromId ( db , review_id ) <EOL> assigner = dbutils . User . fromId ( db , assigner_id ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( transaction_id , ) ) <EOL> by_user = { } <EOL> for reviewer_id , path , filter_type , created in cursor : <EOL> added_filters , removed_filters , unassigned , assigned = by_user . setdefault ( reviewer_id , ( [ ] , [ ] , [ ] , [ ] ) ) <EOL> if created : added_filters . append ( ( filter_type , path or "<STR_LIT:/>" ) ) <EOL> else : removed_filters . append ( ( filter_type , path or "<STR_LIT:/>" ) ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( transaction_id , ) ) <EOL> for reviewer_id , was_assigned , file_id , deleted , inserted in cursor : <EOL> added_filters , removed_filters , unassigned , assigned = by_user . setdefault ( reviewer_id , ( None , None , [ ] , [ ] ) ) <EOL> if was_assigned : assigned . append ( ( file_id , deleted , inserted ) ) <EOL> else : unassigned . append ( ( file_id , deleted , inserted ) ) <EOL> pending_mails = [ ] <EOL> for reviewer_id , ( added_filters , removed_filters , unassigned , assigned ) in by_user . items ( ) : <EOL> reviewer = dbutils . User . fromId ( db , reviewer_id ) <EOL> if assigner != reviewer : <EOL> pending_mails . extend ( mail . sendAssignmentsChanged ( db , assigner , reviewer , review , added_filters , removed_filters , unassigned , assigned ) ) <EOL> return pending_mails <EOL> def retireUser ( db , user ) : <EOL> cursor = db . cursor ( ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( user . id , ) ) <EOL> cursor . execute ( """<STR_LIT>""" , <EOL> ( user . id , ) ) </s>
