File: formatters.py

package info (click to toggle)
python-vitrageclient 5.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 648 kB
  • sloc: python: 1,807; makefile: 26; sh: 2
file content (96 lines) | stat: -rw-r--r-- 3,057 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#  Copyright 2018 - Nokia Corporation
#  #
#  Licensed under the Apache License, Version 2.0 (the "License"); you may
#  not use this file except in compliance with the License. You may obtain
#  a copy of the License at
#  #
#       http://www.apache.org/licenses/LICENSE-2.0
#  #
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#  License for the specific language governing permissions and limitations
#  under the License.
import abc
from cliff.formatters import base

from networkx.drawing.nx_pydot import write_dot
from networkx.readwrite.graphml import GraphMLWriter
from networkx.readwrite import json_graph

import networkx as nx


class GraphFormatter(base.SingleFormatter, metaclass=abc.ABCMeta):
    def add_argument_group(self, parser):
        pass

    def emit_one(self, column_names, data, stdout, _=None):
        data = {n: i for n, i in zip(column_names, data)}

        # vitrage properties are not standard
        # to convert with networkx we need to
        # use the standard properties
        # some converters have issues with multigraph
        # so disable it (currently we don't have real multigraphs)
        self._reformat(data)

        if nx.__version__ >= '3.0':
            graph = json_graph.node_link_graph(
                data, name='graph_index')
        elif nx.__version__ >= '2.0':
            graph = json_graph.node_link_graph(
                data, attrs={'name': 'graph_index'})
        else:
            graph = json_graph.node_link_graph(data)

        self._write_format(graph, stdout)

    @staticmethod
    def _reformat(data):
        for node in data['nodes']:
            name = node.pop('name', None)
            v_type = node['vitrage_type']
            if name and name != v_type:
                # if name and type the same
                # don't print twice its redundant
                # e.g openstack.cluster
                node['label'] = name + '\n' + v_type
            else:
                node['label'] = v_type

            # type list is not supported in some
            # formats
            GraphFormatter._list2str(node)

        data['multigraph'] = False

        for node in data['links']:
            node['label'] = node.pop('relationship_type')
            # used only in multigraph
            node.pop('key')

    @staticmethod
    def _list2str(node):
        for k, v in node.items():
            if type(v) is list:
                node[k] = str(v)
            if type(v) is str and ":" in v:
                node[k] = '"' + v + '"'

    @abc.abstractmethod
    def _write_format(self, graph, stdout):
        pass


class DOTFormatter(GraphFormatter):

    def _write_format(self, graph, stdout):
        write_dot(graph, stdout)


class GraphMLFormatter(GraphFormatter):

    def _write_format(self, graph, stdout):
        writer = GraphMLWriter(graph=graph)
        writer.dump(stdout)