Exemple #1
0
 def initTreemapCanvas(self):
     self.tmcanvas = TreemapSquarified(self.pane, width='13i', height='8i')
     self.tmcanvas.config(bg='white')
     self.pane.config(bg='blue')
     self.pane.add(self.tmcanvas.frame)
     self.pane.paneconfigure(self.tmcanvas.frame,
                             sticky=Tkinter.N + Tkinter.S + Tkinter.E +
                             Tkinter.W)
     self.tooltip = TkCanvasToolTip(self.tmcanvas, follow=True)
Exemple #2
0
class CDDApp:
    def __init__(self, dirname, options):
        self.dirname=dirname
        self.options = options
        self.filelist = None
        self.matches = None
        self.dupsInFile = None

    def getFileList(self):
        if( self.filelist == None):
            if( self.options.pattern ==''):
                self.filelist = PreparePygmentsFileList(self.dirname)
            else:
                rawfilelist = GetDirFileList(self.dirname)
                self.filelist = fnmatch.filter(rawfilelist,self.options.pattern)
                
        return(self.filelist)

    def run(self):
        filelist = self.getFileList()        
        self.cdd = CodeDupDetect(filelist,self.options.minimum)
        self.PrintDuplicates()
        if self.options.report:
            self.cdd.html_output(self.options.report)
        if self.options.comments:
            self.cdd.insert_comments(self.dirname)
        
        if( self.options.treemap == True and self.foundMatches()):
            self.ShowDuplicatesTreemap()
            self.root.mainloop()        
    
    def PrintDuplicates(self):
        tm1 = datetime.datetime.now()
        with FileOrStdout(self.options.filename) as output:
            exactmatch = self.cdd.printmatches(output)
            tm2 = datetime.datetime.now()
            output.write("time to find matches - %s\n" %(tm2-tm1))

    def foundMatches(self):
        '''
        return true if there is atleast one match found.
        '''
        matches = self.getMatches()
        return( len(matches) > 0)
            
    def ShowDuplicatesTreemap(self):
        assert(self.foundMatches()==True)
        self.initTk()
        self.createTreemap()
        self.showDupListTree()
        
    def initTk(self):
        self.root = Tkinter.Tk()
        self.root.title("Code Duplication Treemap")
        self.pane = Tkinter.PanedWindow(self.root, orient=Tkinter.HORIZONTAL)
        self.pane.pack(fill=Tkinter.BOTH, expand=1)
        self.initDupListTree()
        self.initTreemap()
        
    def initDupListTree(self):
        frame = Tkinter.Frame(self.pane)
        self.duplisttree = createScrollableCanvas(frame, width='2i')
        self.pane.add(frame)
        self.pane.paneconfigure(frame, sticky=Tkinter.N+Tkinter.S+Tkinter.E+Tkinter.W)

    def initTreemap(self):
        self.tmcanvas = TreemapSquarified(self.pane,width='13i', height='8i',leafnodecb = self.tmLeafnodeCallback)
        self.tmcanvas.config(bg='white')
        self.pane.add(self.tmcanvas.frame)
        self.pane.paneconfigure(self.tmcanvas.frame, sticky=Tkinter.N+Tkinter.S+Tkinter.E+Tkinter.W)
        self.tooltip = TkCanvasToolTip(self.tmcanvas, follow=True)

    def getColormap(self,tmrootnode):
        clrmap = TMColorMap(minclr=(0,255,0),maxclr=(255,0,0))        
        minval = tmrootnode.minclr(CLR_PROP)
        maxval = tmrootnode.maxclr(CLR_PROP)
        clrmap.setlimits(minval,maxval, neutralval=3)
        return(clrmap)
        
    def createTreemap(self):
        tmrootnode = self.makeTree()
        clrmap = self.getColormap(tmrootnode)
        self.tmcanvas.set(tmcolormap=clrmap,sizeprop=SIZE_PROP,clrprop=CLR_PROP,upper=[1200,700])
        self.tmcanvas.drawTreemap(tmrootnode)
        self.tooltip.updatebindings()

    def getMatches(self):
        if( self.matches == None):
            exactmatches = self.cdd.findcopies()
            self.matches = sorted(exactmatches,reverse=True,key=lambda x:x.matchedlines)
        return(self.matches)
    
    def getMatchLcInfo(self):
        #get the line count information of the duplicates
        matches = self.getMatches()
        #convert the matches to dictionary of filename against the number of copied lines
        matchinfodict = dict()
        for matchset in matches:
            for match in matchset:
                fname = match.srcfile()
                lc = matchinfodict.get(fname, 0)
                matchinfodict[fname] = lc + match.getLineCount()
        return(matchinfodict)

    def getLcInfo(self):
        #get the line count information about the files
        filelist = self.getFileList()
        lcinfodict = dict()
        for fname in filelist:
            with open(fname, "r") as f:
                lines = f.readlines()
                lcinfodict[fname] = len(lines)
        return(lcinfodict)
    
    def makeTree(self):
        matchlcinfo = self.getMatchLcInfo()
        lcinfo = self.getLcInfo()        
        tmrootnode = TreemapNode("Duplication Map - ")
        for fname, lc in lcinfo.iteritems():
            namelist = fname.split(os.sep)
            node = tmrootnode.addChild(namelist)
            node.setProp(SIZE_PROP, lc)
            node.setProp(CLR_PROP, matchlcinfo.get(fname, 0))
            node.setProp('filename', fname)
        tmrootnode.MergeSingleChildNodes('/')
        return(tmrootnode)

    def getDupsInFile(self,fname):
        if( self.dupsInFile == None):
            matches = self.getMatches()
            self.dupsInFile = dict()
            for matchset in matches:
                for match in matchset:
                    fname = match.srcfile()
                    duplist = self.dupsInFile.get(fname, [])
                    duplist.append((match.getStartLine(), match.getLineCount()))
                    self.dupsInFile[fname] = duplist
        return(self.dupsInFile.get(fname, None))
                
        
    def showDupListTree(self):
        mtreeroot = DupTreeItem("Duplicate List")
        #Add the tree items for various categories like (1-10 lines, 10-100 lines, 101-500 lines, More than 500 lines"
        dup500_ = mtreeroot.addChildName("More than 500 lines")
        dup101_500 = mtreeroot.addChildName("101-500 lines")
        dup11_100 = mtreeroot.addChildName("11-100 lines")
        dup1_10 = mtreeroot.addChildName("upto 10 lines")
        
        matchid = 0
        matches = self.getMatches()
        for matchset in matches:
            matchid = matchid+1
            matchnode = DupTreeItem("")
            lc = 0
            for match in matchset:
                fname = match.srcfile()
                lc = max(lc, match.getLineCount())
                start = match.getStartLine()
                matchnode.addChildName("%s (line %d - %d)" % (fname, start, start+lc))
            
            matchnode.name = "Match %d (Lines : %d)" % (matchid, lc)
            
            if( lc > 0 and lc <= 10):
                dup1_10.addChild(matchnode)
            elif( lc >10 and lc <= 100):
                dup11_100.addChild(matchnode)
            elif( lc >100 and lc < 500):
                dup101_500.addChild(matchnode)
            else:
                dup500_.addChild(matchnode)        
        
        for child in mtreeroot.children:
            child.name = "%s (count : %d)" % (child.name, len(child.children))
        
        #now create a 'tree display"
        self.filetree = TreeNode(self.duplisttree, None, mtreeroot)
        self.filetree.update()
        self.filetree.expand()
        
    def tmLeafnodeCallback(self, node, tmcanvas, canvasid,lower,upper):
        '''
        draw the approx positions for the duplicates in 'dark brown' color on the
        canvas rectangles of that file.
        '''        
        width = upper[0]-lower[0]
        height = float(upper[1]-lower[1])
            
        if( width > 4 and height > 2):            
            fname = node.getProp('filename')
            assert(fname != None)
            dupsinfile = self.getDupsInFile(fname)
            #if dupsinfile is None, then there are no duplicates in file
            if( dupsinfile != None):
                fsize = float(node.getSize(SIZE_PROP))
                x = lower[0]
                y = lower[1]
                #show small magenta coloured strip of 4 pixels (rectwd) to represent the location
                #of duplication.
                rectwd = 4
                    
                for startline, linecount in dupsinfile:
                    rectht = int(height*(float(linecount)/fsize)+0.5)
                    if( rectht > 1):
                        rectstart = int(height*(float(startline)/fsize)+0.5)
                        #draw rectangle with 'magenta' color fill and no border (border width=0)
                        tmcanvas.create_rectangle(x+2, y+rectstart, x+rectwd+2, y+rectstart+rectht,
                                                  fill='magenta',width=0)
Exemple #3
0
 def initTreemap(self):
     self.tmcanvas = TreemapSquarified(self.pane,width='13i', height='8i',leafnodecb = self.tmLeafnodeCallback)
     self.tmcanvas.config(bg='white')
     self.pane.add(self.tmcanvas.frame)
     self.pane.paneconfigure(self.tmcanvas.frame, sticky=Tkinter.N+Tkinter.S+Tkinter.E+Tkinter.W)
     self.tooltip = TkCanvasToolTip(self.tmcanvas, follow=True)