def diff_snapshots(self,snapshot_a,snapshot_b,save = True, diff=None):

        """
        Returns a list of
        """

        file_revisions_a = snapshot_a.file_revisions
        file_revisions_b = snapshot_b.file_revisions

        file_revisions_diff = diff_objects(file_revisions_a,
                                           file_revisions_b,
                                           file_revision_key,
                                           file_revision_comparator)

        #We just generate code objects and issues
        #for the modified file revisions, to save time when diffing.

        logger.debug("Generating list of modified file revisions...")
        modified_file_revisions_by_path = {}
        for fr_type in ('modified','added','deleted'):
            for fr in file_revisions_diff[fr_type]:
                if not fr.path in modified_file_revisions_by_path:
                    modified_file_revisions_by_path[fr.path] = fr

        logger.debug("Generating list of modified issues...")

        modified_file_revisions_a = [fr for fr in file_revisions_a
                                     if fr.path in modified_file_revisions_by_path]
        modified_file_revisions_b = [fr for fr in file_revisions_b
                                     if fr.path in modified_file_revisions_by_path]

        if modified_file_revisions_a:
            #to do: check the file revisions chunk-wise to avoid DB query errors
            issue_occurrences_a = self.project.backend.filter(IssueOccurrence,
                                         {
                                            'file_revision' : {'$in' : modified_file_revisions_a}
                                         },
                                      include = ('file_revision','issue'))
        else:
            issue_occurrences_a = []

        if modified_file_revisions_b:
            #to do: check the file revisions chunk-wise to avoid DB query errors
            issue_occurrences_b = self.project.backend.filter(IssueOccurrence,
                                           {
                                            'file_revision' : {'$in' : modified_file_revisions_b}
                                            },
                                      include = ('file_revision','issue'))
        else:
            issue_occurrences_b = []

        logger.debug("Diffing issues (%d in A, %d in B)" % (len(issue_occurrences_a),
                                                           len(issue_occurrences_b)))


        issue_occurrences_diff = diff_objects(issue_occurrences_a,
                                              issue_occurrences_b,
                                              issue_occurrence_key,
                                              issue_occurrence_comparator)

        logger.debug("Diffing summary...")
        summary_diff = self.diff_summaries(snapshot_a,snapshot_b)

        if diff is None:
            diff = Diff({'summary' : summary_diff,
                        'snapshot_a' : snapshot_a,
                        'project' : self.project,
                        'configuration' : self.project.configuration,
                        'snapshot_b' : snapshot_b})
            #we generate the hash value for this diff
            hasher = Hasher()
            hasher.add(diff.snapshot_a.hash)
            hasher.add(diff.snapshot_b.hash)
            diff.hash = hasher.digest.hexdigest()
        elif save:
            with self.project.backend.transaction():
                self.project.backend.filter(DiffFileRevision,{'diff' : diff}).delete()
                self.project.backend.filter(DiffIssueOccurrence,{'diff' : diff}).delete()
        if save:
            with self.project.backend.transaction():
                self.project.backend.save(diff)

        diff_file_revisions = []

        with self.project.backend.transaction():
            for key,file_revisions in file_revisions_diff.items():
                for file_revision in file_revisions:
                    hasher = Hasher()
                    hasher.add(file_revision.hash)
                    hasher.add(diff.hash)
                    hasher.add(key)
                    diff_file_revision = DiffFileRevision({
                                            'diff' : diff,
                                            'file_revision' : file_revision,
                                            'hash' : hasher.digest.hexdigest(),
                                            'key' : key})
                    if save:
                        self.project.backend.save(diff_file_revision)
                    diff_file_revisions.append(diff_file_revision)

        diff_issue_occurrences = []
        mapping = {'deleted' : 'fixed','added' : 'added'}
        with self.project.backend.transaction():
            for key,issue_occurrences in issue_occurrences_diff.items():
                if not key in mapping:
                    continue
                for issue_occurrence in issue_occurrences:
                    hasher = Hasher()
                    hasher.add(issue_occurrence.hash)
                    hasher.add(diff.hash)
                    hasher.add(mapping[key])
                    diff_issue_occurrence = DiffIssueOccurrence({
                            'diff' : diff,
                            'hash' : hasher.digest.hexdigest(),
                            'issue_occurrence' : issue_occurrence,
                            'key' : mapping[key]
                        })
                    if save:
                        self.project.backend.save(diff_issue_occurrence)
                    diff_issue_occurrences.append(diff_issue_occurrence)

        return diff,diff_file_revisions,diff_issue_occurrences
def diff_snapshots ( self , snapshot_a , snapshot_b , save = True , diff = None ) : file_revisions_a = snapshot_a . file_revisions file_revisions_b = snapshot_b . file_revisions file_revisions_diff = diff_objects ( file_revisions_a , file_revisions_b , file_revision_key , file_revision_comparator ) logger . debug ( "Generating list of modified file revisions..." ) modified_file_revisions_by_path = { } for fr_type in ( 'modified' , 'added' , 'deleted' ) : for fr in file_revisions_diff [ fr_type ] : if not fr . path in modified_file_revisions_by_path : modified_file_revisions_by_path [ fr . path ] = fr logger . debug ( "Generating list of modified issues..." ) modified_file_revisions_a = [ fr for fr in file_revisions_a if fr . path in modified_file_revisions_by_path ] modified_file_revisions_b = [ fr for fr in file_revisions_b if fr . path in modified_file_revisions_by_path ] if modified_file_revisions_a : issue_occurrences_a = self . project . backend . filter ( IssueOccurrence , { 'file_revision' : { '$in' : modified_file_revisions_a } } , include = ( 'file_revision' , 'issue' ) ) else : issue_occurrences_a = [ ] if modified_file_revisions_b : issue_occurrences_b = self . project . backend . filter ( IssueOccurrence , { 'file_revision' : { '$in' : modified_file_revisions_b } } , include = ( 'file_revision' , 'issue' ) ) else : issue_occurrences_b = [ ] logger . debug ( "Diffing issues (%d in A, %d in B)" % ( len ( issue_occurrences_a ) , len ( issue_occurrences_b ) ) ) issue_occurrences_diff = diff_objects ( issue_occurrences_a , issue_occurrences_b , issue_occurrence_key , issue_occurrence_comparator ) logger . debug ( "Diffing summary..." ) summary_diff = self . diff_summaries ( snapshot_a , snapshot_b ) if diff is None : diff = Diff ( { 'summary' : summary_diff , 'snapshot_a' : snapshot_a , 'project' : self . project , 'configuration' : self . project . configuration , 'snapshot_b' : snapshot_b } ) hasher = Hasher ( ) hasher . add ( diff . snapshot_a . hash ) hasher . add ( diff . snapshot_b . hash ) diff . hash = hasher . digest . hexdigest ( ) elif save : with self . project . backend . transaction ( ) : self . project . backend . filter ( DiffFileRevision , { 'diff' : diff } ) . delete ( ) self . project . backend . filter ( DiffIssueOccurrence , { 'diff' : diff } ) . delete ( ) if save : with self . project . backend . transaction ( ) : self . project . backend . save ( diff ) diff_file_revisions = [ ] with self . project . backend . transaction ( ) : for key , file_revisions in file_revisions_diff . items ( ) : for file_revision in file_revisions : hasher = Hasher ( ) hasher . add ( file_revision . hash ) hasher . add ( diff . hash ) hasher . add ( key ) diff_file_revision = DiffFileRevision ( { 'diff' : diff , 'file_revision' : file_revision , 'hash' : hasher . digest . hexdigest ( ) , 'key' : key } ) if save : self . project . backend . save ( diff_file_revision ) diff_file_revisions . append ( diff_file_revision ) diff_issue_occurrences = [ ] mapping = { 'deleted' : 'fixed' , 'added' : 'added' } with self . project . backend . transaction ( ) : for key , issue_occurrences in issue_occurrences_diff . items ( ) : if not key in mapping : continue for issue_occurrence in issue_occurrences : hasher = Hasher ( ) hasher . add ( issue_occurrence . hash ) hasher . add ( diff . hash ) hasher . add ( mapping [ key ] ) diff_issue_occurrence = DiffIssueOccurrence ( { 'diff' : diff , 'hash' : hasher . digest . hexdigest ( ) , 'issue_occurrence' : issue_occurrence , 'key' : mapping [ key ] } ) if save : self . project . backend . save ( diff_issue_occurrence ) diff_issue_occurrences . append ( diff_issue_occurrence ) return diff , diff_file_revisions , diff_issue_occurrences
Returns a list of