Skip to content

Commit f1dcfca

Browse files
committed
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. Commit ready for merge. - Legacy-Id: 10623
1 parent b23952c commit f1dcfca

4 files changed

Lines changed: 46 additions & 40 deletions

File tree

ietf/group/info.py

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,9 @@ def construct_group_menu_context(request, group, selected, group_type, others):
336336
entries.append(("Email expansions", urlreverse("ietf.group.info.email", kwargs=kwargs)))
337337
entries.append(("History", urlreverse("ietf.group.info.history", kwargs=kwargs)))
338338
if group.features.has_documents:
339-
entries.append((mark_safe("Dependency graph »"), urlreverse("ietf.group.info.dependencies_pdf", kwargs=kwargs)))
339+
kwargs["output_type"] = "svg"
340+
entries.append((mark_safe("Dependency graph »"), urlreverse("ietf.group.info.dependencies", kwargs=kwargs)))
341+
del kwargs["output_type"]
340342

341343
if group.list_archive.startswith("http:") or group.list_archive.startswith("https:") or group.list_archive.startswith("ftp:"):
342344
entries.append((mark_safe("List archive »"), group.list_archive))
@@ -656,50 +658,44 @@ def make_dot(group):
656658
dict( nodes=nodes, edges=edges )
657659
)
658660

659-
def dependencies_dot(request, acronym, group_type=None):
661+
@cache_page(60 * 60)
662+
def dependencies(request, acronym, group_type=None, output_type="pdf"):
660663
group = get_group_or_404(acronym, group_type)
661664
if not group.features.has_documents:
662665
raise Http404
663666

664-
return HttpResponse(make_dot(group),
665-
content_type='text/plain; charset=UTF-8'
666-
)
667-
668-
@cache_page ( 60 * 60 )
669-
def dependencies_pdf(request, acronym, group_type=None):
670-
group = get_group_or_404(acronym, group_type)
671-
if not group.features.has_documents:
672-
raise Http404
673-
674-
dothandle,dotname = mkstemp()
667+
dothandle, dotname = mkstemp()
675668
os.close(dothandle)
676-
dotfile = open(dotname,"w")
669+
dotfile = open(dotname, "w")
677670
dotfile.write(make_dot(group))
678671
dotfile.close()
679672

680-
unflathandle,unflatname = mkstemp()
681-
os.close(unflathandle)
673+
if (output_type == "dot"):
674+
return HttpResponse(make_dot(group),
675+
content_type='text/plain; charset=UTF-8'
676+
)
682677

683-
pshandle,psname = mkstemp()
684-
os.close(pshandle)
678+
unflathandle, unflatname = mkstemp()
679+
os.close(unflathandle)
680+
outhandle, outname = mkstemp()
681+
os.close(outhandle)
685682

686-
pdfhandle,pdfname = mkstemp()
687-
os.close(pdfhandle)
683+
pipe("%s -f -l 10 -o %s %s" % (settings.UNFLATTEN_BINARY, unflatname, dotname))
684+
pipe("%s -T%s -o %s %s" % (settings.DOT_BINARY, output_type, outname, unflatname))
688685

689-
pipe("%s -f -l 10 -o %s %s" % (settings.UNFLATTEN_BINARY,unflatname,dotname))
690-
pipe("%s -Tps -Gsize=10.5,8.0 -Gmargin=0.25 -Gratio=auto -Grotate=90 -o %s %s" % (settings.DOT_BINARY,psname,unflatname))
691-
pipe("%s %s %s" % (settings.PS2PDF_BINARY,psname,pdfname))
692-
693-
pdfhandle = open(pdfname,"r")
694-
pdf = pdfhandle.read()
695-
pdfhandle.close()
686+
outhandle = open(outname, "r")
687+
out = outhandle.read()
688+
outhandle.close()
696689

697-
os.unlink(pdfname)
698-
os.unlink(psname)
690+
os.unlink(outname)
699691
os.unlink(unflatname)
700692
os.unlink(dotname)
701693

702-
return HttpResponse(pdf, content_type='application/pdf')
694+
if (output_type == "pdf"):
695+
output_type = "application/pdf"
696+
elif (output_type == "svg"):
697+
output_type = "image/svg+xml"
698+
return HttpResponse(out, content_type=output_type)
703699

704700
def email_aliases(request, acronym=None, group_type=None):
705701
group = get_group_or_404(acronym,group_type) if acronym else None

ietf/group/tests.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
skip_dot_to_pdf = True
1515
skip_message = "settings.SKIP_DOT_TO_PDF = %s" % skip_dot_to_pdf
1616
elif ( os.path.exists(settings.DOT_BINARY) and
17-
os.path.exists(settings.UNFLATTEN_BINARY) and
18-
os.path.exists(settings.PS2PDF_BINARY)):
17+
os.path.exists(settings.UNFLATTEN_BINARY)):
1918
skip_dot_to_pdf = False
2019
skip_message = ""
2120
else:
@@ -62,9 +61,9 @@ class GroupTests(TestCase):
6261
def test_group_document_dependency_dotfile(self):
6362
make_test_data()
6463
for group in Group.objects.filter(Q(type="wg") | Q(type="rg")):
65-
client = Client(Accept='application/pdf')
66-
for url in [ urlreverse("ietf.group.info.dependencies_dot",kwargs=dict(acronym=group.acronym)),
67-
urlreverse("ietf.group.info.dependencies_dot",kwargs=dict(acronym=group.acronym,group_type=group.type_id)),
64+
client = Client(Accept='text/plain')
65+
for url in [ urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,output_type="dot")),
66+
urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,group_type=group.type_id,output_type="dot")),
6867
]:
6968
r = client.get(url)
7069
self.assertTrue(r.status_code == 200, "Failed to receive "
@@ -76,12 +75,25 @@ def test_group_document_dependency_pdffile(self):
7675
make_test_data()
7776
for group in Group.objects.filter(Q(type="wg") | Q(type="rg")):
7877
client = Client(Accept='application/pdf')
79-
for url in [ urlreverse("ietf.group.info.dependencies_pdf",kwargs=dict(acronym=group.acronym)),
80-
urlreverse("ietf.group.info.dependencies_pdf",kwargs=dict(acronym=group.acronym,group_type=group.type_id)),
78+
for url in [ urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,output_type="pdf")),
79+
urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,group_type=group.type_id,output_type="pdf")),
8180
]:
8281
r = client.get(url)
8382
self.assertTrue(r.status_code == 200, "Failed to receive "
8483
"a pdf dependency graph for group: %s"%group.acronym)
8584
self.assertGreater(len(r.content), 0, "Pdf dependency graph for group "
8685
"%s has no content"%group.acronym)
86+
87+
def test_group_document_dependency_svgfile(self):
88+
make_test_data()
89+
for group in Group.objects.filter(Q(type="wg") | Q(type="rg")):
90+
client = Client(Accept='image/svg+xml')
91+
for url in [ urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,output_type="svg")),
92+
urlreverse("ietf.group.info.dependencies",kwargs=dict(acronym=group.acronym,group_type=group.type_id,output_type="svg")),
93+
]:
94+
r = client.get(url)
95+
self.assertTrue(r.status_code == 200, "Failed to receive "
96+
"a svg dependency graph for group: %s"%group.acronym)
97+
self.assertGreater(len(r.content), 0, "svg dependency graph for group "
98+
"%s has no content"%group.acronym)
8799

ietf/group/urls_info_details.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
(r'^about/$', 'ietf.group.info.group_about', None, 'group_about'),
1010
(r'^history/$','ietf.group.info.history'),
1111
(r'^email/$', 'ietf.group.info.email'),
12-
(r'^deps/dot/$', 'ietf.group.info.dependencies_dot'),
13-
(r'^deps/pdf/$', 'ietf.group.info.dependencies_pdf'),
12+
(r'^deps/(?P<output_type>[\w-]+)/$', 'ietf.group.info.dependencies'),
1413
(r'^init-charter/', 'ietf.group.edit.submit_initial_charter'),
1514
(r'^edit/$', 'ietf.group.edit.edit', {'action': "edit"}, "group_edit"),
1615
(r'^conclude/$', 'ietf.group.edit.conclude'),

ietf/settings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,6 @@ def skip_unreadable_post(record):
506506

507507
DOT_BINARY = '/usr/bin/dot'
508508
UNFLATTEN_BINARY= '/usr/bin/unflatten'
509-
PS2PDF_BINARY = '/usr/bin/ps2pdf'
510509
RSYNC_BINARY = '/usr/bin/rsync'
511510

512511
# Account settings

0 commit comments

Comments
 (0)