← Back to team overview

graphite-dev team mailing list archive

[Merge] lp:~bkjones/graphite/mailgraph into lp:graphite

 

jonesy has proposed merging lp:~bkjones/graphite/mailgraph into lp:graphite.

Requested reviews:
  graphite-dev (graphite-dev)

For more details, see:
https://code.launchpad.net/~bkjones/graphite/mailgraph/+merge/87665

I've implemented a change to the dashboard UI such that the 'Graph Operations' menu that appears when clicking on a graph now contains an 'Email' option. Clicking that pops up a form dialog which takes a number of email parameters (from, to, subject, and message). Clicking 'Send' will create an email, attach the graph itself as an attachment (not a link to the graph), and send the email. 

The changes are relatively isolated: I added a function to dashboard.js (though I obviously had to *alter* the part that adds the item to the menu), I added a url pattern to dashboard/urls.py, added a method to dashboard/views.py, and added a file dashboard/send_graph.py. 

A couple of folks in freenode #graphite thought it would be useful to submit this for inclusion in the main distribution. I have a working deployment that is a checkout of this branch, but please let me know if anything doesn't work properly. I'm also not a Django or Javascript guru, so extra eyeballs could be useful in uncovering anything that could be done in a more efficient manner. 


-- 
https://code.launchpad.net/~bkjones/graphite/mailgraph/+merge/87665
Your team graphite-dev is requested to review the proposed merge of lp:~bkjones/graphite/mailgraph into lp:graphite.
=== modified file 'webapp/content/js/dashboard.js'
--- webapp/content/js/dashboard.js	2011-12-05 06:10:16 +0000
+++ webapp/content/js/dashboard.js	2012-01-05 18:05:44 +0000
@@ -1525,6 +1525,12 @@
     }, {
       xtype: 'button',
       fieldLabel: "<span style='visibility: hidden'>",
+      text: 'Email',
+      width: 100,
+      handler: function () { menu.destroy(); mailGraph(record); }
+    }, {
+      xtype: 'button',
+      fieldLabel: "<span style='visibility: hidden'>",
       text: "Direct URL",
       width: 100,
       handler: function () {
@@ -1706,6 +1712,83 @@
   });
 }
 
+function mailGraph(record) {
+  mygraphParams = record.get('params');
+  mygraphParams['target'] = record.data['target'];
+  newparams = Ext.encode(Ext.apply(mygraphParams, defaultGraphParams));
+
+  var fromField = new Ext.form.TextField({
+    fieldLabel: "From",
+    name: 'sender',
+    width: 300,
+    allowBlank: false,
+  });
+
+  var toField = new Ext.form.TextField({
+    fieldLabel: "To",
+    name: 'recipients',
+    width: 300,
+    allowBlank: false,
+  });
+
+  var subjectField = new Ext.form.TextField({
+    fieldLabel: "Subject",
+    name: 'subject',
+    width: 300,
+    allowBlank: false,
+  });
+
+  var msgField = new Ext.form.TextArea({
+    fieldLabel: "Message",
+    name: 'message',
+    width: 300,
+    height: 75
+  });
+
+  var graphParamsField = new Ext.form.TextField({
+     name: 'graph_params',
+     hidden: true,
+     value: newparams
+  });
+
+  var contactForm = new Ext.form.FormPanel({
+    width: 300,
+    labelWidth: 90,
+    items: [fromField, toField, subjectField, msgField, graphParamsField],
+    buttons: [{
+      text: 'Cancel',
+      handler: function(){win.close();}
+    }, {
+         text: 'Send',
+         handler: function(){
+           if(contactForm.getForm().isValid()){
+             contactForm.getForm().submit({
+               url: '/dashboard/email',
+               waitMsg: 'Processing Request',
+               success: function (contactForm, response) {
+         console.log(response.result);
+                 win.close();
+               }
+             });
+           }
+         }
+     }]
+  });
+
+  var win;
+
+  win = new Ext.Window({
+    title: "Send graph via email",
+    width: 450,
+    height: 230,
+    resizable: true,
+    modal: true,
+    layout: 'fit',
+    items: [contactForm],
+  });
+  win.show();
+}
+
 
 function cloneGraph(record) {
   var index = graphStore.indexOf(record);

=== added file 'webapp/graphite/dashboard/send_graph.py'
--- webapp/graphite/dashboard/send_graph.py	1970-01-01 00:00:00 +0000
+++ webapp/graphite/dashboard/send_graph.py	2012-01-05 18:05:44 +0000
@@ -0,0 +1,20 @@
+from django.core.mail import EmailMessage
+from graphite.logger import log
+
+def send_graph_email(subject, sender, recipients, attachments=None, body=None):
+    """
+    :param str sender: sender's email address
+    :param list recipients: list of recipient emails
+    :param list attachments: list of triples of the form:
+        (filename, content, mimetype). See the django docs
+        https://docs.djangoproject.com/en/1.3/topics/email/#django.core.mail.EmailMessage
+    """
+    attachments = attachments or []
+    msg = EmailMessage(subject=subject, 
+		       from_email=sender, 
+                       to=recipients, 
+		       body=body,
+                       attachments=attachments)
+    msg.send()
+
+	

=== modified file 'webapp/graphite/dashboard/urls.py'
--- webapp/graphite/dashboard/urls.py	2011-07-20 04:55:09 +0000
+++ webapp/graphite/dashboard/urls.py	2012-01-05 18:05:44 +0000
@@ -5,6 +5,7 @@
   ('^load/(?P<name>[^/]+)', 'load'),
   ('^delete/(?P<name>[^/]+)', 'delete'),
   ('^create-temporary/?', 'create_temporary'),
+  ('^email', 'email'),
   ('^find/', 'find'),
   ('^help/', 'help'),
   ('^(?P<name>[^/]+)', 'dashboard'),

=== modified file 'webapp/graphite/dashboard/views.py'
--- webapp/graphite/dashboard/views.py	2011-08-13 08:20:38 +0000
+++ webapp/graphite/dashboard/views.py	2012-01-05 18:05:44 +0000
@@ -1,12 +1,16 @@
 import re
 import errno
+import json
 from os.path import getmtime, join, exists
+from urllib import urlencode
 from ConfigParser import ConfigParser
 from django.shortcuts import render_to_response
-from django.http import HttpResponse
+from django.http import HttpResponse, QueryDict
 from django.conf import settings
 from graphite.util import json
 from graphite.dashboard.models import Dashboard
+from graphite.render.views import renderView
+from send_graph import send_graph_email
 
 
 fieldRegex = re.compile(r'<([^>]+)>')
@@ -202,6 +206,31 @@
   context = {}
   return render_to_response("dashboardHelp.html", context)
 
+def email(request):
+    sender = request.POST['sender']
+    recipients = request.POST['recipients'].split()
+    subject = request.POST['subject']
+    message = request.POST['message']
+
+    # these need to be passed to the render function in an HTTP request.
+    graph_params = json.loads(request.POST['graph_params'], parse_int=str)
+    target = QueryDict(graph_params.pop('target'))
+    graph_params = QueryDict(urlencode(graph_params))
+
+    new_post = request.POST.copy()
+    new_post.update(graph_params)
+    new_post.update(target)
+    request.POST = new_post
+
+    resp = renderView(request)
+    img = resp.content
+
+    if img:
+        attachments = [('graph.png', img, 'image/png')]
+        send_graph_email(subject, sender, recipients, attachments, message)
+
+    return json_response(dict(success=True))
+
 
 def create_temporary(request):
   state = str( json.dumps( json.loads( request.POST['state'] ) ) )