From be844c3ed788a19b04aeb2a8fec79ad36854556a Mon Sep 17 00:00:00 2001 From: Romain Dorgueil Date: Thu, 25 May 2017 16:41:01 +0200 Subject: [PATCH] WIP GRAPHVIZ --- Makefile | 2 +- Projectfile | 1 + bin/imgcat | 112 +++++++++++++++++++++++++++++++++++++++ bin/test_graph | 1 + bonobo/commands/graph.py | 22 ++++++++ bonobo/commands/run.py | 27 +++++----- bonobo/constants.py | 2 + bonobo/structs/graphs.py | 2 + bonobo/util/graphviz.py | 9 ++++ setup.py | 1 + 10 files changed, 165 insertions(+), 14 deletions(-) create mode 100755 bin/imgcat create mode 100644 bin/test_graph create mode 100644 bonobo/commands/graph.py create mode 100644 bonobo/util/graphviz.py diff --git a/Makefile b/Makefile index 6db0f7c..6c5443d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # This file has been auto-generated. # All changes will be lost, see Projectfile. # -# Updated at 2017-05-03 18:02:59.359160 +# Updated at 2017-05-08 11:34:30.472553 PACKAGE ?= bonobo PYTHON ?= $(shell which python) diff --git a/Projectfile b/Projectfile index 47844ee..95e5afa 100644 --- a/Projectfile +++ b/Projectfile @@ -60,6 +60,7 @@ entry_points = { ], 'bonobo.commands': [ 'init = bonobo.commands.init:register', + 'graph = bonobo.commands.graph:register', 'run = bonobo.commands.run:register', 'version = bonobo.commands.version:register', ], diff --git a/bin/imgcat b/bin/imgcat new file mode 100755 index 0000000..001d2b8 --- /dev/null +++ b/bin/imgcat @@ -0,0 +1,112 @@ +#!/bin/bash + +# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux; +# ST, and for all ESCs in to be replaced with ESC ESC. It +# only accepts ESC backslash for ST. +function print_osc() { + if [[ $TERM == screen* ]] ; then + printf "\033Ptmux;\033\033]" + else + printf "\033]" + fi +} + +# More of the tmux workaround described above. +function print_st() { + if [[ $TERM == screen* ]] ; then + printf "\a\033\\" + else + printf "\a" + fi +} + +# print_image filename inline base64contents print_filename +# filename: Filename to convey to client +# inline: 0 or 1 +# base64contents: Base64-encoded contents +# print_filename: If non-empty, print the filename +# before outputting the image +function print_image() { + print_osc + printf '1337;File=' + if [[ -n "$1" ]]; then + printf 'name='`printf "%s" "$1" | base64`";" + fi + + VERSION=$(base64 --version 2>&1) + if [[ "$VERSION" =~ fourmilab ]]; then + BASE64ARG=-d + elif [[ "$VERSION" =~ GNU ]]; then + BASE64ARG=-di + else + BASE64ARG=-D + fi + + printf "%s" "$3" | base64 $BASE64ARG | wc -c | awk '{printf "size=%d",$1}' + printf ";inline=$2" + printf ":" + printf "%s" "$3" + print_st + printf '\n' + if [[ -n "$4" ]]; then + echo $1 + fi +} + +function error() { + echo "ERROR: $*" 1>&2 +} + +function show_help() { + echo "Usage: imgcat [-p] filename ..." 1>& 2 + echo " or: cat filename | imgcat" 1>& 2 +} + +## Main + +if [ -t 0 ]; then + has_stdin=f +else + has_stdin=t +fi + +# Show help if no arguments and no stdin. +if [ $has_stdin = f -a $# -eq 0 ]; then + show_help + exit +fi + +# Look for command line flags. +while [ $# -gt 0 ]; do + case "$1" in + -h|--h|--help) + show_help + exit + ;; + -p|--p|--print) + print_filename=1 + ;; + -*) + error "Unknown option flag: $1" + show_help + exit 1 + ;; + *) + if [ -r "$1" ] ; then + has_stdin=f + print_image "$1" 1 "$(base64 < "$1")" "$print_filename" + else + error "imgcat: $1: No such file or directory" + exit 2 + fi + ;; + esac + shift +done + +# Read and print stdin +if [ $has_stdin = t ]; then + print_image "" 1 "$(cat | base64)" "" +fi + +exit 0 diff --git a/bin/test_graph b/bin/test_graph new file mode 100644 index 0000000..1e5fd85 --- /dev/null +++ b/bin/test_graph @@ -0,0 +1 @@ +bonobo graph bonobo/examples/tutorials/tut02_03_writeasmap.py | dot -otest.png -Tpng && bin/imgcat test.png diff --git a/bonobo/commands/graph.py b/bonobo/commands/graph.py new file mode 100644 index 0000000..b8bbdf9 --- /dev/null +++ b/bonobo/commands/graph.py @@ -0,0 +1,22 @@ +import json + +from bonobo.util.objects import get_name +from bonobo.commands.run import read_file +from bonobo.constants import BEGIN + + +def execute(file): + graph, plugins, services = read_file(file) + + print('digraph {') + print(' rankdir = LR;') + print(' "BEGIN" [shape="point"];') + for i in graph.outputs_of(BEGIN): + print(' "BEGIN" -> ' + json.dumps(get_name(graph.nodes[i])) + ';') + print('}') + + +def register(parser): + import argparse + parser.add_argument('file', type=argparse.FileType()) + return execute diff --git a/bonobo/commands/run.py b/bonobo/commands/run.py index b7872e2..60123c8 100644 --- a/bonobo/commands/run.py +++ b/bonobo/commands/run.py @@ -1,11 +1,7 @@ -import argparse - import os import bonobo - -DEFAULT_SERVICES_FILENAME = '_services.py' -DEFAULT_SERVICES_ATTR = 'get_services' +from bonobo.constants import DEFAULT_SERVICES_ATTR, DEFAULT_SERVICES_FILENAME def get_default_services(filename, services=None): @@ -29,7 +25,7 @@ def get_default_services(filename, services=None): return services or {} -def execute(file, quiet=False): +def read_file(file): with file: code = compile(file.read(), file.name, 'exec') @@ -56,19 +52,24 @@ def execute(file, quiet=False): ).format(len(graphs)) graph = list(graphs.values())[0] + plugins = [] + services = get_default_services( + file.name, context.get(DEFAULT_SERVICES_ATTR)() if DEFAULT_SERVICES_ATTR in context else None + ) + + return graph, plugins, services + + +def execute(file, quiet=False): + graph, plugins, services = read_file(file) # todo if console and not quiet, then add the console plugin # todo when better console plugin, add it if console and just disable display - return bonobo.run( - graph, - plugins=[], - services=get_default_services( - file.name, context.get(DEFAULT_SERVICES_ATTR)() if DEFAULT_SERVICES_ATTR in context else None - ) - ) + return bonobo.run(graph, plugins=plugins, services=services) def register(parser): + import argparse parser.add_argument('file', type=argparse.FileType()) parser.add_argument('--quiet', action='store_true') return execute diff --git a/bonobo/constants.py b/bonobo/constants.py index d567229..4187197 100644 --- a/bonobo/constants.py +++ b/bonobo/constants.py @@ -4,3 +4,5 @@ BEGIN = Token('Begin') END = Token('End') INHERIT_INPUT = Token('InheritInput') NOT_MODIFIED = Token('NotModified') +DEFAULT_SERVICES_FILENAME = '_services.py' +DEFAULT_SERVICES_ATTR = 'get_services' \ No newline at end of file diff --git a/bonobo/structs/graphs.py b/bonobo/structs/graphs.py index d2d755e..c68186b 100644 --- a/bonobo/structs/graphs.py +++ b/bonobo/structs/graphs.py @@ -29,3 +29,5 @@ class Graph: def __len__(self): return len(self.nodes) + + diff --git a/bonobo/util/graphviz.py b/bonobo/util/graphviz.py new file mode 100644 index 0000000..fa88974 --- /dev/null +++ b/bonobo/util/graphviz.py @@ -0,0 +1,9 @@ + +def render_as_dot(graph): + """ + + :param bonobo.Graph graph: + :return: str + """ + + pass \ No newline at end of file diff --git a/setup.py b/setup.py index 4cd8d82..1153f35 100644 --- a/setup.py +++ b/setup.py @@ -65,6 +65,7 @@ setup( entry_points={ 'bonobo.commands': [ 'init = bonobo.commands.init:register', + 'graph = bonobo.commands.graph:register', 'run = bonobo.commands.run:register', 'version = bonobo.commands.version:register' ],