Commit 22a1cf1f authored by Dylann Cordel's avatar Dylann Cordel

commit wip

parent 6629c87a
# -*- coding: utf-8 -*-
__version__ = '0.0.0'
default_app_config = 'cms_graphviz.apps.CMSGraphvizConfig'
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.apps import AppConfig, apps
class CMSGraphvizConfig(AppConfig):
name = 'cms_graphviz'
verbose_name = 'CMS Graphviz'
......@@ -5,23 +5,18 @@ from django.utils.translation import ugettext_lazy as _
from cms.plugin_pool import plugin_pool
from cms.plugin_base import CMSPluginBase
from django.conf import settings
from cms_graphviz.forms import GraphvizForm
from cms_graphviz.models import GraphvizPlugin as GraphvizPluginModel
class GraphvizPluginPlugin(CMSPluginBase):
class GraphvizPlugin(CMSPluginBase):
form = GraphvizForm
model = GraphvizPluginModel
text_enabled = False
name = _('Graph')
render_template = 'cms_graphviz/plugin.html'
cache = True
def render(self, context, instance, placeholder):
graph = ''
context['graph'] = graph
return context
plugin_pool.register_plugin(GraphvizPluginPlugin)
plugin_pool.register_plugin(GraphvizPlugin)
......@@ -2,8 +2,13 @@
from __future__ import unicode_literals
from StringIO import StringIO
from django import forms
from django.conf import settings
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.utils.translation import ugettext_lazy as _
from cms_graphviz.models import GraphvizPlugin
......@@ -11,12 +16,70 @@ class GraphvizForm(forms.ModelForm):
class Meta:
model = GraphvizPlugin
exclude = []
exclude = ([] if getattr(settings, 'CMS_GRAPHVIZ_ENABLE_MOBILE_VERSION', False)
else ['mobile_graph_dot', ])
def __init__(self, *args, **kwargs):
super(GraphvizPlugin, self).__init__(*args, **kwargs)
choices = settings.CMS_GRAPHVIZ_STYLES
super(GraphvizForm, self).__init__(*args, **kwargs)
choices = getattr(settings, 'CMS_GRAPHVIZ_STYLES', None)
if choices:
choices = tuple((key, value['label']) for key, value in choices.items())
self.fields['style'].widget = forms.Select(choices=choices)
else:
self.fields['style'].widget = forms.HiddenInput()
def clean(self):
super(GraphvizForm, self).clean()
self._clean_graph(GraphvizPlugin.VERSION_DESKTOP)
self._clean_graph(GraphvizPlugin.VERSION_MOBILE)
def _clean_graph(self, version):
data = self.cleaned_data
if version == GraphvizPlugin.VERSION_DESKTOP:
file_dest = 'graph_image'
field = 'graph_dot'
elif version == GraphvizPlugin.VERSION_MOBILE:
file_dest = 'mobile_graph_image'
field = 'mobile_graph_dot'
else:
raise Exception(_('Wrong graph version'))
if not data.get(field, None):
return
try:
graph = GraphvizPlugin.generate_graph(graph=data[field],
display_type=data['display_type'],
style=data['style'],
version=version)
except Exception:
self.add_error(field, _('Your graph seems invalid'))
return
display_type = data['display_type']
if display_type in (GraphvizPlugin.DISPLAY_TYPE_PNG, GraphvizPlugin.DISPLAY_TYPE_SVG):
if display_type == GraphvizPlugin.DISPLAY_TYPE_SVG:
fmt = 'SVG'
mime_type = 'image/svg+xml'
else:
fmt = 'PNG'
mime_type = 'image/png'
stringio_obj = StringIO(graph)
image_file = InMemoryUploadedFile(stringio_obj, None,
'graph-%s-%s.%s' % (version, '%d', fmt.lower()),
mime_type, stringio_obj.len, None)
self.cleaned_data[file_dest] = image_file
def save(self, commit=True):
if commit:
mobile_graph_image = self.cleaned_data.get('mobile_graph_image', None)
graph_image = self.cleaned_data.get('graph_image', None)
if mobile_graph_image or graph_image:
if self.instance.pk:
super(GraphvizForm, self).save(commit)
pk = self.instance.pk
if mobile_graph_image:
self.instance.mobile_graph_image.save(mobile_graph_image.name % pk,
mobile_graph_image)
if graph_image:
self.instance.graph_image.save(graph_image.name % pk, graph_image)
return super(GraphvizForm, self).save(commit)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import djangocms_text_ckeditor.fields
class Migration(migrations.Migration):
dependencies = [
('cms', '0013_auto_20160404_1908'),
]
operations = [
migrations.CreateModel(
name='GraphvizPlugin',
fields=[
('cmsplugin_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='cms.CMSPlugin')),
('name', models.CharField(max_length=100, verbose_name='name', blank=True)),
('graph_dot', models.TextField(verbose_name='DOT graph')),
('mobile_graph_dot', models.TextField(help_text='If you want a specific version for small screens like vertical smartphones, you can create an alternative schema and more condensed schema.', null=True, verbose_name='mobile DOT graph', blank=True)),
('graph_image', models.ImageField(verbose_name='stored graph file', upload_to='graphviz', null=True, editable=False, blank=True)),
('mobile_graph_image', models.ImageField(verbose_name='stored mobile graph file', upload_to='graphviz', null=True, editable=False, blank=True)),
('description', djangocms_text_ckeditor.fields.HTMLField(null=True, verbose_name='description', blank=True)),
('display_type', models.CharField(default='svg', max_length=3, verbose_name='display type', choices=[('svg', 'Au format DOT'), ('svg', 'Image SVG'), ('png', 'Image PNG en base 64')])),
('style', models.CharField(max_length=100, null=True, verbose_name='style', blank=True)),
],
options={
'verbose_name': 'graph',
'verbose_name_plural': 'graphics',
},
bases=('cms.cmsplugin',),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from cms.models.pluginmodel import CMSPlugin
from django.utils.translation import ugettext_lazy as _
class GraphvizPlugin(CMSPlugin):
DISPLAY_TYPE_SVG = 'svg'
DISPLAY_TYPE_PNG = 'png'
DISPLAY_TYPE_IMG_URL = 'url'
DISPLAY_TYPE_CHOICES = (
(DISPLAY_TYPE_SVG, _('Image SVG')),
(DISPLAY_TYPE_PNG, _('Image PNG en base 64')),
(DISPLAY_TYPE_IMG_URL, _('Image PNG stockée sur le serveur')),
)
class Meta:
verbose_name = _('graph')
verbose_name_plural = _('graphics')
name = models.CharField(
verbose_name=_('name'),
max_length=100,
null=False, blank=True,)
graph_dot = models.TextField(
verbose_name=_('DOT graph'),
null=False, blank=False,)
display_type = models.CharField(
verbose_name=_('display type'),
max_length=3,
default=DISPLAY_TYPE_SVG,
choices=DISPLAY_TYPE_CHOICES,
null=False, blank=False,)
style = models.CharField(
verbose_name=_('style'),
max_length=100,
null=True, blank=True,)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
# from django.core.files import Image
from django.db import models
from django.utils.translation import ugettext_lazy as _
from cms.models.pluginmodel import CMSPlugin
from djangocms_text_ckeditor.fields import HTMLField
from pygraphviz import AGraph
class GraphvizPlugin(CMSPlugin):
DISPLAY_TYPE_DOT = 'dot'
DISPLAY_TYPE_SVG = 'svg'
DISPLAY_TYPE_PNG = 'png'
DISPLAY_TYPE_IMG_URL = 'url'
VERSION_MOBILE = 'm'
VERSION_DESKTOP = 'd'
DISPLAY_TYPE_CHOICES = (
(DISPLAY_TYPE_DOT, _('Au format DOT')),
(DISPLAY_TYPE_SVG, _('Image SVG')),
(DISPLAY_TYPE_PNG, _('Image PNG en base 64')),
)
class Meta:
verbose_name = _('graph')
verbose_name_plural = _('graphics')
name = models.CharField(
verbose_name=_('name'),
max_length=100,
null=False, blank=True,)
graph_dot = models.TextField(
verbose_name=_('DOT graph'),
null=False, blank=False,)
mobile_graph_dot = models.TextField(
verbose_name=_('mobile DOT graph'),
help_text=_('If you want a specific version for small screens like vertical smartphones, '
'you can create an alternative schema and more condensed schema.'),
null=True, blank=True,)
graph_image = models.ImageField(
verbose_name=_('stored graph file'),
null=True, blank=True,
editable=False,
upload_to='graphviz')
mobile_graph_image = models.ImageField(
verbose_name=_('stored mobile graph file'),
null=True, blank=True,
editable=False,
upload_to='graphviz')
description = HTMLField(
verbose_name=_('description'),
null=True, blank=True,)
display_type = models.CharField(
verbose_name=_('display type'),
max_length=3,
default=DISPLAY_TYPE_SVG,
choices=DISPLAY_TYPE_CHOICES,
null=False, blank=False,)
style = models.CharField(
verbose_name=_('style'),
max_length=100,
null=True, blank=True,)
@classmethod
def generate_graph(
cls, graph,
display_type=DISPLAY_TYPE_SVG, style=None, version=VERSION_DESKTOP
):
if display_type == cls.DISPLAY_TYPE_DOT:
return graph
g = AGraph(graph)
if style:
style = getattr(settings, 'CMS_GRAPHVIZ_STYLES', {}).get(style, None)
if 'graph_attr' in style:
for attr, value in style['graph_attr'].items():
if attr not in g.graph_attr:
g.graph_attr[attr] = value
if 'node_attr' in style:
for attr, value in style['node_attr'].items():
if attr not in g.node_attr:
g.node_attr[attr] = value
if 'nodes' in style:
for node_id, attrs in style['nodes'].items():
if not g.has_node(node_id):
continue
node = g.get_node(node_id)
for attr, value in attrs.items():
if attr not in node.attr:
node.attr[attr] = value
if display_type in (cls.DISPLAY_TYPE_PNG, cls.DISPLAY_TYPE_SVG):
return g.draw(prog='dot', format=display_type)
@property
def graph(self):
if self.display_type == self.DISPLAY_TYPE_DOT:
return self.graph_dot
return self.graph_image
@property
def graph_mobile(self):
if self.display_type == self.DISPLAY_TYPE_DOT:
return self.mobile_graph_dot
return self.mobile_graph_image
{% if instance.name %}
<h2>{{ instance.name }} | {{ instance.display_type }}</h2>
{% endif %}
<div class="graphviz">
{% if instance.display_type == instance.DISPLAY_TYPE_SVG %}
{{ graph|safe }}
{% elif instance.display_type == instance.DISPLAY_TYPE_IMG_URL %}
<img src="{{ graph }}" alt="{{ instance.name }}" />
{% comment %}<img src="data:image/png;base64,{{ graph }}" alt="{{ instance.name }}" />{% endcomment %}
{{ instance.graph }}
{% elif instance.display_type == instance.DISPLAY_TYPE_PNG %}
<img src="data:image/png;base64,{{ graph }}" alt="{{ instance.name }}" />
{% comment %}<img src="data:image/png;base64,{{ graph }}" alt="{{ instance.name }}" />{% endcomment %}
{{ instance.graph }}
{% else %}
<pre class="dot">{{ graph }}</pre>
<pre class="dot">{{ instance.graph }}</pre>
{% endif %}
</div>
......@@ -33,7 +33,8 @@ setup(
install_requires=[
'Django>=1.8,<1.10',
'django-cms>=3.2,<4.0',
'pygraphviz'
'graphviz',
'pygraphviz>=1.2'
],
packages=find_packages(exclude=["project", "project.*"]),
include_package_data=True,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment