25
25
#############################
26
26
# Work around bugs in pydot #
27
27
#############################
28
# Pydot can't handle names with - in it. We replace them.
28
## Pydot can't handle names with - in it. We replace them.
31
30
def _cleanup_str(s):
32
31
return s.replace('-', '')
35
33
class Subgraph(d.Subgraph):
37
34
def __init__(self, name, *args, **kwargs):
38
35
name = _cleanup_str(name)
39
36
d.Subgraph.__init__(self, name, *args, **kwargs)
42
38
class Node(d.Node):
44
39
def __init__(self, name, *args, **kwargs):
45
40
name = _cleanup_str(name)
46
41
d.Node.__init__(self, name, *args, **kwargs)
49
43
class Edge(d.Edge):
51
44
def __init__(self, first, second, *args, **kwargs):
52
45
first = _cleanup_str(first)
53
46
second = _cleanup_str(second)
54
47
d.Edge.__init__(self, first, second, *args, **kwargs)
57
49
class CleanedDot(d.Dot):
59
50
def get_node(self, name, *args, **kwargs):
60
51
name = _cleanup_str(name)
61
52
return d.Dot.get_node(self, name, *args, **kwargs)
96
85
costs = r"""<tr><td colspan="2"><table border="0px" cellspacing="0">"""
97
86
for ware, count in b.buildcost.items():
98
87
w = b.tribe.wares[ware]
99
costs += ('<tr><td border="0px">%s x </td><td border="0px"><img src="%s"/></td><td border="0px">%s</td></tr>' %
100
(count, w.image, w.descname))
88
costs += ('<tr><td border="0px">%s x </td><td border="0px"><img src="%s"/></td><td border="0px">%s</td></tr>' % (count, w.image, w.descname))
101
89
costs += r"""</table></td></tr>"""
102
90
if not b.buildcost:
107
label=(r"""<<TABLE border="1px" cellborder="0px" cellspacing="0px" cellpadding="0px">
95
label = (r"""<<TABLE border="1px" cellborder="0px" cellspacing="0px" cellpadding="0px">
108
96
<TR><TD><IMG SRC="%s"/></TD>
109
97
<TD valign="bottom">%s</TD>
111
99
<TR><TD align="left" colspan="2">%s</TD></TR>
113
</TABLE>>""" % (b.image, workers, b.descname, costs)).replace('\n', ''),
114
URL='../../buildings/%s/' % b.name,
101
</TABLE>>""" % (b.image, workers, b.descname, costs)).replace('\n',''),
102
URL = "../../buildings/%s/" % b.name,
103
fillcolor = "orange",
119
sg = Subgraph('%s_enhancements' % b.name,
120
ordering='out', rankdir='TB', rank='same')
107
sg = Subgraph("%s_enhancements" % b.name,
108
ordering = "out", rankdir="TB", rank="same")
121
109
if b.enhancement and not b.enhanced_building:
123
111
while cb.enhancement:
124
112
if limit_buildings == None or (cb.name in limit_buildings):
125
113
sg.add_node(Node(_cleanup_str(cb.name)))
126
114
if limit_buildings == None or (cb.enhancement in limit_buildings):
127
g.add_edge(Edge(cb.name, cb.enhancement, color='blue'))
115
g.add_edge(Edge(cb.name, cb.enhancement, color="blue"))
128
116
cb = b.tribe.buildings[cb.enhancement]
129
117
if limit_buildings == None or (cb.name in limit_buildings):
130
118
sg.add_node(Node(_cleanup_str(cb.name)))
136
125
if isinstance(b, (ProductionSite,)):
137
126
# for worker,c in b.workers:
138
127
# g.add_edge(Edge(worker, name, color="orange"))
140
129
for output in b.outputs:
141
130
if limit_outputs is None or output in limit_outputs:
142
g.add_edge(Edge(b.name, output, color='darkgreen'))
131
g.add_edge(Edge(b.name, output, color="darkgreen"))
144
133
for input_ in b.inputs:
145
134
if limit_inputs is None or input_ in limit_inputs:
146
g.add_edge(Edge(input_, b.name, color='#cd0000'))
135
g.add_edge(Edge(input_, b.name, color="#cd0000"))
150
139
def add_ware(g, w):
151
140
# Add the nice node
154
label=(r"""<<TABLE border="0px">
143
label = (r"""<<TABLE border="0px">
155
144
<TR><TD><IMG SRC="%s"/></TD></TR>
156
145
<TR><TD>%s</TD></TR>
157
146
</TABLE>>""") % (w.image, w.descname),
158
URL='../../wares/%s/' % (w.name),
147
URL = "../../wares/%s/" % (w.name),
148
fillcolor = "#dddddd",
166
154
def add_worker(g, w, as_recruit=False):
167
155
# Add the nice node
169
shape='octagon' if not as_recruit else 'ellipse',
170
label=(r"""<<TABLE border="0px">
157
shape = "octagon" if not as_recruit else "ellipse",
158
label = (r"""<<TABLE border="0px">
171
159
<TR><TD><IMG SRC="%s"/></TD>
173
161
</TABLE>>""") % (w.image, w.descname),
174
URL='../../workers/%s/' % w.name,
162
URL="../../workers/%s/" % w.name,
181
169
def make_graph(tribe_name):
183
tdir = mkdtemp(prefix='widelands-help')
171
tdir = mkdtemp(prefix="widelands-help")
185
json_directory = path.normpath(MEDIA_ROOT + '/map_object_info')
186
tribeinfo_file = open(path.normpath(
187
json_directory + '/tribe_' + tribe_name + '.json'), 'r')
173
json_directory = path.normpath(MEDIA_ROOT + "/map_object_info")
174
tribeinfo_file = open(path.normpath(json_directory + "/tribe_" + tribe_name + ".json"), "r")
188
175
tribeinfo = json.load(tribeinfo_file)
190
177
t = Tribe(tribeinfo, json_directory)
192
g = CleanedDot(concentrate='false', style='filled', bgcolor='white',
193
overlap='false', splines='true', rankdir='LR')
179
g = CleanedDot(concentrate="false", style="filled", bgcolor="white",
180
overlap="false", splines="true", rankdir="LR")
195
for name, w in t.wares.items():
182
for name,w in t.wares.items():
198
185
# for name,w in t.workers.items():
199
186
# add_worker(g, w)
201
for name, b in t.buildings.items():
188
for name,b in t.buildings.items():
202
189
add_building(g, b, link_workers=False)
204
g.write_pdf(path.join(tdir, '%s.pdf' % tribe_name))
207
g.write_gif(path.join(tdir, '%s.gif' % tribe_name))
209
rtdir, tdir = tdir, ''
192
g.write_pdf(path.join(tdir, "%s.pdf" % tribe_name))
195
g.write_gif(path.join(tdir, "%s.gif" % tribe_name))
197
rtdir, tdir = tdir, ""
213
200
def make_building_graph(t, building_name):
214
201
if isinstance(t, basestring):
217
204
b = t.buildings[building_name]
219
g = CleanedDot(concentrate='false', bgcolor='transparent',
220
overlap='false', splines='true', rankdir='LR')
206
g = CleanedDot(concentrate="false", bgcolor="transparent",
207
overlap="false", splines="true", rankdir="LR")
222
209
if not isinstance(b, (ProductionSite,)):
223
210
inputs, outputs = [], []
225
# TODO: prepare for tribes having buildings with a ware as both input
227
inputs, outputs = [[t.wares[name] for name in lst]
228
for lst in [b.inputs, b.outputs]]
212
# TODO: prepare for tribes having buildings with a ware as both input and output.
213
inputs, outputs = [[t.wares[name] for name in lst] for lst in [b.inputs, b.outputs]]
230
215
# find the uppermost building in the enhancement hierarchy
232
217
while bb.base_building:
233
218
bb = bb.base_building
234
add_building(g, bb, limit_inputs=[],
235
limit_outputs=[], link_workers=False)
219
add_building(g, bb, limit_inputs=[], limit_outputs=[], link_workers=False)
237
221
add_building(g, b)
240
224
while bb.enhancement:
241
225
bb = t.buildings[bb.enhancement]
242
add_building(g, bb, limit_inputs=[],
243
limit_outputs=[], link_workers=False)
226
add_building(g, bb, limit_inputs=[], limit_outputs=[], link_workers=False)
245
228
[add_ware(g, w) for w in inputs + outputs]
248
makedirs(path.join(tdir, 'help/%s/buildings/%s/' %
249
(t.name, building_name)))
252
g.write(path.join(tdir, 'help/%s/buildings/%s/source.dot' %
253
(t.name, building_name)))
230
try: makedirs(path.join(tdir, "help/%s/buildings/%s/" % (t.name, building_name)))
232
g.write(path.join(tdir, "help/%s/buildings/%s/source.dot" % (t.name, building_name)))
256
234
def make_worker_graph(t, worker_name):
257
235
if isinstance(t, basestring):
260
238
w = t.workers[worker_name]
262
g = CleanedDot(concentrate='false', bgcolor='transparent',
263
overlap='false', splines='true', rankdir='LR')
240
g = CleanedDot(concentrate="false", bgcolor="transparent",
241
overlap="false", splines="true", rankdir="LR")
265
243
buildings = [bld for bld in t.buildings.values() if
266
isinstance(bld, ProductionSite) and
267
(w.name in bld.workers or w.name in bld.recruits)]
244
isinstance(bld, ProductionSite) and
245
(w.name in bld.workers or w.name in bld.recruits)]
269
247
for bld in buildings:
270
add_building(g, bld, limit_inputs=[], limit_outputs=[], limit_buildings=[
271
buildings], link_workers=False, limit_recruits=[w.name])
248
add_building(g, bld, limit_inputs=[], limit_outputs=[], limit_buildings=[buildings], link_workers=False, limit_recruits=[w.name])
272
249
if w.name in bld.workers:
273
g.add_edge(Edge(bld.name, w.name, color='orange', arrowhead='none'))
250
g.add_edge(Edge(bld.name, w.name, color="orange", arrowhead="none"))
275
sg = Subgraph('%s_enhancements' % w.name,
276
ordering='out', rankdir='TB', rank='same')
252
sg = Subgraph("%s_enhancements" % w.name,
253
ordering = "out", rankdir="TB", rank="same")
277
254
# find exactly one level of enhancement
278
255
for other in t.workers.values():
279
256
if other.becomes == w.name:
280
257
add_worker(sg, other)
281
g.add_edge(Edge(other.name, w.name, color='blue'))
258
g.add_edge(Edge(other.name, w.name, color="blue"))
282
259
elif w.becomes == other.name:
283
260
add_worker(sg, other)
284
g.add_edge(Edge(w.name, other.name, color='blue'))
261
g.add_edge(Edge(w.name, other.name, color="blue"))
286
263
add_worker(sg, w)
287
264
g.add_subgraph(sg)
290
makedirs(path.join(tdir, 'help/%s/workers/%s/' % (t.name, w.name)))
293
g.write(path.join(tdir, 'help/%s/workers/%s/source.dot' % (t.name, w.name)))
266
try: makedirs(path.join(tdir, "help/%s/workers/%s/" % (t.name, w.name)))
268
g.write(path.join(tdir, "help/%s/workers/%s/source.dot" % (t.name, w.name)))
296
270
def make_ware_graph(t, ware_name):
297
271
if isinstance(t, basestring):
299
273
w = t.wares[ware_name]
301
g = CleanedDot(concentrate='false', bgcolor='transparent',
302
overlap='false', splines='true', rankdir='LR')
275
g = CleanedDot(concentrate="false", bgcolor="transparent",
276
overlap="false", splines="true", rankdir="LR")
304
buildings = [bld for bld in t.buildings.values() if isinstance(
305
bld, (ProductionSite, )) and (w.name in bld.inputs or w.name in bld.outputs)]
306
[add_building(g, bld, limit_inputs=[w.name], limit_outputs=[w.name], limit_buildings=[
307
b.name for b in buildings], link_workers=False) for bld in buildings]
278
buildings = [bld for bld in t.buildings.values() if isinstance(bld, (ProductionSite, )) and (w.name in bld.inputs or w.name in bld.outputs)]
279
[add_building(g, bld, limit_inputs=[w.name], limit_outputs=[w.name], limit_buildings=[b.name for b in buildings], link_workers=False) for bld in buildings]
312
makedirs(path.join(tdir, 'help/%s/wares/%s/' % (t.name, ware_name)))
315
g.write(path.join(tdir, 'help/%s/wares/%s/source.dot' % (t.name, ware_name)))
283
try: makedirs(path.join(tdir, "help/%s/wares/%s/" % (t.name, ware_name)))
285
g.write(path.join(tdir, "help/%s/wares/%s/source.dot" % (t.name, ware_name)))
318
287
def process_dotfile(directory):
319
subprocess.Popen(('dot -Tpng -o %s/menu.png -Tcmapx -o %s/map.map %s/source.dot' %
320
(directory, directory, directory)).split(' ')).wait()
321
# with open(directory,"w") as html:
322
# html.write(r"""<IMG SRC="menu.png" border="0px" usemap="#G"/>""" +
323
# open(path.join(directory, "map.map")).read())
288
subprocess.Popen(("dot -Tpng -o %s/menu.png -Tcmapx -o %s/map.map %s/source.dot" % (directory, directory, directory)).split(" ")).wait()
289
#with open(directory,"w") as html:
290
# html.write(r"""<IMG SRC="menu.png" border="0px" usemap="#G"/>""" + open(path.join(directory, "map.map")).read())
326
292
def make_all_subgraphs(t):
328
tdir = mkdtemp(prefix='widelands-help')
294
tdir = mkdtemp(prefix="widelands-help")
329
295
if isinstance(t, basestring):
331
print 'making all subgraphs for tribe', t.name, 'in', tdir
297
print "making all subgraphs for tribe", t.name, "in", tdir
333
print ' making wares'
299
print " making wares"
335
301
for w in t.wares:
337
303
make_ware_graph(t, w)
338
process_dotfile(path.join(tdir, 'help/%s/wares/%s/' % (t.name, w)))
304
process_dotfile(path.join(tdir, "help/%s/wares/%s/" % (t.name, w)))
340
print ' making workers'
306
print " making workers"
342
308
for w in t.workers:
344
310
make_worker_graph(t, w)
345
process_dotfile(path.join(tdir, 'help/%s/workers/%s/' % (t.name, w)))
311
process_dotfile(path.join(tdir, "help/%s/workers/%s/" % (t.name, w)))
347
print ' making buildings'
313
print " making buildings"
349
315
for b in t.buildings:
351
317
make_building_graph(t, b)
352
process_dotfile(path.join(tdir, 'help/%s/buildings/%s/' % (t.name, b)))
318
process_dotfile(path.join(tdir, "help/%s/buildings/%s/" % (t.name, b)))
354
rtdir, tdir = tdir, ''
320
rtdir, tdir = tdir, ""
358
323
def add_bases(tribe, building, g):
359
324
if b.enhanced_building:
362
if __name__ == '__main__':
327
if __name__ == "__main__":
363
328
make_all_subgraphs()