1"""Copyright 2008 Orbitz WorldWide 2 3Licensed under the Apache License, Version 2.0 (the "License"); 4you may not use this file except in compliance with the License. 5You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9Unless required by applicable law or agreed to in writing, software 10distributed under the License is distributed on an "AS IS" BASIS, 11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12See the License for the specific language governing permissions and 13limitations under the License.""" 14 15import re 16 17from django.conf import settings 18from django.shortcuts import render 19from django.utils.safestring import mark_safe 20from django.utils.html import escape 21from graphite.account.models import Profile 22from graphite.compat import HttpResponse 23from graphite.user_util import getProfile, getProfileByUsername 24from graphite.util import json 25from graphite.logger import log 26from hashlib import md5 27 28 29def header(request): 30 "View for the header frame of the browser UI" 31 context = {} 32 context['user'] = request.user 33 context['profile'] = getProfile(request) 34 context['documentation_url'] = settings.DOCUMENTATION_URL 35 context['login_url'] = settings.LOGIN_URL 36 return render(request, "browserHeader.html", context) 37 38 39def browser(request): 40 "View for the top-level frame of the browser UI" 41 context = { 42 'queryString': mark_safe(request.GET.urlencode()), 43 'target': request.GET.get('target') 44 } 45 if context['queryString']: 46 context['queryString'] = context['queryString'].replace('#','%23') 47 if context['target']: 48 context['target'] = context['target'].replace('#','%23') #js libs terminate a querystring on # 49 return render(request, "browser.html", context) 50 51 52def search(request): 53 query = request.POST.get('query') 54 if not query: 55 return HttpResponse("") 56 57 patterns = query.split() 58 regexes = [re.compile(p,re.I) for p in patterns] 59 60 def matches(s): 61 for regex in regexes: 62 if regex.search(s): 63 return True 64 return False 65 66 results = [] 67 68 index_file = open(settings.INDEX_FILE) 69 for line in index_file: 70 if matches(line): 71 results.append( line.strip() ) 72 if len(results) >= 100: 73 break 74 75 index_file.close() 76 result_string = ','.join(results) 77 return HttpResponse(result_string, content_type='text/plain') 78 79 80def myGraphLookup(request): 81 "View for My Graphs navigation" 82 profile = getProfile(request,allowDefault=False) 83 assert profile 84 85 nodes = [] 86 leafNode = { 87 'allowChildren' : 0, 88 'expandable' : 0, 89 'leaf' : 1, 90 } 91 branchNode = { 92 'allowChildren' : 1, 93 'expandable' : 1, 94 'leaf' : 0, 95 } 96 97 try: 98 path = request.GET.get('path', u'') 99 100 if path: 101 if path.endswith('.'): 102 userpath_prefix = path 103 104 else: 105 userpath_prefix = path + '.' 106 107 else: 108 userpath_prefix = u"" 109 110 matches = [ graph for graph in profile.mygraph_set.all().order_by('name') if graph.name.startswith(userpath_prefix) ] 111 112 log.info( "myGraphLookup: username=%s, path=%s, userpath_prefix=%s, %ld graph to process" % (profile.user.username, path, userpath_prefix, len(matches)) ) 113 branch_inserted = set() 114 leaf_inserted = set() 115 116 for graph in matches: #Now let's add the matching graph 117 isBranch = False 118 dotPos = graph.name.find( '.', len(userpath_prefix) ) 119 120 if dotPos >= 0: 121 isBranch = True 122 name = graph.name[ len(userpath_prefix) : dotPos ] 123 if name in branch_inserted: continue 124 branch_inserted.add(name) 125 126 else: 127 name = graph.name[ len(userpath_prefix): ] 128 if name in leaf_inserted: continue 129 leaf_inserted.add(name) 130 131 node = {'text': escape(name)} 132 133 if isBranch: 134 node.update({'id': userpath_prefix + name + '.'}) 135 node.update(branchNode) 136 137 else: 138 m = md5() 139 m.update(name.encode('utf-8')) 140 node.update( { 'id' : str(userpath_prefix + m.hexdigest()), 'graphUrl' : graph.url } ) 141 node.update(leafNode) 142 143 nodes.append(node) 144 145 except Exception: 146 log.exception("browser.views.myGraphLookup(): could not complete request.") 147 148 if not nodes: 149 no_graphs = { 'text' : "No saved graphs", 'id' : 'no-click' } 150 no_graphs.update(leafNode) 151 nodes.append(no_graphs) 152 153 return json_response(nodes, request) 154 155 156def userGraphLookup(request): 157 "View for User Graphs navigation" 158 user = request.GET.get('user') 159 path = request.GET['path'] 160 161 if user: 162 username = user 163 graphPath = path[len(username)+1:] 164 elif '.' in path: 165 username, graphPath = path.split('.', 1) 166 else: 167 username, graphPath = path, None 168 169 nodes = [] 170 171 branchNode = { 172 'allowChildren' : 1, 173 'expandable' : 1, 174 'leaf' : 0, 175 } 176 leafNode = { 177 'allowChildren' : 0, 178 'expandable' : 0, 179 'leaf' : 1, 180 } 181 182 try: 183 184 if not username: 185 profiles = Profile.objects.exclude(user__username='default').order_by('user__username') 186 187 for profile in profiles: 188 if profile.mygraph_set.count(): 189 node = { 190 'text' : profile.user.username, 191 'id' : profile.user.username, 192 } 193 194 node.update(branchNode) 195 nodes.append(node) 196 197 else: 198 profile = getProfileByUsername(username) 199 assert profile, "No profile for username '%s'" % username 200 201 if graphPath: 202 prefix = graphPath.rstrip('.') + '.' 203 else: 204 prefix = '' 205 206 matches = [ graph for graph in profile.mygraph_set.order_by('name') if graph.name.startswith(prefix) ] 207 inserted = set() 208 209 for graph in matches: 210 relativePath = graph.name[ len(prefix): ] 211 nodeName = relativePath.split('.')[0] 212 213 if nodeName in inserted: 214 continue 215 inserted.add(nodeName) 216 217 if '.' in relativePath: # branch 218 node = { 219 'text' : escape(nodeName), 220 'id' : username + '.' + prefix + nodeName + '.', 221 } 222 node.update(branchNode) 223 else: # leaf 224 m = md5() 225 m.update(nodeName.encode('utf-8')) 226 227 node = { 228 'text' : escape(nodeName), 229 'id' : username + '.' + prefix + m.hexdigest(), 230 'graphUrl' : graph.url, 231 } 232 node.update(leafNode) 233 234 nodes.append(node) 235 236 except Exception: 237 log.exception("browser.views.userLookup(): could not complete request for %s" % username) 238 239 if not nodes: 240 no_graphs = { 'text' : "No saved graphs", 'id' : 'no-click' } 241 no_graphs.update(leafNode) 242 nodes.append(no_graphs) 243 244 nodes.sort(key=lambda node: node['allowChildren'], reverse = True) 245 246 return json_response(nodes, request) 247 248 249def json_response(nodes, request=None): 250 if request: 251 jsonp = request.GET.get('jsonp', False) or request.POST.get('jsonp', False) 252 else: 253 jsonp = False 254 #json = str(nodes) #poor man's json encoder for simple types 255 json_data = json.dumps(nodes) 256 if jsonp: 257 response = HttpResponse("%s(%s)" % (jsonp, json_data), 258 content_type="text/javascript") 259 else: 260 response = HttpResponse(json_data, content_type="application/json") 261 response['Pragma'] = 'no-cache' 262 response['Cache-Control'] = 'no-cache' 263 return response 264