/usr/lib/python3/dist-packages/graphviz/files.py is in python3-graphviz 0.5.2-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | # files.py - save, render, view
"""Save DOT code objects, render with Graphviz dot, and open in viewer."""
import os
import io
import codecs
from ._compat import text_type
from . import backend, tools
__all__ = ['File', 'Source']
class Base(object):
_format = 'pdf'
_engine = 'dot'
_encoding = 'utf-8'
@property
def format(self):
"""The output format used for rendering ('pdf', 'png', ...)."""
return self._format
@format.setter
def format(self, format):
format = format.lower()
if format not in backend.FORMATS:
raise ValueError('unknown format: %r' % format)
self._format = format
@property
def engine(self):
"""The layout commmand used for rendering ('dot', 'neato', ...)."""
return self._engine
@engine.setter
def engine(self, engine):
engine = engine.lower()
if engine not in backend.ENGINES:
raise ValueError('unknown engine: %r' % engine)
self._engine = engine
@property
def encoding(self):
"""The encoding for the saved source file."""
return self._encoding
@encoding.setter
def encoding(self, encoding):
if encoding is not None:
codecs.lookup(encoding)
self._encoding = encoding
class File(Base):
directory = ''
_default_extension = 'gv'
def __init__(self, filename=None, directory=None, format=None, engine=None, encoding=None):
if filename is None:
name = getattr(self, 'name', None) or self.__class__.__name__
filename = '%s.%s' % (name, self._default_extension)
self.filename = filename
if directory is not None:
self.directory = directory
if format is not None:
self.format = format
if engine is not None:
self.engine = engine
if encoding is not None:
self.encoding = encoding
def _repr_svg_(self):
return self.pipe(format='svg').decode(self._encoding)
def pipe(self, format=None):
"""Return the source piped through the Graphviz layout command.
Args:
format: The output format used for rendering ('pdf', 'png', etc.).
Returns:
Binary (encoded) stdout of the layout command.
"""
if format is None:
format = self._format
data = text_type(self.source).encode(self._encoding)
outs = backend.pipe(self._engine, format, data)
return outs
@property
def filepath(self):
return os.path.join(self.directory, self.filename)
def save(self, filename=None, directory=None):
"""Save the DOT source to file.
Args:
filename: Filename for saving the source (defaults to name + '.gv')
directory: (Sub)directory for source saving and rendering.
Returns:
The (possibly relative) path of the saved source file.
"""
if filename is not None:
self.filename = filename
if directory is not None:
self.directory = directory
filepath = self.filepath
tools.mkdirs(filepath)
data = text_type(self.source)
with io.open(filepath, 'w', encoding=self.encoding) as fd:
fd.write(data)
return filepath
def render(self, filename=None, directory=None, view=False, cleanup=False):
"""Save the source to file and render with the Graphviz engine.
Args:
filename: Filename for saving the source (defaults to name + '.gv')
directory: (Sub)directory for source saving and rendering.
view: Open the rendered result with the default application.
cleanup: Delete the source file after rendering.
Returns:
The (possibly relative) path of the rendered file.
Raises:
RuntimeError: If the Graphviz executable is not found.
RuntimeError: If viewer opening is requested but not supported.
"""
filepath = self.save(filename, directory)
rendered = backend.render(self._engine, self._format, filepath)
if cleanup:
os.remove(filepath)
if view:
self._view(rendered, self._format)
return rendered
def view(self, filename=None, directory=None, cleanup=False):
"""Save the source to file, open the rendered result in a viewer.
Args:
filename: Filename for saving the source (defaults to name + '.gv')
directory: (Sub)directory for source saving and rendering.
cleanup: Delete the source file after rendering.
Returns:
The (possibly relative) path of the rendered file.
Raises:
RuntimeError: If the Graphviz executable is not found.
RuntimeError: If opening the viewer is not supported.
Short-cut method for calling ``render()`` with ``view=True``.
"""
return self.render(view=True,
filename=filename, directory=directory, cleanup=cleanup)
def _view(self, filepath, format):
"""Start the right viewer based on file format and platform."""
methodnames = [
'_view_%s_%s' % (format, backend.PLATFORM),
'_view_%s' % backend.PLATFORM,
]
for name in methodnames:
view_method = getattr(self, name, None)
if view_method is not None:
break
else:
raise RuntimeError('%r has no built-in viewer support for %r '
'on %r platform' % (self.__class__, format, backend.PLATFORM))
view_method(filepath)
_view_darwin = staticmethod(backend.view.darwin)
_view_linux = staticmethod(backend.view.linux)
_view_windows = staticmethod(backend.view.windows)
class Source(File):
"""Verbatim DOT source code string to be rendered by Graphviz.
Args:
source: The verbatim DOT source code string.
filename: Filename for saving the source (defaults to name + '.gv').
directory: (Sub)directory for source saving and rendering.
format: Rendering output format ('pdf', 'png', ...).
engine: Layout command used ('dot', 'neato', ...).
encoding: Encoding for saving the source.
.. note::
All parameters except source are optional and can be changed under
their corresponding attribute name after instance creation.
"""
def __init__(self, source, filename=None, directory=None, format=None, engine=None, encoding=None):
super(Source, self).__init__(filename, directory, format, engine, encoding)
self.source = source
|