1 # Statistiques SVG avec Python 2 # 3 # auteur : Frédéric Laurent 4 # http://www.opikanoba.org 5 6 import os 7 import os.path 8 import string 9 import webbrowser 10 import tempfile 11 import SVGdraw 12 13 XMAX=100 14 STEP=20 15 YMAX=100 16 BAR_THICKNESS= 20 17 SPACE= 10 18 19 class DirectoryExplorer: 20 def __init__(self): 21 self.svgURL=tempfile.gettempdir()+"result.svg" 22 self.infos = [] 23 self.totalSize = 0 24 self.rootSize=0 25 self.rootName=None 26 27 def tupleCmp(self, a,b): 28 (nameA, sizeA) = a 29 (nameB, sizeB) = b 30 return cmp(sizeB,sizeA) 31 32 def gatherSize(self, directory, level, deep=1): 33 listdir = os.listdir(directory) 34 filelist = filter(lambda f:os.path.isfile(os.path.join(directory, f)), listdir) 35 weight = sum([os.path.getsize(os.path.join(directory, name)) for name in filelist]) 36 subdir = filter(lambda f: os.path.isdir(os.path.join(directory, f)), listdir) 37 subdir_w = sum([self.gatherSize(os.path.join(directory,f),level,deep+1) for f in subdir]) 38 total = weight+subdir_w 39 if (deep<=level): 40 if (deep==1): 41 self.totalSize = total 42 self.rootSize = weight 43 self.rootName=directory 44 self.infos.append((directory,self.rootSize)) 45 else: 46 self.infos.append((directory,total)) 47 return total 48 49 def toSVG(self): 50 #modification du maximum en X : depend du nombre d'element 51 global XMAX 52 XMAX = len(self.infos)*(BAR_THICKNESS+SPACE) 53 # creation du document 54 doc=SVGdraw.drawing() 55 svg=SVGdraw.svg(None, '100%','100%') 56 57 # creation des patterns pour les axes et la grille 58 axeX = SVGdraw.pattern(id="axeX",width="20",height="10",patternUnits="userSpaceOnUse") 59 axeX.addElement(SVGdraw.path("M 0 0, L 0 10","none","black","0.25")) 60 axeX.addElement(SVGdraw.path("M 10 10, V 5","none","lightgray","0.25")) 61 axeY = SVGdraw.pattern(id="axeY",width="10",height="20",patternUnits="userSpaceOnUse") 62 axeY.addElement(SVGdraw.path("M 0 0, L 10 0","none","black","0.25")) 63 axeY.addElement(SVGdraw.path("M 5 10, L 10 10","none","lightgray","0.25")) 64 grid = SVGdraw.pattern(id="grid",width="10",height="10",patternUnits="userSpaceOnUse") 65 grid.addElement(SVGdraw.path("M 0 0, L 10 0, L 10 10,L 0 10, L 0 0","none","lightgray","0.25")) 66 67 defs=SVGdraw.defs() 68 defs.addElement(axeX) 69 defs.addElement(axeY) 70 defs.addElement(grid) 71 svg.addElement(defs) 72 73 group=SVGdraw.group(transform="translate(130,130) scale(1,-1)") 74 75 # dessin de la grille de fond 76 group.addElement(SVGdraw.rect(0,0,XMAX,YMAX,"url(#grid)","lightgray","0.25")) 77 78 # dessin des axes 79 group.addElement(SVGdraw.rect(0,-10,XMAX,10,"url(#axeX)")) 80 group.addElement(SVGdraw.rect(-10,0,10,YMAX,"url(#axeY)")) 81 group.addElement(SVGdraw.line(0,0,XMAX,0,"black",1)) 82 group.addElement(SVGdraw.line(0,0,0,YMAX,"black",1)) 83 # dessin des fleches des axes 84 group.addElement(SVGdraw.polygon([[-3,YMAX],[3,YMAX],[0,YMAX+10]], "black","white")) 85 group.addElement(SVGdraw.polygon([[XMAX,-3],[XMAX,3],[XMAX+10,0]], "black","white")) 86 87 textgroup=SVGdraw.group(transform="scale(1,-1)") 88 # graduations 89 for y in range(0,YMAX+STEP,STEP): 90 textgroup.addElement(SVGdraw.text(-STEP,y, str(y), 8, text_anchor="middle", transform="translate(0,%d)"%(-y*2))) 91 textgroup.addElement(SVGdraw.text(0,YMAX+SPACE, r"%", 8, transform="translate(0,%d)"%(-(YMAX+SPACE)*2))) 92 93 # ajout de la legende principale 94 legendText = "Repertoire %s - taille %.02f ko"%(self.rootName,float(self.totalSize/1024.0)) 95 textgroup.addElement(SVGdraw.text(XMAX,YMAX+3*SPACE, legendText,12, "verdana", 96 text_anchor="end", fill="darkblue",transform="translate(0,%d)"%(-(YMAX+3*SPACE)*2))) 97 98 group.addElement(textgroup) 99 100 # tri des elements selon la taille occupee 101 self.infos.sort(self.tupleCmp) 102 103 xincr=0 104 #self.infos 105 for (name,size) in self.infos: 106 # calcul du pourcentage de place occupe 107 pourcent = (100.0*float(size))/float(self.totalSize) 108 height=int(pourcent*YMAX/100); 109 # insertion du texte de l'emplacement sur le disque et de la taille occupee en Ko 110 legendText = "%s (%### ###.02f ko)"%(name,float(size/1024.0)) 111 legend = SVGdraw.text(xincr+BAR_THICKNESS/2, -10,legendText,8,"verdana",text_anchor="begin",fill="blue") 112 legend.attributes["transform"]="scale(1,-1) translate(0,20) rotate(45,%d,-10)"%(xincr+BAR_THICKNESS/2) 113 group.addElement(legend) 114 115 #insertion de la barre representant le pourcentage 116 group.addElement(SVGdraw.rect(xincr,0,BAR_THICKNESS, height,"green","black",opacity=0.5)) 117 118 #insertion de la taille en pourcentage a gauche de la barre 119 pourcentText=SVGdraw.text(xincr+BAR_THICKNESS/2, height+SPACE,"%02.01f%% "%pourcent,6, 120 "arial", text_anchor="middle", fill="black") 121 pourcentText.attributes["transform"]="scale(1,-1) translate(0,-%d)"%((height+SPACE)*2) 122 group.addElement(pourcentText) 123 # augmentation du l'abscisse en X 124 xincr = xincr+BAR_THICKNESS+SPACE 125 126 svg.addElement(group) 127 doc.setSVG(svg) 128 doc.toXml(self.svgURL) 129 130 if __name__=="__main__": 131 de = DirectoryExplorer() 132 de.gatherSize(r"c:\Python",2) 133 de.toSVG() 134 webbrowser.open(de.svgURL)