| Scott Baker | a3cd261 | 2015-02-26 17:06:46 -0800 | [diff] [blame] | 1 | from django.http import HttpResponse |
| 2 | from django.views.generic import TemplateView, View |
| 3 | from django import template |
| 4 | from monitor import driver |
| 5 | from core.models import * |
| 6 | import json |
| 7 | import os |
| 8 | import time |
| Scott Baker | b58973a | 2015-04-27 16:00:27 -0700 | [diff] [blame] | 9 | import tempfile |
| Scott Baker | a3cd261 | 2015-02-26 17:06:46 -0800 | [diff] [blame] | 10 | |
| 11 | class ServiceGridView(TemplateView): |
| 12 | head_template = r"""{% extends "admin/dashboard/dashboard_base.html" %} |
| 13 | {% load admin_static %} |
| 14 | {% block content %} |
| 15 | """ |
| 16 | |
| 17 | tail_template = r"{% endblock %}" |
| 18 | |
| 19 | def get(self, request, name="root", *args, **kwargs): |
| 20 | head_template = self.head_template |
| 21 | tail_template = self.tail_template |
| 22 | |
| Scott Baker | ed99f8e | 2015-06-10 15:47:30 -0700 | [diff] [blame] | 23 | html = '<table class="service-grid"><tr>' |
| Scott Baker | a3cd261 | 2015-02-26 17:06:46 -0800 | [diff] [blame] | 24 | |
| Scott Baker | b58973a | 2015-04-27 16:00:27 -0700 | [diff] [blame] | 25 | icons=[] |
| Scott Baker | a3cd261 | 2015-02-26 17:06:46 -0800 | [diff] [blame] | 26 | for service in Service.objects.all(): |
| Scott Baker | a3cd261 | 2015-02-26 17:06:46 -0800 | [diff] [blame] | 27 | view_url = service.view_url |
| 28 | if (not view_url): |
| 29 | view_url = "/admin/core/service/$id$/" |
| 30 | view_url = view_url.replace("$id$", str(service.id)) |
| 31 | |
| 32 | image_url = service.icon_url |
| 33 | if (not image_url): |
| 34 | image_url = "/static/primarycons_blue/gear_2.png" |
| 35 | |
| Scott Baker | b58973a | 2015-04-27 16:00:27 -0700 | [diff] [blame] | 36 | icons.append( {"name": service.name, "view_url": view_url, "image_url": image_url} ) |
| 37 | |
| 38 | icons.append( {"name": "Tenancy Graph", "view_url": "/serviceGraph.png", "image_url": "/static/primarycons_blue/service_graph.png", "horiz_rule": True} ) |
| 39 | icons.append( {"name": "Add Service", "view_url": "/admin/core/service/add/", "image_url": "/static/primarycons_blue/plus.png"} ) |
| 40 | |
| 41 | i=0 |
| 42 | for icon in icons: |
| 43 | if icon.get("horiz_rule", False): |
| 44 | html = html + "</tr><tr><td colspan=4><hr></td></tr><tr>" |
| 45 | i=0 |
| 46 | |
| 47 | service_name = icon["name"] |
| 48 | view_url = icon["view_url"] |
| 49 | image_url = icon["image_url"] |
| 50 | |
| 51 | if (i%4) == 0: |
| 52 | html = html + '</tr><tr>' |
| 53 | |
| Scott Baker | ed99f8e | 2015-06-10 15:47:30 -0700 | [diff] [blame] | 54 | html = html + '<td width=96 height=128 valign=top align=center><a class="service-grid-icon" href="%s"><img src="%s" height=64 width=64></img></a>' % (view_url, image_url) |
| 55 | html = html + '<p><a class="service-grid-icon-link" href="%s">%s</a></p></td>' % (view_url, service_name) |
| Scott Baker | a3cd261 | 2015-02-26 17:06:46 -0800 | [diff] [blame] | 56 | i=i+1 |
| 57 | |
| 58 | html = html + '</tr></table>' |
| 59 | |
| 60 | t = template.Template(head_template + html + self.tail_template) |
| 61 | |
| 62 | response_kwargs = {} |
| 63 | response_kwargs.setdefault('content_type', self.content_type) |
| 64 | return self.response_class( |
| 65 | request = request, |
| 66 | template = t, |
| 67 | **response_kwargs) |
| 68 | |
| Scott Baker | b58973a | 2015-04-27 16:00:27 -0700 | [diff] [blame] | 69 | class ServiceGraphViewOld(TemplateView): |
| 70 | # this attempt used networkx |
| 71 | # yum -y install python-matplotlib python-networkx |
| 72 | # pip-python install -upgrade networkx |
| 73 | # pip-python install graphviz pygraphviz |
| Scott Baker | a3cd261 | 2015-02-26 17:06:46 -0800 | [diff] [blame] | 74 | |
| Scott Baker | b58973a | 2015-04-27 16:00:27 -0700 | [diff] [blame] | 75 | def get(self, request, name="root", *args, **kwargs): |
| 76 | import networkx as nx |
| 77 | import matplotlib as mpl |
| 78 | mpl.use("Agg") |
| 79 | import matplotlib.pyplot as plt |
| 80 | import nxedges |
| 81 | |
| 82 | plt.figure(figsize=(10,8)) |
| 83 | |
| 84 | g = nx.DiGraph() |
| 85 | |
| 86 | labels = {} |
| 87 | for service in Service.objects.all(): |
| 88 | g.add_node(service.id) |
| 89 | if len(service.name)>8: |
| 90 | labels[service.id] = service.name[:8] + "\n" + service.name[8:] |
| 91 | else: |
| 92 | labels[service.id] = service.name |
| 93 | |
| 94 | for tenant in CoarseTenant.objects.all(): |
| 95 | if (not tenant.provider_service) or (not tenant.subscriber_service): |
| 96 | continue |
| 97 | g.add_edge(tenant.subscriber_service.id, tenant.provider_service.id) |
| 98 | |
| 99 | pos = nx.graphviz_layout(g) |
| 100 | nxedges.xos_draw_networkx_edges(g,pos,arrow_len=30) |
| 101 | nx.draw_networkx_nodes(g,pos,node_size=5000) |
| 102 | nx.draw_networkx_labels(g,pos,labels,font_size=12) |
| 103 | #plt.axis('off') |
| 104 | plt.savefig("/tmp/foo.png") |
| 105 | |
| 106 | return HttpResponse(open("/tmp/foo.png","r").read(), content_type="image/png") |
| 107 | |
| 108 | class ServiceGraphView(TemplateView): |
| 109 | # this attempt just uses graphviz directly |
| 110 | # yum -y install graphviz |
| 111 | # pip-python install pygraphviz |
| 112 | |
| 113 | def get(self, request, name="root", *args, **kwargs): |
| 114 | import pygraphviz as pgv |
| 115 | |
| 116 | g = pgv.AGraph(directed=True) |
| 117 | g.graph_attr.update(size="8,4!") |
| 118 | g.graph_attr.update(dpi="100") |
| 119 | #g.graph_attr.update(nodesep="2.5") |
| 120 | g.graph_attr.update(overlap="false") |
| 121 | g.graph_attr.update(graphdir="TB") |
| 122 | |
| 123 | for service in Service.objects.all(): |
| Scott Baker | a0306ec | 2015-10-21 16:04:46 -0700 | [diff] [blame] | 124 | provided_tenants = Tenant.objects.filter(provider_service=service, subscriber_service__isnull=False) |
| 125 | subscribed_tenants = Tenant.objects.filter(subscriber_service=service, provider_service__isnull=False) |
| Scott Baker | b58973a | 2015-04-27 16:00:27 -0700 | [diff] [blame] | 126 | if not (provided_tenants or subscribed_tenants): |
| 127 | # nodes with no edges aren't interesting |
| 128 | continue |
| 129 | g.add_node(service.id, label=service.name) |
| 130 | |
| Scott Baker | a0306ec | 2015-10-21 16:04:46 -0700 | [diff] [blame] | 131 | for tenant in Tenant.objects.all(): |
| Scott Baker | b58973a | 2015-04-27 16:00:27 -0700 | [diff] [blame] | 132 | if (not tenant.provider_service) or (not tenant.subscriber_service): |
| 133 | continue |
| 134 | g.add_edge(tenant.subscriber_service.id, tenant.provider_service.id) |
| 135 | |
| 136 | tf = tempfile.TemporaryFile() |
| 137 | g.layout(prog="dot") |
| 138 | g.draw(path=tf, format="png") |
| 139 | tf.seek(0) |
| 140 | |
| 141 | return HttpResponse(tf.read(), content_type="image/png") |