~lucio.torre/graphite/add-flot

« back to all changes in this revision

Viewing changes to webapp/graphite/graphlot/views.py

  • Committer: lucio.torre at gmail
  • Date: 2010-10-30 21:58:12 UTC
  • Revision ID: lucio.torre@gmail.com-20101030215812-g3al9ja7vp77u1tj
graphlot working

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import re
 
2
 
 
3
from django.shortcuts import render_to_response
 
4
from django.http import HttpResponse, Http404
 
5
from django.conf import settings
 
6
import simplejson
 
7
 
 
8
from graphite.render.views import parseOptions
 
9
from graphite.render.evaluator import evaluateTarget
 
10
 
 
11
 
 
12
def graphlot_render(request):
 
13
    """Render the main graphlot view."""
 
14
    metrics = []
 
15
    for target in request.GET.getlist('target'):
 
16
        metrics.append(dict(name=target, yaxis="one"))
 
17
    for target in request.GET.getlist('y2target'):
 
18
        metrics.append(dict(name=target, yaxis="two"))
 
19
 
 
20
    untiltime = request.GET.get('until', "-0hour")
 
21
    fromtime = request.GET.get('from', "-24hour")
 
22
    context = dict(metric_list=metrics, fromtime=fromtime, untiltime=untiltime)
 
23
    return render_to_response("graphlot.html", context)
 
24
 
 
25
def get_data(request):
 
26
    """Get the data for one series."""
 
27
    (graphOptions, requestOptions) = parseOptions(request)
 
28
    requestContext = {
 
29
        'startTime' : requestOptions['startTime'],
 
30
        'endTime' : requestOptions['endTime'],
 
31
        'data' : []
 
32
    }
 
33
    target = requestOptions['targets'][0]
 
34
    seriesList = evaluateTarget(requestContext, target)
 
35
    result = [ dict(
 
36
            name=timeseries.name,
 
37
            data=[ x for x in timeseries ],
 
38
            start=timeseries.start,
 
39
            end=timeseries.end,
 
40
            step=timeseries.step,
 
41
            ) for timeseries in seriesList ]
 
42
    if not result:
 
43
        raise Http404
 
44
    return HttpResponse(simplejson.dumps(result), mimetype="application/json")
 
45
 
 
46
def find_metric(request):
 
47
    """Autocomplete helper on metric names."""
 
48
    try:
 
49
        query = str( request.REQUEST['q'] )
 
50
    except:
 
51
        return HttpResponseBadRequest(
 
52
            content="Missing required parameter 'q'", mimetype="text/plain")
 
53
 
 
54
    store = settings.LOCAL_STORE
 
55
 
 
56
    matches = list( store.find(query+"*") )
 
57
    content = "\n".join([node.metric_path for node in matches ])
 
58
    response = HttpResponse(content, mimetype='text/plain')
 
59
 
 
60
    return response
 
61
 
 
62
def header(request):
 
63
  "View for the header frame of the browser UI"
 
64
  context = {}
 
65
  context['user'] = request.user
 
66
  context['profile'] = getProfile(request)
 
67
  context['documentation_url'] = settings.DOCUMENTATION_URL
 
68
  return render_to_response("browserHeader.html", context)
 
69
 
 
70
 
 
71
def browser(request):
 
72
  "View for the top-level frame of the browser UI"
 
73
  context = {
 
74
    'queryString' : request.GET.urlencode(),
 
75
    'target' : request.GET.get('target')
 
76
  }
 
77
  if context['queryString']:
 
78
    context['queryString'] = context['queryString'].replace('#','%23')
 
79
  if context['target']:
 
80
    context['target'] = context['target'].replace('#','%23') #js libs terminate a querystring on #
 
81
  return render_to_response("browser.html", context)
 
82
 
 
83
 
 
84
def search(request):
 
85
  query = request.POST['query']
 
86
  if not query:
 
87
    return HttpResponse("")
 
88
 
 
89
  patterns = query.split()
 
90
  regexes = [re.compile(p,re.I) for p in patterns]
 
91
  def matches(s):
 
92
    for regex in regexes:
 
93
      if regex.search(s):
 
94
        return True
 
95
    return False
 
96
 
 
97
  results = []
 
98
 
 
99
  index_file = open(settings.INDEX_FILE)
 
100
  for line in index_file:
 
101
    if matches(line):
 
102
      results.append( line.strip() )
 
103
    if len(results) >= 100:
 
104
      break
 
105
 
 
106
  index_file.close()
 
107
  result_string = ','.join(results)
 
108
  return HttpResponse(result_string, mimetype='text/plain')
 
109
 
 
110
 
 
111
def myGraphLookup(request):
 
112
  "View for My Graphs navigation"
 
113
  profile = getProfile(request,allowDefault=False)
 
114
  assert profile
 
115
 
 
116
  nodes = []
 
117
  leafNode = {
 
118
    'allowChildren' : 0,
 
119
    'expandable' : 0,
 
120
    'leaf' : 1,
 
121
  }
 
122
  branchNode = {
 
123
    'allowChildren' : 1,
 
124
    'expandable' : 1,
 
125
    'leaf' : 0,
 
126
  }
 
127
 
 
128
  try:
 
129
    path = str( request.GET['path'] )
 
130
 
 
131
    if path:
 
132
      if path.endswith('.'):
 
133
        userpath_prefix = path
 
134
 
 
135
      else:
 
136
        userpath_prefix = path + '.'
 
137
 
 
138
    else:
 
139
      userpath_prefix = ""
 
140
 
 
141
    matches = [ graph for graph in profile.mygraph_set.all().order_by('name') if graph.name.startswith(userpath_prefix) ]
 
142
 
 
143
    log.info( "myGraphLookup: username=%s, path=%s, userpath_prefix=%s, %ld graph to process" % (profile.user.username, path, userpath_prefix, len(matches)) )
 
144
    branch_inserted = set()
 
145
    leaf_inserted = set()
 
146
 
 
147
    for graph in matches: #Now let's add the matching graph
 
148
      isBranch = False
 
149
      dotPos = graph.name.find( '.', len(userpath_prefix) )
 
150
 
 
151
      if dotPos >= 0:
 
152
        isBranch = True
 
153
        name = graph.name[ len(userpath_prefix) : dotPos ]
 
154
        if name in branch_inserted: continue
 
155
        branch_inserted.add(name)
 
156
 
 
157
      else:
 
158
         name = graph.name[ len(userpath_prefix): ]
 
159
         if name in leaf_inserted: continue
 
160
         leaf_inserted.add(name)
 
161
 
 
162
      node = {'text' : str(name) }
 
163
 
 
164
      if isBranch:
 
165
        node.update( { 'id' : str(userpath_prefix + name + '.') } )
 
166
        node.update(branchNode)
 
167
 
 
168
      else:
 
169
        node.update( { 'id' : str(userpath_prefix + name), 'graphUrl' : str(graph.url) } )
 
170
        node.update(leafNode)
 
171
 
 
172
      nodes.append(node)
 
173
 
 
174
  except:
 
175
    log.exception("browser.views.myGraphLookup(): could not complete request.")
 
176
 
 
177
  if not nodes:
 
178
    no_graphs = { 'text' : "No saved graphs", 'id' : 'no-click' }
 
179
    no_graphs.update(leafNode)
 
180
    nodes.append(no_graphs)
 
181
 
 
182
  return json_response(nodes)
 
183
 
 
184
def userGraphLookup(request):
 
185
  "View for User Graphs navigation"
 
186
  username = request.GET['path']
 
187
  nodes = []
 
188
 
 
189
  branchNode = {
 
190
    'allowChildren' : 1,
 
191
    'expandable' : 1,
 
192
    'leaf' : 0,
 
193
  }
 
194
  leafNode = {
 
195
    'allowChildren' : 0,
 
196
    'expandable' : 0,
 
197
    'leaf' : 1,
 
198
  }
 
199
 
 
200
  try:
 
201
 
 
202
    if not username:
 
203
      profiles = Profile.objects.exclude(user=defaultUser)
 
204
 
 
205
      for profile in profiles:
 
206
        if profile.mygraph_set.count():
 
207
          node = {
 
208
            'text' : str(profile.user.username),
 
209
            'id' : str(profile.user.username)
 
210
          }
 
211
 
 
212
          node.update(branchNode)
 
213
          nodes.append(node)
 
214
 
 
215
    else:
 
216
      profile = getProfileByUsername(username)
 
217
      assert profile, "No profile for username '%s'" % username
 
218
 
 
219
      for graph in profile.mygraph_set.all().order_by('name'):
 
220
        node = {
 
221
          'text' : str(graph.name),
 
222
          'id' : str(graph.name),
 
223
          'graphUrl' : str(graph.url)
 
224
        }
 
225
        node.update(leafNode)
 
226
        nodes.append(node)
 
227
 
 
228
  except:
 
229
    log.exception("browser.views.userLookup(): could not complete request for %s" % username)
 
230
 
 
231
  if not nodes:
 
232
    no_graphs = { 'text' : "No saved graphs", 'id' : 'no-click' }
 
233
    no_graphs.update(leafNode)
 
234
    nodes.append(no_graphs)
 
235
 
 
236
  return json_response(nodes)
 
237
 
 
238
 
 
239
def json_response(nodes):
 
240
  #json = str(nodes) #poor man's json encoder for simple types
 
241
  json_data = json.dumps(nodes)
 
242
  response = HttpResponse(json_data,mimetype="application/json")
 
243
  response['Pragma'] = 'no-cache'
 
244
  response['Cache-Control'] = 'no-cache'
 
245
  return response
 
246
 
 
247
 
 
248
def any(iterable): #python2.4 compatibility
 
249
  for i in iterable:
 
250
    if i:
 
251
      return True
 
252
  return False