From 4bc31b9856144c3bd56183a7b360a79526a67071 Mon Sep 17 00:00:00 2001 From: Henrik Levkowetz Date: Tue, 12 Jan 2016 17:14:11 +0000 Subject: [PATCH] Merged in [10623] from lars@netapp.com: Simplify the dependency graph generation, by relying on dot to generate PDF (and now also SVG) directly. Default to showing SVG from the link on a group's page. - Legacy-Id: 10650 Note: SVN reference [10623] has been migrated to Git commit f1dcfcafb61bcda355353600730632c212b3a1e6 --- ietf/group/info.py | 56 +++++++++++++++------------------ ietf/group/tests.py | 26 ++++++++++----- ietf/group/urls_info_details.py | 3 +- ietf/settings.py | 1 - 4 files changed, 46 insertions(+), 40 deletions(-) diff --git a/ietf/group/info.py b/ietf/group/info.py index 8a9f5c564..19bbff6d3 100644 --- a/ietf/group/info.py +++ b/ietf/group/info.py @@ -336,7 +336,9 @@ def construct_group_menu_context(request, group, selected, group_type, others): entries.append(("Email expansions", urlreverse("ietf.group.info.email", kwargs=kwargs))) entries.append(("History", urlreverse("ietf.group.info.history", kwargs=kwargs))) if group.features.has_documents: - entries.append((mark_safe("Dependency graph »"), urlreverse("ietf.group.info.dependencies_pdf", kwargs=kwargs))) + kwargs["output_type"] = "svg" + entries.append((mark_safe("Dependency graph »"), urlreverse("ietf.group.info.dependencies", kwargs=kwargs))) + del kwargs["output_type"] if group.list_archive.startswith("http:") or group.list_archive.startswith("https:") or group.list_archive.startswith("ftp:"): entries.append((mark_safe("List archive »"), group.list_archive)) @@ -656,50 +658,44 @@ def make_dot(group): dict( nodes=nodes, edges=edges ) ) -def dependencies_dot(request, acronym, group_type=None): +@cache_page(60 * 60) +def dependencies(request, acronym, group_type=None, output_type="pdf"): group = get_group_or_404(acronym, group_type) if not group.features.has_documents: raise Http404 - return HttpResponse(make_dot(group), - content_type='text/plain; charset=UTF-8' - ) - -@cache_page ( 60 * 60 ) -def dependencies_pdf(request, acronym, group_type=None): - group = get_group_or_404(acronym, group_type) - if not group.features.has_documents: - raise Http404 - - dothandle,dotname = mkstemp() + dothandle, dotname = mkstemp() os.close(dothandle) - dotfile = open(dotname,"w") + dotfile = open(dotname, "w") dotfile.write(make_dot(group)) dotfile.close() - unflathandle,unflatname = mkstemp() + if (output_type == "dot"): + return HttpResponse(make_dot(group), + content_type='text/plain; charset=UTF-8' + ) + + unflathandle, unflatname = mkstemp() os.close(unflathandle) + outhandle, outname = mkstemp() + os.close(outhandle) - pshandle,psname = mkstemp() - os.close(pshandle) + pipe("%s -f -l 10 -o %s %s" % (settings.UNFLATTEN_BINARY, unflatname, dotname)) + pipe("%s -T%s -o %s %s" % (settings.DOT_BINARY, output_type, outname, unflatname)) - pdfhandle,pdfname = mkstemp() - os.close(pdfhandle) + outhandle = open(outname, "r") + out = outhandle.read() + outhandle.close() - pipe("%s -f -l 10 -o %s %s" % (settings.UNFLATTEN_BINARY,unflatname,dotname)) - pipe("%s -Tps -Gsize=10.5,8.0 -Gmargin=0.25 -Gratio=auto -Grotate=90 -o %s %s" % (settings.DOT_BINARY,psname,unflatname)) - pipe("%s %s %s" % (settings.PS2PDF_BINARY,psname,pdfname)) - - pdfhandle = open(pdfname,"r") - pdf = pdfhandle.read() - pdfhandle.close() - - os.unlink(pdfname) - os.unlink(psname) + os.unlink(outname) os.unlink(unflatname) os.unlink(dotname) - return HttpResponse(pdf, content_type='application/pdf') + if (output_type == "pdf"): + output_type = "application/pdf" + elif (output_type == "svg"): + output_type = "image/svg+xml" + return HttpResponse(out, content_type=output_type) def email_aliases(request, acronym=None, group_type=None): group = get_group_or_404(acronym,group_type) if acronym else None diff --git a/ietf/group/tests.py b/ietf/group/tests.py index 03ffd8713..f00a01362 100644 --- a/ietf/group/tests.py +++ b/ietf/group/tests.py @@ -17,8 +17,7 @@ if getattr(settings,'SKIP_DOT_TO_PDF', False): skip_dot_to_pdf = True skip_message = "settings.SKIP_DOT_TO_PDF = %s" % skip_dot_to_pdf elif ( os.path.exists(settings.DOT_BINARY) and - os.path.exists(settings.UNFLATTEN_BINARY) and - os.path.exists(settings.PS2PDF_BINARY)): + os.path.exists(settings.UNFLATTEN_BINARY)): skip_dot_to_pdf = False skip_message = "" else: @@ -65,9 +64,9 @@ class GroupDocDependencyGraphTests(TestCase): def test_group_document_dependency_dotfile(self): make_test_data() for group in Group.objects.filter(Q(type="wg") | Q(type="rg")): - client = Client(Accept='application/pdf') - for url in [ urlreverse("ietf.group.info.dependencies_dot",kwargs=dict(acronym=group.acronym)), - urlreverse("ietf.group.info.dependencies_dot",kwargs=dict(acronym=group.acronym,group_type=group.type_id)), + client = Client(Accept='text/plain') + for url in [ urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,output_type="dot")), + urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,group_type=group.type_id,output_type="dot")), ]: r = client.get(url) self.assertTrue(r.status_code == 200, "Failed to receive " @@ -79,14 +78,27 @@ class GroupDocDependencyGraphTests(TestCase): make_test_data() for group in Group.objects.filter(Q(type="wg") | Q(type="rg")): client = Client(Accept='application/pdf') - for url in [ urlreverse("ietf.group.info.dependencies_pdf",kwargs=dict(acronym=group.acronym)), - urlreverse("ietf.group.info.dependencies_pdf",kwargs=dict(acronym=group.acronym,group_type=group.type_id)), + for url in [ urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,output_type="pdf")), + urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,group_type=group.type_id,output_type="pdf")), ]: r = client.get(url) self.assertTrue(r.status_code == 200, "Failed to receive " "a pdf dependency graph for group: %s"%group.acronym) self.assertGreater(len(r.content), 0, "Pdf dependency graph for group " "%s has no content"%group.acronym) + + def test_group_document_dependency_svgfile(self): + make_test_data() + for group in Group.objects.filter(Q(type="wg") | Q(type="rg")): + client = Client(Accept='image/svg+xml') + for url in [ urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,output_type="svg")), + urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,group_type=group.type_id,output_type="svg")), + ]: + r = client.get(url) + self.assertTrue(r.status_code == 200, "Failed to receive " + "a svg dependency graph for group: %s"%group.acronym) + self.assertGreater(len(r.content), 0, "svg dependency graph for group " + "%s has no content"%group.acronym) class GroupRoleEmailTests(TestCase): diff --git a/ietf/group/urls_info_details.py b/ietf/group/urls_info_details.py index c0a97e9eb..9529c9577 100644 --- a/ietf/group/urls_info_details.py +++ b/ietf/group/urls_info_details.py @@ -9,8 +9,7 @@ urlpatterns = patterns('', (r'^about/$', 'ietf.group.info.group_about', None, 'group_about'), (r'^history/$','ietf.group.info.history'), (r'^email/$', 'ietf.group.info.email'), - (r'^deps/dot/$', 'ietf.group.info.dependencies_dot'), - (r'^deps/pdf/$', 'ietf.group.info.dependencies_pdf'), + (r'^deps/(?P[\w-]+)/$', 'ietf.group.info.dependencies'), (r'^init-charter/', 'ietf.group.edit.submit_initial_charter'), (r'^edit/$', 'ietf.group.edit.edit', {'action': "edit"}, "group_edit"), (r'^conclude/$', 'ietf.group.edit.conclude'), diff --git a/ietf/settings.py b/ietf/settings.py index 4fd829f5d..bdf6822e2 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -509,7 +509,6 @@ INTERNET_DRAFT_DAYS_TO_EXPIRE = 185 DOT_BINARY = '/usr/bin/dot' UNFLATTEN_BINARY= '/usr/bin/unflatten' -PS2PDF_BINARY = '/usr/bin/ps2pdf' RSYNC_BINARY = '/usr/bin/rsync' # Account settings