Skip to content

Instantly share code, notes, and snippets.

@un33k
Forked from jacobian/gen-generic-views.py
Created September 23, 2011 04:26
Show Gist options
  • Save un33k/1236741 to your computer and use it in GitHub Desktop.
Save un33k/1236741 to your computer and use it in GitHub Desktop.
import re
import inspect
import pygraphviz as pgv
from django.conf import settings; settings.configure()
from django.views import generic
class GenericViewGraph(pgv.AGraph):
_ignore_types = (None, object)
def __init__(self, *args, **kwargs):
kwargs['directed'] = kwargs.get('directed', True)
super(GenericViewGraph, self).__init__(*args, **kwargs)
self.graph_attr.update(
splines = True,
concentrate = True,
)
self.node_attr.update(
shape = 'none',
fontname = 'helvetica neue light',
fontsize = 8,
labeljust = 'r',
style = 'filled',
fillcolor = 'white',
)
self.edge_attr.update(
arrowhead = 'vee',
arrowsize = 0.7,
)
self.seen_nodes = set()
def add_view_class(self, cls, is_public=False):
if cls in self._ignore_types or cls in self.seen_nodes:
return
self.seen_nodes.add(cls)
for base in cls.__bases__:
if base in self._ignore_types:
continue
self.add_edge(base.__name__, cls.__name__)
self.add_view_class(base)
node = self.get_node(cls.__name__)
node.attr['label'] = self.format_class_label(cls, is_public)
if is_public:
node.attr['fontsize'] = 9
def format_class_label(self, cls, is_public):
properties = []
methods = []
el = escape_label
for (name, attr) in inspect.getmembers(cls):
# Skip private methods and attributes of parent classes
if name.startswith('_') or name not in cls.__dict__:
continue
if inspect.ismethod(attr):
argspec = inspect.formatargspec(*inspect.getargspec(attr))
methods.append('<FONT FACE="helvetica neue medium">%s</FONT>%s' % (name, el(argspec)))
else:
properties.append('<FONT FACE="helvetica neue medium">%s</FONT> = %s' % (name, el(self.format_property_value(attr))))
ms = '<BR/>'.join(methods)
ps = '<BR/>'.join(properties)
bgcolor = "#ffffaa" if is_public else "white"
tdbgcolor = "#ffff77" if is_public else "#cccccc"
rec = ('<TABLE BGCOLOR="%s" ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">'
'<TR><TD ALIGN="CENTER" BGCOLOR="%s"><FONT FACE="helvetica neue bold">%s</FONT></TD></TR>'
'<TR><TD ALIGN="LEFT" BALIGN="LEFT">%s</TD></TR>'
'<TR><TD ALIGN="LEFT" BALIGN="LEFT">%s</TD></TR>'
'</TABLE>'
) % (bgcolor, tdbgcolor, cls.__name__, ms, ps)
return "<%s>" % rec
def format_property_value(self, attr):
r = repr(attr)
if r.startswith('<class'):
r = attr.__name__
return r
def escape_label(txt):
return re.sub(r'([{}<>|])', r'\\\1', txt)
def main():
views = [getattr(generic, v) for v in dir(generic) if v.endswith('View') and v != 'View']
for v in views:
g = GenericViewGraph()
g.add_view_class(v, is_public=True)
g.layout('dot')
g.write('dot/%s.dot' % v.__name__)
g.draw('pdf/%s.pdf' % v.__name__)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment