~ubuntu-branches/ubuntu/saucy/ubuntuone-client/saucy-proposed

« back to all changes in this revision

Viewing changes to ubuntuone/syncdaemon/fsm/fsm_draw.py

  • Committer: Package Import Robot
  • Author(s): Rodney Dawes
  • Date: 2013-07-11 15:11:07 UTC
  • mfrom: (1.1.83)
  • Revision ID: package-import@ubuntu.com-20130711151107-6tbv4n9er446e2yy
Tags: 13.07-0ubuntu1
* New upstream release.
  - Remove libsyncdaemon and convert to pure python project.
* debian/control:
  - Update dependencies for changes.
  - Drop libsyncdaemon packages. (LP: #1196684)
* debian/rules:
  - Convert to pure dh and update for build system changes.
* debian/tests:
  - Add autopkgtest configuration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# ubuntuone.syncdaemon.fsm.fsm_draw - draw a fsm
2
 
#
3
 
# Author: Lucio Torre <lucio.torre@canonical.com>
4
 
#
5
 
# Copyright 2009-2012 Canonical Ltd.
6
 
#
7
 
# This program is free software: you can redistribute it and/or modify it
8
 
# under the terms of the GNU General Public License version 3, as published
9
 
# by the Free Software Foundation.
10
 
#
11
 
# This program is distributed in the hope that it will be useful, but
12
 
# WITHOUT ANY WARRANTY; without even the implied warranties of
13
 
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14
 
# PURPOSE.  See the GNU General Public License for more details.
15
 
#
16
 
# You should have received a copy of the GNU General Public License along
17
 
# with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
#
19
 
# In addition, as a special exception, the copyright holders give
20
 
# permission to link the code of portions of this program with the
21
 
# OpenSSL library under certain conditions as described in each
22
 
# individual source file, and distribute linked combinations
23
 
# including the two.
24
 
# You must obey the GNU General Public License in all respects
25
 
# for all of the code used other than OpenSSL.  If you modify
26
 
# file(s) with this exception, you may extend this exception to your
27
 
# version of the file(s), but you are not obligated to do so.  If you
28
 
# do not wish to do so, delete this exception statement from your
29
 
# version.  If you delete this exception statement from all source
30
 
# files in the program, then also delete it here.
31
 
"""This module is useful for debugging states machines by plotting them."""
32
 
 
33
 
import tempfile
34
 
import time
35
 
import sys
36
 
 
37
 
# pylint: disable-msg=F0401
38
 
import gtk
39
 
 
40
 
import xdot
41
 
from ubuntuone.syncdaemon.fsm import fsm
42
 
 
43
 
 
44
 
def dict2label(d):
45
 
    'transform a dictionary into a label'
46
 
    t = '"%s"' % "\\n".join("%s=%s" % x for x in sorted(d.items()))
47
 
    return t
48
 
 
49
 
 
50
 
def main(filename, debug=False):
51
 
    'draw the state machine that is in $filename'
52
 
 
53
 
    print "Parsing file...   (%s)" % time.ctime()
54
 
    machine = fsm.StateMachine(filename)
55
 
 
56
 
    print "Building graph... (%s)" % time.ctime()
57
 
    despair = object()
58
 
    graph_base = u'digraph G {\n%s [label="despair"]\n%%s\n}' % id(despair)
59
 
    graph_lines = []
60
 
    s2s = {}
61
 
    for state in machine.states.values():
62
 
        line = "%s [label=%s]" % (id(state), dict2label(state.values))
63
 
        graph_lines.append(line)
64
 
 
65
 
    for event in machine.events.values():
66
 
        for transition in event.draw_transitions:
67
 
            if all(map(lambda x: x == "*", transition.target.values())):
68
 
                target = despair
69
 
            else:
70
 
                try:
71
 
                    target = machine.get_state(transition.target)
72
 
                except KeyError:
73
 
                    continue
74
 
 
75
 
            l = s2s.setdefault((fsm.hash_dict(transition.source),
76
 
                                fsm.hash_dict(transition.target)), [])
77
 
            l.append(transition)
78
 
 
79
 
    for (source, target), ts in s2s.items():
80
 
        try:
81
 
            source = machine.get_state(dict(source))
82
 
            if all(map(lambda x: x == "*", dict(target).values())):
83
 
                target = despair
84
 
            else:
85
 
                target = machine.get_state(dict(target))
86
 
        except KeyError:
87
 
            continue
88
 
        cases = []
89
 
        for t in ts:
90
 
            ps = " ".join(["%s:%s" % (k, v) for k, v in t.parameters.items()])
91
 
            cases.append("%s:%s" % (t.event, ps))
92
 
        line = '%s [label="%s", shape=box, fontsize=7]' % (
93
 
            id(ts), "\\n".join(cases))
94
 
        graph_lines.append(line)
95
 
 
96
 
        arrow = '%s -> %s' % (
97
 
            id(source), id(ts))
98
 
        graph_lines.append(arrow)
99
 
        arrow = '%s -> %s' % (
100
 
            id(ts), id(target))
101
 
        graph_lines.append(arrow)
102
 
 
103
 
    dotcode = graph_base % "\n".join(graph_lines)
104
 
    if debug:
105
 
        filename = tempfile.mkstemp(prefix='graph-', suffix='.debug')
106
 
        a = open(filename, "w")
107
 
        a.write(dotcode)
108
 
        a.close()
109
 
 
110
 
    # go for it!
111
 
    print "Drawing...        (%s)" % time.ctime()
112
 
    window = xdot.DotWindow()
113
 
    window.set_dotcode(dotcode)
114
 
    window.connect('destroy', gtk.main_quit)
115
 
    gtk.main()
116
 
 
117
 
if __name__ == "__main__":
118
 
    main(sys.argv[1], True)