Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import jinja2 | |
| 6 import json | |
| 7 import os | |
| 8 import urllib | |
| 9 import webapp2 | |
| 10 | |
| 11 from google.appengine.ext import ndb | |
| 12 from google.appengine.ext import blobstore | |
| 13 from google.appengine.ext.webapp import blobstore_handlers | |
| 14 | |
| 15 | |
| 16 JINJA_ENVIRONMENT = jinja2.Environment( | |
| 17 loader=jinja2.FileSystemLoader(os.path.dirname(__file__)), | |
| 18 extensions=['jinja2.ext.autoescape']) | |
| 19 | |
| 20 | |
| 21 class Profiler(ndb.Model): | |
| 22 """Profiler entity to store json data. Use run_id as its key. | |
| 23 Json data will be stored at blobstore, but can be referred by BlobKey which | |
| 24 can be constructed by blob_str.""" | |
| 25 blob_str = ndb.StringProperty() | |
|
sullivan
2013/09/17 14:58:47
Why not ndb.BlobKeyProperty?
junjianx
2013/09/20 06:31:09
Done.
| |
| 26 | |
| 27 | |
| 28 class Template(ndb.Model): | |
| 29 """Template to breakdown profiler with multiple tags. | |
| 30 Use content as its key.""" | |
| 31 content = ndb.PickleProperty() | |
|
sullivan
2013/09/17 14:58:47
ndb.JsonProperty?
Also, isn't this redundant with
junjianx
2013/09/20 06:31:09
I replaced PickleProperty with JsonProperty.
But i
| |
| 32 tags = ndb.StringProperty(repeated=True) | |
|
sullivan
2013/09/17 14:58:47
Where are tags used?
junjianx
2013/09/20 06:31:09
Tag will be used in next issue to help user managi
| |
| 33 | |
| 34 | |
| 35 class MainPage(webapp2.RequestHandler): | |
| 36 """Show breakdown with received profiler-id and template-id. If nothing was | |
| 37 received, show blank page waiting user to upload file.""" | |
| 38 def get(self): | |
| 39 page_template = JINJA_ENVIRONMENT.get_template('index.html') | |
| 40 upload_url = blobstore.create_upload_url('/upload') | |
| 41 | |
| 42 # Get profiler id and template id from url query. | |
| 43 prof_id = self.request.get('prof_id') | |
| 44 tmpl_id = self.request.get('tmpl_id') | |
| 45 | |
| 46 template_values = { 'upload_url': upload_url } | |
| 47 | |
| 48 if not prof_id or not tmpl_id: | |
| 49 self.response.write(page_template.render(template_values)) | |
| 50 else: | |
| 51 # Get entity key. | |
| 52 prof_key = ndb.Key(urlsafe=prof_id) | |
|
sullivan
2013/09/17 14:58:47
It looks like it's also possible to construct a Pr
junjianx
2013/09/20 06:31:09
Done.
| |
| 53 tmpl_key = ndb.Key(urlsafe=tmpl_id) | |
| 54 | |
| 55 # Get entity object. | |
| 56 profiler = Profiler.query(ancestor=prof_key).get() | |
| 57 template = Template.query(ancestor=tmpl_key).get() | |
| 58 | |
| 59 # Use blob string to construct BlobKey. | |
| 60 blob_key = blobstore.BlobKey(profiler.blob_str) | |
| 61 template_values['json'] = blobstore.BlobReader(blob_key).read() | |
| 62 template_values['template'] = template.content | |
| 63 | |
| 64 self.response.write(page_template.render(template_values)) | |
| 65 | |
| 66 | |
| 67 class UploadHandler(blobstore_handlers.BlobstoreUploadHandler): | |
| 68 """Handle file uploading with BlobstoreUploadHandler. BlobstoreUploadHandler | |
| 69 can deal with files overweighing size limitation within one HTTP connection so | |
| 70 that user can upload large json file.""" | |
| 71 def post(self): | |
| 72 blob_info = self.get_uploads('file')[0] | |
| 73 json_file = blob_info.open().read() | |
| 74 json_data = json.loads(json_file) | |
| 75 | |
| 76 # Check the uniqueness of data run_id and store new one. | |
| 77 run_id = json_data['run_id'] | |
| 78 prof_key = ndb.Key('Profiler', run_id) | |
| 79 if Profiler.query(ancestor=prof_key).count() == 0: | |
| 80 profiler = Profiler(parent=prof_key) | |
| 81 profiler.blob_str = str(blob_info.key()) | |
| 82 profiler.put() | |
|
sullivan
2013/09/17 14:58:47
Did you mean to have a hierarchy of Profile object
junjianx
2013/09/20 06:31:09
Done.
| |
| 83 | |
| 84 # Check the uniqueness of template content and store new one. | |
| 85 for tag, content in json_data['templates'].iteritems(): | |
| 86 content = json.dumps(content) | |
| 87 tmpl_key = ndb.Key('Template', content) | |
| 88 if tag == json_data['default_template']: | |
| 89 default_key = tmpl_key | |
| 90 if (Template.query(ancestor=tmpl_key).count() == 0): | |
| 91 template = Template(parent=tmpl_key) | |
| 92 template.content = content | |
| 93 template.tags = [tag] | |
| 94 template.put() | |
|
sullivan
2013/09/17 14:58:47
It looks like the templates are already stored in
junjianx
2013/09/20 06:31:09
Template represents one category of breakdown. Tem
| |
| 95 | |
| 96 # Jump to new graph page using default template. | |
| 97 query_params = { | |
| 98 'prof_id': prof_key.urlsafe(), | |
| 99 'tmpl_id': default_key.urlsafe() | |
| 100 } | |
| 101 self.redirect('/?' + urllib.urlencode(query_params)) | |
| 102 | |
| 103 | |
| 104 application = webapp2.WSGIApplication([ | |
| 105 ('/', MainPage), | |
| 106 ('/upload', UploadHandler) | |
| 107 ], debug=True) | |
| OLD | NEW |