168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)# found in the LICENSE file.
468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# This file is expected to be used under another directory to use,
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# so we disable checking import path of GAE tools from this directory.
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# pylint: disable=F0401,E0611,W0232
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)import json
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)from google.appengine.ext import blobstore
1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)from google.appengine.ext import ndb
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class Profiler(ndb.Model):
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  """Profiler entity to store json data. Use run_id as its key.
1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Json data will be stored at blobstore, but can be referred by BlobKey."""
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  blob_key = ndb.BlobKeyProperty()
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class Template(ndb.Model):
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  """Template to breakdown profiler with multiple tags.
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Use content as its key."""
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  content = ndb.JsonProperty()
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)def CreateProfiler(blob_info):
2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  """Create Profiler entity in database of uploaded file. Return run_id."""
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  json_str = blob_info.open().read()
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  json_obj = json.loads(json_str)
3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  # Check the uniqueness of data run_id and store new one.
3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  run_id = json_obj['run_id']
3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  prof_key = ndb.Key('Profiler', run_id)
3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if not prof_key.get():
3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    # Profile for this run_id does not exist
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    profiler = Profiler(id=run_id, blob_key=blob_info.key())
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    profiler.put()
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return run_id
4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)def GetProfiler(run_id):
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  """Get Profiler entity from database of given run_id."""
4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  # Get entity key.
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  profiler = ndb.Key('Profiler', run_id).get()
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return blobstore.BlobReader(profiler.blob_key).read()
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)def CreateTemplates(blob_info):
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  """Create Template entities for all templates of uploaded file. Return ndb.Key
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  of default template or None if not indicated or found in templates."""
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  json_str = blob_info.open().read()
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  json_obj = json.loads(json_str)
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  # Return None when no default template indicated.
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if 'default_template' not in json_obj:
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return None
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  # Return None when no default template found in templates.
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if json_obj['default_template'] not in json_obj['templates']:
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return None
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  # Check the uniqueness of template content and store new one.
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for tag, content in json_obj['templates'].iteritems():
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    content_str = json.dumps(content)
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    tmpl_key = ndb.Key('Template', content_str)
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if tag == json_obj['default_template']:
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      default_key = tmpl_key
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if not tmpl_key.get():
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      # Template of the same content does not exist.
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      template = Template(id=content_str, content=content)
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      template.put()
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return default_key
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)def CreateTemplate(content):
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  """Create Template entity for user to share."""
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  content_str = json.dumps(content)
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  tmpl_key = ndb.Key('Template', content_str)
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if not tmpl_key.get():
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    # Template of the same content does not exist.
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    template = Template(id=content_str, content=content)
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    template.put()
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return tmpl_key
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)def GetTemplate(tmpl_id):
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  """Get Template entity of given tmpl_id generated by ndb.Key."""
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  # Get entity key.
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  template = ndb.Key(urlsafe=tmpl_id).get()
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return json.dumps(template.content)
94