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