|
| 1 | +from __future__ import unicode_literals |
| 2 | + |
| 3 | +from builtins import str |
| 4 | +from .dag import get_outgoing_edges |
| 5 | +from ._run import topo_sort |
| 6 | +import os |
| 7 | +import tempfile |
| 8 | + |
| 9 | +from ffmpeg.nodes import ( |
| 10 | + FilterNode, |
| 11 | + get_stream_spec_nodes, |
| 12 | + InputNode, |
| 13 | + OutputNode, |
| 14 | + Stream, |
| 15 | + stream_operator, |
| 16 | +) |
| 17 | + |
| 18 | + |
| 19 | +_RIGHT_ARROW = '\u2192' |
| 20 | + |
| 21 | + |
| 22 | +def _get_node_color(node): |
| 23 | + if isinstance(node, InputNode): |
| 24 | + color = '#99cc00' |
| 25 | + elif isinstance(node, OutputNode): |
| 26 | + color = '#99ccff' |
| 27 | + elif isinstance(node, FilterNode): |
| 28 | + color = '#ffcc00' |
| 29 | + else: |
| 30 | + color = None |
| 31 | + return color |
| 32 | + |
| 33 | + |
| 34 | +@stream_operator() |
| 35 | +def view(stream_spec, **kwargs): |
| 36 | + try: |
| 37 | + import graphviz |
| 38 | + except ImportError: |
| 39 | + raise ImportError('failed to import graphviz; please make sure graphviz is installed (e.g. `pip install ' |
| 40 | + 'graphviz`)') |
| 41 | + |
| 42 | + filename = kwargs.pop('filename', None) |
| 43 | + show_labels = kwargs.pop('show_labels', True) |
| 44 | + if filename is None: |
| 45 | + filename = tempfile.mktemp() |
| 46 | + |
| 47 | + nodes = get_stream_spec_nodes(stream_spec) |
| 48 | + |
| 49 | + sorted_nodes, outgoing_edge_maps = topo_sort(nodes) |
| 50 | + graph = graphviz.Digraph() |
| 51 | + graph.attr(rankdir='LR') |
| 52 | + if len(list(kwargs.keys())) != 0: |
| 53 | + raise ValueError('Invalid kwargs key(s): {}'.format(', '.join(list(kwargs.keys())))) |
| 54 | + |
| 55 | + for node in sorted_nodes: |
| 56 | + color = _get_node_color(node) |
| 57 | + |
| 58 | + graph.node(str(hash(node)), node.short_repr, shape='box', style='filled', fillcolor=color) |
| 59 | + outgoing_edge_map = outgoing_edge_maps.get(node, {}) |
| 60 | + |
| 61 | + for edge in get_outgoing_edges(node, outgoing_edge_map): |
| 62 | + kwargs = {} |
| 63 | + up_label = edge.upstream_label |
| 64 | + down_label = edge.downstream_label |
| 65 | + if show_labels and (up_label is not None or down_label is not None): |
| 66 | + if up_label is None: |
| 67 | + up_label = '' |
| 68 | + if down_label is None: |
| 69 | + down_label = '' |
| 70 | + if up_label != '' and down_label != '': |
| 71 | + middle = ' {} '.format(_RIGHT_ARROW) |
| 72 | + else: |
| 73 | + middle = '' |
| 74 | + kwargs['label'] = '{} {} {}'.format(up_label, middle, down_label) |
| 75 | + upstream_node_id = str(hash(edge.upstream_node)) |
| 76 | + downstream_node_id = str(hash(edge.downstream_node)) |
| 77 | + graph.edge(upstream_node_id, downstream_node_id, **kwargs) |
| 78 | + |
| 79 | + graph.view(filename) |
| 80 | + |
| 81 | + return stream_spec |
| 82 | + |
| 83 | + |
| 84 | +__all__ = [ |
| 85 | + 'view', |
| 86 | +] |
0 commit comments