blob: 783a5e9788cf4cff3af8fb2430738248d2427e7c [file] [log] [blame]
Scott Bakerf8120702015-02-26 17:06:46 -08001from django.http import HttpResponse
2from django.views.generic import TemplateView, View
3from django import template
Scott Bakerf8120702015-02-26 17:06:46 -08004from core.models import *
Matteo Scandolof05cf362016-05-09 10:31:21 -07005from core.dashboard.views import DashboardDynamicView
6from xos.config import XOS_DIR
Scott Bakerf8120702015-02-26 17:06:46 -08007import json
8import os
9import time
Scott Baker9a42e6f2015-04-27 16:00:27 -070010import tempfile
Scott Bakerf8120702015-02-26 17:06:46 -080011
Matteo Scandolof05cf362016-05-09 10:31:21 -070012
Scott Bakerf8120702015-02-26 17:06:46 -080013class ServiceGridView(TemplateView):
Matteo Scandolof05cf362016-05-09 10:31:21 -070014
15 head_template = r"""{% extends "admin/dashboard/dashboard_base.html" %}
16 {% load admin_static %}
17 {% block content %}
18 """
19
20 tail_template = r"{% endblock %}"
21
22 def readTemplate(self, fn):
23 TEMPLATE_DIRS = [XOS_DIR + "/templates/admin/dashboard/",
24 XOS_DIR + "/core/xoslib/dashboards/"]
25
26 for template_dir in TEMPLATE_DIRS:
27 pathname = os.path.join(template_dir, fn) + ".html"
28 if os.path.exists(pathname):
29 break
30 else:
31 return "failed to find %s in %s" % (fn, TEMPLATE_DIRS)
32
33 template = open(pathname, "r").read()
34 return template
35
36 def get(self, request, name="root", *args, **kwargs):
37
Matteo Scandolof05cf362016-05-09 10:31:21 -070038 dash = DashboardView.objects.get(name="Services Grid")
39
40 gridTemplate = self.readTemplate(dash.url[9:])
41
42 t = template.Template(self.head_template + gridTemplate + self.tail_template)
43
44 response_kwargs = {}
45 response_kwargs.setdefault('content_type', self.content_type)
46
47 return self.response_class(
48 request=request,
49 template=t,
50 **response_kwargs)
51
52
53class ServiceGridViewPy(TemplateView):
Scott Bakerf8120702015-02-26 17:06:46 -080054 head_template = r"""{% extends "admin/dashboard/dashboard_base.html" %}
55 {% load admin_static %}
56 {% block content %}
57 """
58
59 tail_template = r"{% endblock %}"
60
61 def get(self, request, name="root", *args, **kwargs):
62 head_template = self.head_template
63 tail_template = self.tail_template
64
Scott Bakerb3500502015-06-10 15:47:30 -070065 html = '<table class="service-grid"><tr>'
Scott Bakerf8120702015-02-26 17:06:46 -080066
Scott Baker9a42e6f2015-04-27 16:00:27 -070067 icons=[]
Scott Bakerf8120702015-02-26 17:06:46 -080068 for service in Service.objects.all():
Scott Bakerf8120702015-02-26 17:06:46 -080069 view_url = service.view_url
70 if (not view_url):
71 view_url = "/admin/core/service/$id$/"
72 view_url = view_url.replace("$id$", str(service.id))
73
74 image_url = service.icon_url
75 if (not image_url):
76 image_url = "/static/primarycons_blue/gear_2.png"
77
Scott Baker9a42e6f2015-04-27 16:00:27 -070078 icons.append( {"name": service.name, "view_url": view_url, "image_url": image_url} )
79
80 icons.append( {"name": "Tenancy Graph", "view_url": "/serviceGraph.png", "image_url": "/static/primarycons_blue/service_graph.png", "horiz_rule": True} )
81 icons.append( {"name": "Add Service", "view_url": "/admin/core/service/add/", "image_url": "/static/primarycons_blue/plus.png"} )
82
83 i=0
84 for icon in icons:
85 if icon.get("horiz_rule", False):
86 html = html + "</tr><tr><td colspan=4><hr></td></tr><tr>"
87 i=0
88
89 service_name = icon["name"]
90 view_url = icon["view_url"]
91 image_url = icon["image_url"]
92
93 if (i%4) == 0:
94 html = html + '</tr><tr>'
95
Scott Bakerb3500502015-06-10 15:47:30 -070096 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)
97 html = html + '<p><a class="service-grid-icon-link" href="%s">%s</a></p></td>' % (view_url, service_name)
Scott Bakerf8120702015-02-26 17:06:46 -080098 i=i+1
99
100 html = html + '</tr></table>'
101
102 t = template.Template(head_template + html + self.tail_template)
103
104 response_kwargs = {}
105 response_kwargs.setdefault('content_type', self.content_type)
106 return self.response_class(
107 request = request,
108 template = t,
109 **response_kwargs)
110
Scott Baker9a42e6f2015-04-27 16:00:27 -0700111class ServiceGraphViewOld(TemplateView):
112 # this attempt used networkx
113 # yum -y install python-matplotlib python-networkx
114 # pip-python install -upgrade networkx
115 # pip-python install graphviz pygraphviz
Scott Bakerf8120702015-02-26 17:06:46 -0800116
Scott Baker9a42e6f2015-04-27 16:00:27 -0700117 def get(self, request, name="root", *args, **kwargs):
118 import networkx as nx
119 import matplotlib as mpl
120 mpl.use("Agg")
121 import matplotlib.pyplot as plt
122 import nxedges
123
124 plt.figure(figsize=(10,8))
125
126 g = nx.DiGraph()
127
128 labels = {}
129 for service in Service.objects.all():
130 g.add_node(service.id)
131 if len(service.name)>8:
132 labels[service.id] = service.name[:8] + "\n" + service.name[8:]
133 else:
134 labels[service.id] = service.name
135
136 for tenant in CoarseTenant.objects.all():
137 if (not tenant.provider_service) or (not tenant.subscriber_service):
138 continue
139 g.add_edge(tenant.subscriber_service.id, tenant.provider_service.id)
140
141 pos = nx.graphviz_layout(g)
142 nxedges.xos_draw_networkx_edges(g,pos,arrow_len=30)
143 nx.draw_networkx_nodes(g,pos,node_size=5000)
144 nx.draw_networkx_labels(g,pos,labels,font_size=12)
145 #plt.axis('off')
146 plt.savefig("/tmp/foo.png")
147
148 return HttpResponse(open("/tmp/foo.png","r").read(), content_type="image/png")
149
150class ServiceGraphView(TemplateView):
151 # this attempt just uses graphviz directly
152 # yum -y install graphviz
153 # pip-python install pygraphviz
154
155 def get(self, request, name="root", *args, **kwargs):
156 import pygraphviz as pgv
157
158 g = pgv.AGraph(directed=True)
159 g.graph_attr.update(size="8,4!")
160 g.graph_attr.update(dpi="100")
161 #g.graph_attr.update(nodesep="2.5")
162 g.graph_attr.update(overlap="false")
163 g.graph_attr.update(graphdir="TB")
164
165 for service in Service.objects.all():
Scott Bakerc6f0eb82015-10-21 16:04:46 -0700166 provided_tenants = Tenant.objects.filter(provider_service=service, subscriber_service__isnull=False)
167 subscribed_tenants = Tenant.objects.filter(subscriber_service=service, provider_service__isnull=False)
Scott Baker9a42e6f2015-04-27 16:00:27 -0700168 if not (provided_tenants or subscribed_tenants):
169 # nodes with no edges aren't interesting
170 continue
171 g.add_node(service.id, label=service.name)
172
Scott Bakerc6f0eb82015-10-21 16:04:46 -0700173 for tenant in Tenant.objects.all():
Scott Baker9a42e6f2015-04-27 16:00:27 -0700174 if (not tenant.provider_service) or (not tenant.subscriber_service):
175 continue
176 g.add_edge(tenant.subscriber_service.id, tenant.provider_service.id)
177
178 tf = tempfile.TemporaryFile()
179 g.layout(prog="dot")
180 g.draw(path=tf, format="png")
181 tf.seek(0)
182
183 return HttpResponse(tf.read(), content_type="image/png")