changeset 6:a88a670c92d0

dont display things that you dont want
author Jeff Hammel <jhammel@mozilla.com>
date Tue, 28 Dec 2010 20:27:12 -0800
parents 65acb32e8dc3
children 145a4d85b37d
files svgsitemap/middleware.py
diffstat 1 files changed, 39 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/svgsitemap/middleware.py
+++ b/svgsitemap/middleware.py
@@ -1,16 +1,17 @@
 """
 request dispatcher
 """
 
 __all__ = ['MapserverMiddleware', 'SVGSiteMap']
 
 import os
 import urlparse
+from fnmatch import fnmatch
 from pygraphviz import AGraph
 from webob import Request, Response, exc
 
 class MapserverMiddleware(object):
     """silly middleware to serve just the svg"""
     def __init__(self, app, svgmap, path='/map'):
         self.app = app
         self.svgmap = svgmap
@@ -31,19 +32,20 @@ class MapserverMiddleware(object):
 class SVGSiteMap(object):
 
     ### class level variables
     defaults = { 'name': '',
                  'hosts': '',
                  'external_referers': True,
                  'maxwidth': 5,
                  'minwidth': '0.01',
+                 'excluded': '*.css *.js */static/* /css/* *.ico /backgrounds/*',
 
                  # input/output
-                 'file': None, # .ini file
+                 'file': None, # graphviz file
                  'output': None, # .svg file
 
                  # graph attributes
                  'bgcolor': 'black',
                  'fontcolor': 'white',
                  'fontname': 'Helvetica',
                  'fontsize': '10.0',
                  'nodecolor': 'aqua',
@@ -63,31 +65,42 @@ class SVGSiteMap(object):
         # set attrs from defaults
         for key in self.defaults:
             setattr(self, key, kw.get(key, self.defaults[key]))
 
         # sanity checks + data fixing
         assert self.output, "Please give an output file"
         assert self.file, "Cannot save file!"
         self.maxwidth = float(self.maxwidth)
+        if isinstance(self.excluded, basestring):
+            self.excluded = self.excluded.split()
         if self.hosts:
             self.hosts = self.hosts.split()
         else:
             self.hosts = []
         if isinstance(self.external_referers, basestring):
             self.external_referers = self.external_referers.lower() == 'true'
 
         # open the graph
         if os.path.exists(self.file):
             self.graph = AGraph(self.file, name=self.name, splines=False, directed=True)
             for edge in self.graph.edges():
+                if self.exclude(edge[0], edge[1]):
+                    self.graph.remove_edge(edge[0], edge[1])
+                    continue
                 count = int(edge.attr['label'])
                 self.edges[(edge[0], edge[1])] = count
                 if count > self.max:
                     self.max = count
+            for node in self.graph.nodes():
+                if not self.graph.neighbors(node) or self.exclude(node):
+                    self.graph.remove_node(node)
+            self.set_widths()
+            self.graph.write(self.file)
+            self.graph.draw(self.output, prog='neato')
         else:
             self.graph = AGraph(name=self.name, splines=False, directed=True)
 
         # make it pretty
         self.graph.graph_attr['name'] = self.name
         self.graph.graph_attr['label'] = self.name
         self.graph.graph_attr['fontname'] = self.fontname
         self.graph.graph_attr['fontcolor'] = self.fontcolor
@@ -133,38 +146,57 @@ class SVGSiteMap(object):
                     
         return self.app(environ, start_response)
 
     def add(self, from_url, to_url):
         """add a conncection in the graph"""
 
         if from_url == to_url:
             return # don't do self-references
+        if self.exclude(from_url, to_url):
+            return # ignore certain urls
         
         if (from_url, to_url) in self.edges:
             count = self.edges[(from_url, to_url)]
             count += 1
             if count > self.max:
                 self.max = count
             self.edges[(from_url, to_url)] = count
             edge = self.graph.get_edge(from_url, to_url)
             edge.attr['label'] =  str(count)
         else:
             self.edges[(from_url, to_url)] = 1
             self.max = 1
             self.graph.add_edge(from_url, to_url, label='1')
 
-        for edge in self.graph.edges():
-            count = self.edges[(edge[0], edge[1])]
-            width = self.maxwidth * count / self.max
-            if not width:
-                width = self.minwidth
-            edge.attr['style'] = 'setlinewidth(%s)' % width
+        if self.maxwidth:
+            self.set_widths()
 
         for url in from_url, to_url:
             node = self.graph.get_node(url)
             node.attr['label'] = url
             node.attr['href'] = url
 
         if self.file:
             self.graph.write(self.file)
         if self.output:
             self.graph.draw(self.output, prog='neato')
+
+    def exclude(self, *urls):
+        """tell whether the edge is excluded"""
+        for pattern in self.excluded:
+            for url in urls:
+                if fnmatch(url, pattern):
+                    return True
+        return False
+
+    def set_widths(self):
+        if self.maxwidth:
+            for edge in self.graph.edges():
+                count = self.edges[(edge[0], edge[1])]
+                width = self.maxwidth * count / self.max
+                if not width:
+                    width = self.minwidth
+                edge.attr['style'] = 'setlinewidth(%s)' % width
+
+        else:
+            for edge in self.graph.edges():
+                edge.attr['style'] = ''