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 |