[views/dot] use an inlined svg for schema and workflow graphs
These are currently served as "temporary" pngs which are actually consummed immediately.
Which means they cannot be requested twice and any further attempt will yield an error
in the logs and some end-user surprise.
There is no known acceptable workaround for IE-8 (and previous versions). SVGWEB could
be workable but it's not trivial to integrate it properly.
Closes #3400448.
--- a/web/views/__init__.py Thu Dec 12 16:17:25 2013 +0100
+++ b/web/views/__init__.py Mon Jan 06 12:01:35 2014 +0100
@@ -25,6 +25,7 @@
from rql import nodes
from logilab.mtconverter import xml_escape
+from logilab.common.deprecation import class_deprecated
def need_table_view(rset, schema):
@@ -125,7 +126,10 @@
return u''
+
class TmpFileViewMixin(object):
+ __metaclass__ = class_deprecated
+ __deprecation_warning__ = '[3.18] %(cls)s is deprecated'
binary = True
content_type = 'application/octet-stream'
cache_max_age = 60*60*2 # stay in http cache for 2 hours by default
--- a/web/views/dotgraphview.py Thu Dec 12 16:17:25 2013 +0100
+++ b/web/views/dotgraphview.py Mon Jan 06 12:01:35 2014 +0100
@@ -22,6 +22,7 @@
import tempfile
import os
+import codecs
from logilab.mtconverter import xml_escape
from logilab.common.graph import GraphGenerator, DotBackend
@@ -33,30 +34,22 @@
__abstract__ = True
backend_class = DotBackend
backend_kwargs = {'ratio': 'compress', 'size': '30,10'}
+
def cell_call(self, row, col):
+ if 'MSIE 8' in self._cw.useragent():
+ return
entity = self.cw_rset.get_entity(row, col)
visitor = self.build_visitor(entity)
prophdlr = self.build_dotpropshandler()
graphname = 'dotgraph%s' % str(entity.eid)
generator = GraphGenerator(self.backend_class(graphname, None,
**self.backend_kwargs))
- # map file
- pmap, mapfile = tempfile.mkstemp(".map", graphname)
- os.close(pmap)
# image file
- fd, tmpfile = tempfile.mkstemp('.png')
+ fd, tmpfile = tempfile.mkstemp('.svg')
os.close(fd)
- generator.generate(visitor, prophdlr, tmpfile, mapfile)
- filekeyid = make_uid()
- self._cw.session.data[filekeyid] = tmpfile
- self.w(u'<img src="%s" alt="%s" usemap="#%s" />' % (
- xml_escape(entity.absolute_url(vid='tmppng', tmpfile=filekeyid)),
- xml_escape(self._cw._('Data connection graph for %s') % entity.dc_title()),
- graphname))
- stream = open(mapfile, 'r').read()
- stream = stream.decode(self._cw.encoding)
- self.w(stream)
- os.unlink(mapfile)
+ generator.generate(visitor, prophdlr, tmpfile)
+ with codecs.open(tmpfile, 'rb', encoding='utf-8') as svgfile:
+ self.w(svgfile.read())
def build_visitor(self, entity):
raise NotImplementedError
--- a/web/views/schema.py Thu Dec 12 16:17:25 2013 +0100
+++ b/web/views/schema.py Mon Jan 06 12:01:35 2014 +0100
@@ -24,6 +24,7 @@
import tempfile
import os, os.path as osp
+import codecs
from logilab.common.graph import GraphGenerator, DotBackend
from logilab.common.ureports import Section, Table
@@ -40,7 +41,6 @@
from cubicweb.view import EntityView, StartupView
from cubicweb import tags, uilib
from cubicweb.web import action, facet, schemaviewer
-from cubicweb.web.views import TmpFileViewMixin
from cubicweb.web.views import uicfg, primary, baseviews, tabs, tableview, ibreadcrumbs
ALWAYS_SKIP_TYPES = BASE_TYPES | SCHEMA_TYPES
@@ -625,6 +625,8 @@
__regid__ = 'schemagraph'
def call(self, etype=None, rtype=None, alt=''):
+ if 'MSIE 8' in self._cw.useragent():
+ return
schema = self._cw.vreg.schema
if etype:
assert rtype is None
@@ -652,22 +654,12 @@
'splines':'true',
'sep':'0.2',
}))
- # map file
- pmap, mapfile = tempfile.mkstemp(".map")
- os.close(pmap)
- # image file
- fd, tmpfile = tempfile.mkstemp('.png')
+ # svg image file
+ fd, tmpfile = tempfile.mkstemp('.svg')
os.close(fd)
- generator.generate(visitor, prophdlr, tmpfile, mapfile)
- filekeyid = make_uid()
- self._cw.session.data[filekeyid] = tmpfile
- self.w(u'<img src="%s" alt="%s" usemap="#schema" />' % (
- xml_escape(self._cw.build_url(vid='tmppng', tmpfile=filekeyid)),
- xml_escape(self._cw._(alt))))
- stream = open(mapfile, 'r').read()
- stream = stream.decode(self._cw.encoding)
- self.w(stream)
- os.unlink(mapfile)
+ generator.generate(visitor, prophdlr, tmpfile)
+ with codecs.open(tmpfile, 'rb', encoding='utf-8') as svgfile:
+ self.w(svgfile.read())
# breadcrumbs ##################################################################
--- a/web/views/workflow.py Thu Dec 12 16:17:25 2013 +0100
+++ b/web/views/workflow.py Mon Jan 06 12:01:35 2014 +0100
@@ -29,6 +29,7 @@
from logilab.mtconverter import xml_escape
from logilab.common.graph import escape
+from logilab.common.deprecation import class_deprecated
from cubicweb import Unauthorized
from cubicweb.predicates import (has_related_entities, one_line_rset,
@@ -436,6 +437,8 @@
class TmpPngView(TmpFileViewMixin, EntityView):
+ __metaclass__ = class_deprecated
+ __deprecation_warning__ = '[3.18] %(cls)s is deprecated'
__regid__ = 'tmppng'
__select__ = match_form_params('tmpfile')
content_type = 'image/png'