00001
00002 """
00003
00004 This is the Runner Class. It should inherit from the PresidenceStack to allow for operators.
00005 Unless this is not in the given task.
00006
00007 """
00008
00009 __copyright__ = """
00010 Copyright 2008 Sean Ross-Ross
00011 """
00012 __license__ = """
00013 This file is part of SLIMpy .
00014
00015 SLIMpy is free software: you can redistribute it and/or modify
00016 it under the terms of the GNU Lesser General Public License as published by
00017 the Free Software Foundation, either version 3 of the License, or
00018 (at your option) any later version.
00019
00020 SLIMpy is distributed in the hope that it will be useful,
00021 but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00023 GNU Lesser General Public License for more details.
00024
00025 You should have received a copy of the GNU Lesser General Public License
00026 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00027 """
00028 from string import Template
00029 from slimpy_base.Core.Runners.RunnerBase import Runner
00030
00031
00032
00033 subgraph = Template("""
00034 subgraph ${node}${proc} {
00035 label = "${node}: ${proc}";
00036 style= "dashed";
00037 color=black;
00038
00039 ${content}
00040 }
00041 """)
00042
00043 class dotRunner( Runner ):
00044 """
00045 prints a Graphvis dot file to stdout
00046 """
00047 type = "dot"
00048
00049 def __init__( self ,records=None):
00050 self.records = records
00051 Runner.__init__( self )
00052
00053 def set_graph(self, graph):
00054 self.counterC = 0
00055 self.counterD = 0
00056
00057 self.graph = graph
00058 self.dot = self.toDot( graph, name="SLIMpy", abr=True )
00059
00060 def run( self ):
00061 """
00062 run the current graph with targets
00063 """
00064
00065 print self.dot
00066
00067
00068 def printDot( self ):
00069 """
00070 returns self.dot
00071 """
00072 return self.dot
00073
00074 def toDot( self, graph, name='SLIMpy', abr=True ):
00075 """
00076 build string representation of graph in do form
00077 """
00078 start = 'digraph %s {\n' % name
00079 end = '\n}'
00080 datastr = 'node [shape = "ellipse",color=green];\n\n'
00081 commstr = 'node [shape = "box",color=red];\n\n'
00082 middle = "\n\n"
00083
00084 dataDict = {}
00085 commandDict = {}
00086 node_dict = {}
00087
00088 for u in graph:
00089 for v in graph.adj( u ):
00090
00091 key1,nodestru = self.nodeToString( u, dataDict, commandDict )
00092 key2,nodestrv = self.nodeToString( v, dataDict, commandDict )
00093
00094 self.add_to_node_dict(key1, key2, nodestru, nodestrv, node_dict)
00095
00096
00097 datastr += "\n".join( ['%(val)s [ label = "%(key)s" ]' %vars() for key, val in dataDict.items()] ) +"\n\n\n"
00098 commstr += "\n".join( ['%(val)s [ label = "%(key)s" ]' %vars() for key, val in commandDict.items()] ) + '\n\n\n'
00099
00100 middle = self.node_dict_to_str(node_dict)
00101
00102 return self.abbrige( start + datastr + commstr + middle + end, abr )
00103
00104 def abbrige( self, s, abr ):
00105 if abr:
00106 for item in self.env['slimvars']['abridgeMap'].items():
00107 s = s.replace( *item )
00108
00109 return s
00110
00111 def node_dict_to_str(self,nd):
00112
00113 result = ""
00114
00115 for key,val in nd.iteritems():
00116 if key == ('localhost',''):
00117 result += "\n".join(val)
00118 else:
00119 name,proc = key
00120 content = "\n".join(val)
00121 result += subgraph.substitute(node=name,
00122 proc=proc,
00123 content=content)
00124 return result
00125
00126 def add_to_node_dict(self,key1,key2,u,v,nd):
00127
00128 middle = '''%(u)s -> %(v)s; \n''' %vars()
00129
00130 globl = ('localhost','')
00131 if key1 and key2 and key1 == key2:
00132 lst = nd.setdefault( key1, [] )
00133 lst.append(middle)
00134 elif key1 or key2:
00135 key = key1 or key2
00136 lst = nd.setdefault( key, [] )
00137 lst.append(middle)
00138
00139 else:
00140 lst = nd.setdefault( globl, [] )
00141 lst.append(middle)
00142
00143 def nodeToString( self, node, dataDict, commandDict ):
00144 """
00145 function to work with data in the hashtable
00146 """
00147 table = self.env['table']
00148
00149 key = None
00150 if self.records:
00151
00152 for rec in self.records:
00153
00154 if rec.name == node:
00155 key = rec.node_info
00156 if isinstance( node, tuple ):
00157 nodes = [table[n] for n in node ]
00158 runnable = self.add( nodes )
00159 s = runnable.nice_str().replace( '"', "'" )
00160
00161 val = "c%d" %self.counterC
00162 if commandDict.has_key( s ):
00163 return key,commandDict[s]
00164 else:
00165 self.counterC+=1
00166 commandDict[s] = val
00167
00168 return key,val
00169
00170
00171 else:
00172 nodes = table[node]
00173
00174 s = str( nodes ).replace( '"', "'" )
00175
00176 val = "d%d" %self.counterD
00177
00178 if dataDict.has_key( s ):
00179 return key,dataDict[s]
00180 else:
00181 self.counterD+=1
00182 dataDict[s] = val
00183 return key,val
00184