6
from django.conf import settings
6
7
from widelandslib.tribe import *
7
#from pudb import set_trace; set_trace()
9
9
from os import makedirs, path
11
11
from tempfile import mkdtemp
15
15
##############################
16
16
# To Do Make_Flow_Diagram.py #
17
17
##############################
18
# i'd like to add things like: forester resores trunk or: gamekeeper restores meat
18
# i'd like to add things like: forester resores log or: gamekeeper restores meat
20
20
# also, a building called construction site where alle the building material can point at would be nice
22
22
# how to tell the viewer, how many and wich ressources turn to others via buildings,
23
# e.g. 6 trunks to 1 coal with the atlanteans, maybe on the edges?
23
# e.g. 6 logs to 1 coal with the atlanteans, maybe on the edges?
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)
125
if isinstance(b, (ProductionSite,)):
126
# for worker,c in b.workers:
136
if isinstance(b, ProductionSite):
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")
172
t = Tribe(tribe_name)
174
g = CleanedDot(concentrate="false", style="filled", bgcolor="white",
175
overlap="false", splines="true", rankdir="LR")
177
for name,w in t.wares.items():
183
tdir = mkdtemp(prefix='widelands-help')
184
json_directory = path.normpath(settings.MEDIA_ROOT + '/map_object_info')
185
with open(path.normpath(
186
json_directory + '/tribe_' + tribe_name + '.json'), 'r') as tribeinfo_file:
187
tribeinfo = json.load(tribeinfo_file)
189
t = Tribe(tribeinfo, json_directory)
191
g = CleanedDot(concentrate='false', style='filled', bgcolor='white',
192
overlap='false', splines='true', rankdir='LR')
194
for name, w in list(t.wares.items()):
180
197
# for name,w in t.workers.items():
181
198
# add_worker(g, w)
183
for name,b in t.buildings.items():
200
for name, b in list(t.buildings.items()):
184
201
add_building(g, b, link_workers=False)
187
g.write_pdf(path.join(tdir, "%s.pdf" % tribe_name))
190
g.write_gif(path.join(tdir, "%s.gif" % tribe_name))
192
rtdir, tdir = tdir, ""
203
g.write_pdf(path.join(tdir, '%s.pdf' % tribe_name))
206
g.write_gif(path.join(tdir, '%s.gif' % tribe_name))
208
rtdir, tdir = tdir, ''
195
212
def make_building_graph(t, building_name):
196
if isinstance(t, basestring):
213
if isinstance(t, str):
199
216
b = t.buildings[building_name]
201
g = CleanedDot(concentrate="false", bgcolor="transparent",
202
overlap="false", splines="true", rankdir="LR")
218
g = CleanedDot(concentrate='false', bgcolor='transparent',
219
overlap='false', splines='true', rankdir='LR')
204
if not isinstance(b, (ProductionSite,)):
221
if not isinstance(b, ProductionSite):
205
222
inputs, outputs = [], []
207
# TODO: prepare for tribes having buildings with a ware as both input and output.
208
inputs, outputs = [[t.wares[name] for name in lst] for lst in [b.inputs, b.outputs]]
224
# TODO: prepare for tribes having buildings with a ware as both input
226
inputs, outputs = [[t.wares[name] for name in lst]
227
for lst in [b.inputs, b.outputs]]
210
229
# find the uppermost building in the enhancement hierarchy
212
231
while bb.base_building:
213
232
bb = bb.base_building
214
add_building(g, bb, limit_inputs=[], limit_outputs=[], link_workers=False)
233
add_building(g, bb, limit_inputs=[],
234
limit_outputs=[], link_workers=False)
216
236
add_building(g, b)
219
239
while bb.enhancement:
220
240
bb = t.buildings[bb.enhancement]
221
add_building(g, bb, limit_inputs=[], limit_outputs=[], link_workers=False)
241
add_building(g, bb, limit_inputs=[],
242
limit_outputs=[], link_workers=False)
223
244
[add_ware(g, w) for w in inputs + outputs]
225
try: makedirs(path.join(tdir, "help/%s/buildings/%s/" % (t.name, building_name)))
227
g.write(path.join(tdir, "help/%s/buildings/%s/source.dot" % (t.name, building_name)))
247
makedirs(path.join(tdir, 'help/%s/buildings/%s/' %
248
(t.name, building_name)))
251
g.write(path.join(tdir, 'help/%s/buildings/%s/source.dot' %
252
(t.name, building_name)))
229
255
def make_worker_graph(t, worker_name):
230
if isinstance(t, basestring):
256
if isinstance(t, str):
233
259
w = t.workers[worker_name]
235
g = CleanedDot(concentrate="false", bgcolor="transparent",
236
overlap="false", splines="true", rankdir="LR")
261
g = CleanedDot(concentrate='false', bgcolor='transparent',
262
overlap='false', splines='true', rankdir='LR')
238
buildings = [bld for bld in t.buildings.values() if
239
isinstance(bld, ProductionSite) and
240
(w.name in bld.workers or w.name in bld.recruits)]
264
buildings = [bld for bld in list(t.buildings.values()) if
265
isinstance(bld, ProductionSite) and
266
(w.name in bld.workers or w.name in bld.recruits)]
242
268
for bld in buildings:
243
add_building(g, bld, limit_inputs=[], limit_outputs=[], limit_buildings=[buildings], link_workers=False, limit_recruits=[w.name])
269
add_building(g, bld, limit_inputs=[], limit_outputs=[], limit_buildings=[
270
buildings], link_workers=False, limit_recruits=[w.name])
244
271
if w.name in bld.workers:
245
g.add_edge(Edge(bld.name, w.name, color="orange", arrowhead="none"))
272
g.add_edge(Edge(bld.name, w.name, color='orange', arrowhead='none'))
247
sg = Subgraph("%s_enhancements" % w.name,
248
ordering = "out", rankdir="TB", rank="same")
274
sg = Subgraph('%s_enhancements' % w.name,
275
ordering='out', rankdir='TB', rank='same')
249
276
# find exactly one level of enhancement
250
for other in t.workers.values():
277
for other in list(t.workers.values()):
251
278
if other.becomes == w.name:
252
279
add_worker(sg, other)
253
g.add_edge(Edge(other.name, w.name, color="blue"))
280
g.add_edge(Edge(other.name, w.name, color='blue'))
254
281
elif w.becomes == other.name:
255
282
add_worker(sg, other)
256
g.add_edge(Edge(w.name, other.name, color="blue"))
283
g.add_edge(Edge(w.name, other.name, color='blue'))
258
285
add_worker(sg, w)
259
286
g.add_subgraph(sg)
261
try: makedirs(path.join(tdir, "help/%s/workers/%s/" % (t.name, w.name)))
263
g.write(path.join(tdir, "help/%s/workers/%s/source.dot" % (t.name, w.name)))
289
makedirs(path.join(tdir, 'help/%s/workers/%s/' % (t.name, w.name)))
292
g.write(path.join(tdir, 'help/%s/workers/%s/source.dot' % (t.name, w.name)))
265
295
def make_ware_graph(t, ware_name):
266
if isinstance(t, basestring):
296
if isinstance(t, str):
268
298
w = t.wares[ware_name]
270
g = CleanedDot(concentrate="false", bgcolor="transparent",
271
overlap="false", splines="true", rankdir="LR")
300
g = CleanedDot(concentrate='false', bgcolor='transparent',
301
overlap='false', splines='true', rankdir='LR')
273
buildings = [bld for bld in t.buildings.values() if isinstance(bld, (ProductionSite, )) and (w.name in bld.inputs or w.name in bld.outputs)]
274
[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]
303
buildings = [bld for bld in list(t.buildings.values()) if isinstance(
304
bld, ProductionSite) and (w.name in bld.inputs or w.name in bld.outputs)]
305
[add_building(g, bld, limit_inputs=[w.name], limit_outputs=[w.name], limit_buildings=[
306
b.name for b in buildings], link_workers=False) for bld in buildings]
278
try: makedirs(path.join(tdir, "help/%s/wares/%s/" % (t.name, ware_name)))
280
g.write(path.join(tdir, "help/%s/wares/%s/source.dot" % (t.name, ware_name)))
311
makedirs(path.join(tdir, 'help/%s/wares/%s/' % (t.name, ware_name)))
314
g.write(path.join(tdir, 'help/%s/wares/%s/source.dot' % (t.name, ware_name)))
282
317
def process_dotfile(directory):
283
subprocess.Popen(("dot -Tpng -o %s/image.png -Tcmapx -o %s/map.map %s/source.dot" % (directory, directory, directory)).split(" ")).wait()
284
#with open(directory,"w") as html:
285
# html.write(r"""<IMG SRC="image.png" border="0px" usemap="#G"/>""" + open(path.join(directory, "map.map")).read())
318
subprocess.Popen(('dot -Tpng -o %s/menu.png -Tcmapx -o %s/map.map %s/source.dot' %
319
(directory, directory, directory)).split(' ')).wait()
320
# with open(directory,"w") as html:
321
# html.write(r"""<IMG SRC="menu.png" border="0px" usemap="#G"/>""" +
322
# open(path.join(directory, "map.map")).read())
287
325
def make_all_subgraphs(t):
289
tdir = mkdtemp(prefix="widelands-help")
290
if isinstance(t, basestring):
327
tdir = mkdtemp(prefix='widelands-help')
328
if isinstance(t, str):
292
print "making all subgraphs for tribe", t.name, "in", tdir
294
print " making workers"
330
print('making all subgraphs for tribe', t.name, 'in', tdir)
332
print(' making wares')
336
make_ware_graph(t, w)
337
process_dotfile(path.join(tdir, 'help/%s/wares/%s/' % (t.name, w)))
339
print(' making workers')
296
341
for w in t.workers:
298
343
make_worker_graph(t, w)
299
process_dotfile(path.join(tdir, "help/%s/workers/%s/" % (t.name, w)))
301
print " making wares"
305
make_ware_graph(t, w)
306
process_dotfile(path.join(tdir, "help/%s/wares/%s/" % (t.name, w)))
308
print " making buildings"
344
process_dotfile(path.join(tdir, 'help/%s/workers/%s/' % (t.name, w)))
346
print(' making buildings')
310
348
for b in t.buildings:
312
350
make_building_graph(t, b)
313
process_dotfile(path.join(tdir, "help/%s/buildings/%s/" % (t.name, b)))
351
process_dotfile(path.join(tdir, 'help/%s/buildings/%s/' % (t.name, b)))
315
rtdir, tdir = tdir, ""
353
rtdir, tdir = tdir, ''
318
357
def add_bases(tribe, building, g):
319
358
if b.enhanced_building:
322
if __name__ == "__main__":
362
if __name__ == '__main__':
323
363
make_all_subgraphs()