annotate svgsitemap/middleware.py @ 1:084088505eea

almost working
author Jeff Hammel <jhammel@mozilla.com>
date Tue, 28 Dec 2010 16:23:07 -0800
parents 7a60bacc6a22
children 30d03e830354
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
1 """
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
2 request dispatcher
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
3 """
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
4
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
5 __all__ = ['MapserverMiddleware', 'SVGSiteMap']
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
6
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
7 import os
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
8 import urlparse
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
9 from pygraphviz import AGraph
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
10 from webob import Request, Response, exc
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
11
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
12 class MapserverMiddleware(object):
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
13 """silly middleware to serve just the svg"""
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
14 def __init__(self, app, svgmap, path='/map'):
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
15 self.app = app
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
16 self.svgmap = svgmap
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
17 self.path = path
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
18
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
19 def __call__(self, environ, start_response):
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
20 request = Request(environ)
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
21 if request.path_info == self.path or not self.path:
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
22 if not os.path.exists(self.svgmap):
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
23 res = exc.HTTPNotFound()
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
24 return res(environ, start_response)
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
25 content = file(self.svgmap).read()
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
26 res = Response(content_type='image/svg+xml', body=content)
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
27 return res(environ, start_response)
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
28 return self.app(environ, start_response)
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
29
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
30
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
31 class SVGSiteMap(object):
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
32
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
33 ### class level variables
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
34 defaults = { 'name': '',
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
35 'hosts': '',
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
36 'external_referers': True,
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
37 'maxwidth': 20
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
38
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
39 # input/output
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
40 'file': None, # .ini file
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
41 'output': None, # .svg file
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
42
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
43 # graph attributes
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
44 'bgcolor': 'black',
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
45 'fontcolor': 'white',
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
46 'fontname': 'Helvetica',
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
47 'fontsize': '10.0',
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
48 'nodecolor': 'aqua',
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
49 'edgecolor': 'lime',
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
50 'shape': 'box',
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
51 'len': '1.3',
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
52 'arrowsize': '0.5',
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
53 }
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
54
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
55 def __init__(self, app, **kw):
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
56
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
57 # boilerplate
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
58 self.app = app
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
59 self.edges = {}
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
60 self.max = 0
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
61
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
62 # set attrs from defaults
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
63 for key in self.defaults:
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
64 setattr(self, key, kw.get(key, self.defaults[key]))
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
65
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
66 # sanity checks + data fixing
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
67 assert self.output, "Please give an output file"
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
68 assert self.file, "Cannot save file!"
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
69 if self.hosts:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
70 self.hosts = self.hosts.split()
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
71 else:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
72 self.hosts = []
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
73 if isinstance(self.external_referers, basestring):
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
74 self.external_referers = self.external_referers.lower() == 'true'
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
75
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
76 # open the graph
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
77 if os.path.exists(self.file):
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
78 self.graph = AGraph(self.file, name=self.name, splines=False, directed=True)
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
79 for edge in self.graph.edges():
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
80 count = int(edge.attr['label'])
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
81 self.edges[(edge[0], edge[1])] = count
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
82 if count > self.max:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
83 self.max = count
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
84 else:
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
85 self.graph = AGraph(name=self.name, splines=False, directed=True)
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
86
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
87 # make it pretty
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
88 self.graph.graph_attr['label'] = self.name
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
89 self.graph.graph_attr['fontname'] = self.fontname
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
90 self.graph.graph_attr['fontcolor'] = self.fontcolor
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
91 self.graph.graph_attr['bgcolor'] = self.bgcolor
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
92 self.graph.node_attr['color'] = self.nodecolor
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
93 self.graph.node_attr['fontcolor'] = self.fontcolor
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
94 self.graph.node_attr['fontname'] = self.fontname
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
95 self.graph.node_attr['fontsize'] = self.fontsize
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
96 self.graph.node_attr['shape'] = self.shape
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
97 self.graph.node_attr['width'] = '0.1'
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
98 self.graph.node_attr['height'] = '0.1'
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
99 self.graph.edge_attr['color'] = self.edgecolor
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
100 self.graph.edge_attr['fontcolor'] = self.fontcolor
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
101 self.graph.edge_attr['fontname'] = self.fontname
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
102 self.graph.edge_attr['fontsize'] = self.fontsize
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
103 self.graph.edge_attr['len'] = self.len
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
104 self.graph.edge_attr['arrowsize'] = self.arrowsize
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
105
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
106 def __call__(self, environ, start_response):
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
107 request = Request(environ)
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
108 if request.referer:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
109
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
110 # parse the URLs
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
111 parsed_referer = urlparse.urlsplit(request.referer)
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
112 parsed_referee = urlparse.urlsplit(request.url)
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
113 islocal = False
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
114
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
115 # see if its local or not
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
116 localhosts = self.hosts[:]
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
117 if parsed_referee.hostname not in localhosts:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
118 localhosts.append(parsed_referee.hostname)
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
119 for host in localhosts:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
120 if parsed_referer.hostname == host or parsed_referer.hostname.endswith('.' + host):
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
121 islocal = True
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
122 break
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
123
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
124 # make the connection
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
125 if islocal:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
126 self.add(parsed_referer.path, parsed_referee.path)
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
127 else:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
128 if self.external_referers:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
129 self.add(request.referer, parsed_referee.path)
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
130
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
131 return self.app(environ, start_response)
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
132
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
133 def add(self, from_url, to_url):
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
134 """add a conncection in the graph"""
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
135
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
136 if from_url == to_url:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
137 return # don't do self-references
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
138
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
139 if (from_url, to_url) in self.edges:
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
140 count = self.edges[(from_url, to_url)]
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
141 count += 1
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
142 if count > self.max:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
143 self.max = count
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
144 self.edges[(from_url, to_url)] = count
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
145 edge = self.graph.get_edge(from_url, to_url)
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
146 edge.attr['label'] = str(count)
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
147 width = self.maxwidth * (count / self.max)
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
148 if not width:
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
149 width = 1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
150 edge.attr['style'] = 'setlinewidth(%d)' % width
0
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
151 else:
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
152 self.edges[(from_url, to_url)] = 1
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
153 self.graph.add_edge(from_url, to_url, label='1')
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
154
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
155 for url in from_url, to_url:
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
156 node = self.graph.get_node(url)
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
157 node.attr['label'] = url
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
158 node.attr['href'] = url
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
159
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
160 if self.file:
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
161 self.graph.write(self.file)
7a60bacc6a22 initial commit
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
162 if self.output:
1
084088505eea almost working
Jeff Hammel <jhammel@mozilla.com>
parents: 0
diff changeset
163 self.graph.draw(self.output, prog='neato')