~widelands-dev/widelands-website/django_staticfiles

« back to all changes in this revision

Viewing changes to widelandslib/make_flow_diagram.py

  • Committer: Holger Rapp
  • Date: 2016-08-08 10:06:42 UTC
  • mto: This revision was merged to the branch mainline in revision 419.
  • Revision ID: sirver@gmx.de-20160808100642-z62vwqitxoyl5fh4
Added the apt-get update script I run every 30 days.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
import subprocess
11
11
from tempfile import mkdtemp
12
12
 
13
 
tdir = ''
 
13
tdir = ""
14
14
 
15
15
##############################
16
16
# To Do Make_Flow_Diagram.py #
25
25
#############################
26
26
# Work around bugs in pydot #
27
27
#############################
28
 
# Pydot can't handle names with - in it. We replace them.
29
 
 
 
28
## Pydot can't handle names with - in it. We replace them.
30
29
 
31
30
def _cleanup_str(s):
32
31
    return s.replace('-', '')
33
32
 
34
 
 
35
33
class Subgraph(d.Subgraph):
36
 
 
37
34
    def __init__(self, name, *args, **kwargs):
38
35
        name = _cleanup_str(name)
39
36
        d.Subgraph.__init__(self, name, *args, **kwargs)
40
37
 
41
 
 
42
38
class Node(d.Node):
43
 
 
44
39
    def __init__(self, name, *args, **kwargs):
45
40
        name = _cleanup_str(name)
46
41
        d.Node.__init__(self, name, *args, **kwargs)
47
42
 
48
 
 
49
43
class Edge(d.Edge):
50
 
 
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)
55
48
 
56
 
 
57
49
class CleanedDot(d.Dot):
58
 
 
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)
64
55
# Begin of drawing #
65
56
####################
66
57
 
67
 
 
68
58
def add_building(g, b, limit_inputs=None, limit_outputs=None, limit_buildings=None, link_workers=True, limit_recruits=None):
69
59
    # Add the nice node
70
 
    workers = ''
 
60
    workers = ""
71
61
    if isinstance(b, (ProductionSite,)):
72
62
        workers = r"""<table border="0px" cellspacing="0">"""
73
63
        for worker in b.workers:
77
67
            ))
78
68
            if link_workers:
79
69
                add_worker(g, wo)
80
 
                g.add_edge(
81
 
                    Edge(b.name, wo.name, color='orange', arrowhead='none'))
 
70
                g.add_edge(Edge(b.name, wo.name, color="orange", arrowhead="none"))
82
71
        for worker in b.recruits:
83
72
            if limit_recruits is None or worker in limit_recruits:
84
73
                wo = b.tribe.workers[worker]
85
74
                add_worker(g, wo, as_recruit=True)
86
 
                g.add_edge(Edge(b.name, wo.name, color='darkgreen'))
 
75
                g.add_edge(Edge(b.name, wo.name, color="darkgreen"))
87
76
        workers += r"""</table>"""
88
77
 
89
78
    if isinstance(b, (MilitarySite,)):
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:
103
 
        costs = ''
 
91
        costs = ""
104
92
 
105
93
    n = Node(b.name,
106
 
             shape='none',
107
 
             label=(r"""<<TABLE border="1px" cellborder="0px" cellspacing="0px" cellpadding="0px">
 
94
        shape = "none",
 
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>
110
98
</TR>
111
99
<TR><TD align="left" colspan="2">%s</TD></TR>
112
100
%s
113
 
</TABLE>>""" % (b.image, workers, b.descname, costs)).replace('\n', ''),
114
 
             URL='../../buildings/%s/' % b.name,
115
 
             fillcolor='orange',
116
 
             style='filled',
117
 
             )
 
101
</TABLE>>""" % (b.image, workers, b.descname, costs)).replace('\n',''),
 
102
        URL = "../../buildings/%s/" % b.name,
 
103
        fillcolor = "orange",
 
104
        style = "filled",
 
105
    )
118
106
 
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:
122
110
        cb = b
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)))
133
121
    else:
134
122
        g.add_node(n)
135
123
 
 
124
 
136
125
    if isinstance(b, (ProductionSite,)):
137
126
        # for worker,c in b.workers:
138
127
        #     g.add_edge(Edge(worker, name, color="orange"))
139
128
 
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"))
143
132
 
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"))
147
136
    return n
148
137
 
149
138
 
150
139
def add_ware(g, w):
151
140
    # Add the nice node
152
141
    n = Node(w.name,
153
 
             shape='ellipse',
154
 
             label=(r"""<<TABLE border="0px">
 
142
             shape = "ellipse",
 
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),
159
 
             fillcolor='#dddddd',
160
 
             style='filled',
161
 
             )
 
147
             URL = "../../wares/%s/" % (w.name),
 
148
             fillcolor = "#dddddd",
 
149
             style="filled",
 
150
)
162
151
 
163
152
    g.add_node(n)
164
153
 
165
 
 
166
154
def add_worker(g, w, as_recruit=False):
167
155
    # Add the nice node
168
156
    n = Node(w.name,
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>
172
160
<TD>%s</TD></TR>
173
161
</TABLE>>""") % (w.image, w.descname),
174
 
             URL='../../workers/%s/' % w.name,
175
 
             style='filled',
176
 
             )
 
162
            URL="../../workers/%s/" % w.name,
 
163
            style="filled",
 
164
        )
177
165
 
178
166
    g.add_node(n)
179
167
 
180
168
 
181
169
def make_graph(tribe_name):
182
170
    global tdir
183
 
    tdir = mkdtemp(prefix='widelands-help')
 
171
    tdir = mkdtemp(prefix="widelands-help")
184
172
 
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)
189
176
 
190
177
    t = Tribe(tribeinfo, json_directory)
191
178
 
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")
194
181
 
195
 
    for name, w in t.wares.items():
 
182
    for name,w in t.wares.items():
196
183
        add_ware(g, w)
197
184
    #
198
185
    # for name,w in t.workers.items():
199
186
    #     add_worker(g, w)
200
187
 
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)
203
190
 
204
 
    g.write_pdf(path.join(tdir, '%s.pdf' % tribe_name))
205
 
 
206
 
    g.set_size('32')
207
 
    g.write_gif(path.join(tdir, '%s.gif' % tribe_name))
208
 
 
209
 
    rtdir, tdir = tdir, ''
 
191
 
 
192
    g.write_pdf(path.join(tdir, "%s.pdf" % tribe_name))
 
193
 
 
194
    g.set_size("32")
 
195
    g.write_gif(path.join(tdir, "%s.gif" % tribe_name))
 
196
 
 
197
    rtdir, tdir = tdir, ""
210
198
    return rtdir
211
199
 
212
 
 
213
200
def make_building_graph(t, building_name):
214
201
    if isinstance(t, basestring):
215
202
        t = Tribe(t)
216
203
 
217
204
    b = t.buildings[building_name]
218
205
 
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")
221
208
 
222
209
    if not isinstance(b, (ProductionSite,)):
223
210
        inputs, outputs = [], []
224
211
    else:
225
 
        # TODO: prepare for tribes having buildings with a ware as both input
226
 
        # and output.
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]]
229
214
 
230
215
    # find the uppermost building in the enhancement hierarchy
231
216
    bb = b
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)
236
220
 
237
221
    add_building(g, b)
238
222
 
239
223
    bb = 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)
244
227
 
245
228
    [add_ware(g, w) for w in inputs + outputs]
246
229
 
247
 
    try:
248
 
        makedirs(path.join(tdir, 'help/%s/buildings/%s/' %
249
 
                           (t.name, building_name)))
250
 
    except:
251
 
        pass
252
 
    g.write(path.join(tdir, 'help/%s/buildings/%s/source.dot' %
253
 
                      (t.name, building_name)))
254
 
 
 
230
    try: makedirs(path.join(tdir, "help/%s/buildings/%s/" % (t.name, building_name)))
 
231
    except: pass
 
232
    g.write(path.join(tdir, "help/%s/buildings/%s/source.dot" % (t.name, building_name)))
255
233
 
256
234
def make_worker_graph(t, worker_name):
257
235
    if isinstance(t, basestring):
259
237
 
260
238
    w = t.workers[worker_name]
261
239
 
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")
264
242
 
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)]
268
246
 
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"))
274
251
 
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"))
285
262
 
286
263
    add_worker(sg, w)
287
264
    g.add_subgraph(sg)
288
265
 
289
 
    try:
290
 
        makedirs(path.join(tdir, 'help/%s/workers/%s/' % (t.name, w.name)))
291
 
    except OSError:
292
 
        pass
293
 
    g.write(path.join(tdir, 'help/%s/workers/%s/source.dot' % (t.name, w.name)))
294
 
 
 
266
    try: makedirs(path.join(tdir, "help/%s/workers/%s/" % (t.name, w.name)))
 
267
    except OSError: pass
 
268
    g.write(path.join(tdir, "help/%s/workers/%s/source.dot" % (t.name, w.name)))
295
269
 
296
270
def make_ware_graph(t, ware_name):
297
271
    if isinstance(t, basestring):
298
272
        t = Tribe(t)
299
273
    w = t.wares[ware_name]
300
274
 
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")
303
277
 
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]
308
280
 
309
281
    add_ware(g, w)
310
282
 
311
 
    try:
312
 
        makedirs(path.join(tdir, 'help/%s/wares/%s/' % (t.name, ware_name)))
313
 
    except OSError:
314
 
        pass
315
 
    g.write(path.join(tdir, 'help/%s/wares/%s/source.dot' % (t.name, ware_name)))
316
 
 
 
283
    try: makedirs(path.join(tdir, "help/%s/wares/%s/" % (t.name, ware_name)))
 
284
    except OSError: pass
 
285
    g.write(path.join(tdir, "help/%s/wares/%s/source.dot" % (t.name, ware_name)))
317
286
 
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())
324
 
 
 
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())
325
291
 
326
292
def make_all_subgraphs(t):
327
293
    global tdir
328
 
    tdir = mkdtemp(prefix='widelands-help')
 
294
    tdir = mkdtemp(prefix="widelands-help")
329
295
    if isinstance(t, basestring):
330
296
        t = Tribe(t)
331
 
    print 'making all subgraphs for tribe', t.name, 'in', tdir
 
297
    print "making all subgraphs for tribe", t.name, "in", tdir
332
298
 
333
 
    print '  making wares'
 
299
    print "  making wares"
334
300
 
335
301
    for w in t.wares:
336
 
        print '    ' + w
 
302
        print "    " + w
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)))
339
305
 
340
 
    print '  making workers'
 
306
    print "  making workers"
341
307
 
342
308
    for w in t.workers:
343
 
        print '    ' + w
 
309
        print "    " + w
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)))
346
312
 
347
 
    print '  making buildings'
 
313
    print "  making buildings"
348
314
 
349
315
    for b in t.buildings:
350
 
        print '    ' + b
 
316
        print "    " + b
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)))
353
319
 
354
 
    rtdir, tdir = tdir, ''
 
320
    rtdir, tdir = tdir, ""
355
321
    return rtdir
356
322
 
357
 
 
358
323
def add_bases(tribe, building, g):
359
324
    if b.enhanced_building:
360
325
        add_building()
361
326
 
362
 
if __name__ == '__main__':
 
327
if __name__ == "__main__":
363
328
    make_all_subgraphs()