Example #1
0
  def post(self, project_id):
    """ Handle modifying actions and redirect to a GET page.

    Args:
      project_id: A string specifyng the project ID.
    """
    self.ensure_user_has_admin(project_id)

    if self.request.get('action:flush_memcache'):
      if memcache.flush_all():
        message = 'Cache flushed, all keys dropped.'
      else:
        message = 'Flushing the cache failed. Please try again.'
      self.redirect(self._construct_url(remove=['action:flush_memcache'],
                                        add={'message': message}))
    elif self.request.get('action:delete_entities'):
      ds_access = DatastoreDistributed(project_id, DATASTORE_LOCATION,
                                       trusted=True)

      entity_keys = [datastore.Key(key)
                     for key in self.request.params.getall('entity_key')]
      _delete_entities(ds_access, entity_keys)
      self.redirect(self._construct_url(
          remove=['action:delete_entities'],
          add={'message': '%d entities deleted' % len(entity_keys)}))
    else:
      self.error(404)
Example #2
0
    def post(self, project_id, entity_key_string=None):
        """ Handles mutations to a given entity.

    Args:
      project_id: A string specifying the project ID.
      entity_key_string: A string specifying the entity key.
    """
        self.ensure_user_has_admin(project_id)

        ds_access = DatastoreDistributed(project_id,
                                         DATASTORE_LOCATION,
                                         trusted=True)

        if self.request.get('action:delete'):
            if entity_key_string:
                _delete_entities(ds_access, [datastore.Key(entity_key_string)])
                redirect_url = self.request.get(
                    'next', '/datastore_viewer/{}'.format(project_id))
                self.redirect(str(redirect_url))
            else:
                self.response.set_status(400)
            return

        if entity_key_string:
            entity = _get_entity_by_key(ds_access,
                                        datastore.Key(entity_key_string))
        else:
            kind = self.request.get('kind')
            namespace = self.request.get('namespace', None)
            entity = datastore.Entity(kind,
                                      _namespace=namespace,
                                      _app=project_id)

        for arg_name in self.request.arguments():
            # Arguments are in <property_type>|<property_name>=<value> format.
            if '|' not in arg_name:
                continue
            data_type_name, property_name = arg_name.split('|')
            form_value = self.request.get(arg_name)
            data_type = DataType.get_by_name(data_type_name)
            if (entity and property_name in entity
                    and data_type.format(entity[property_name]) == form_value):
                # If the property is unchanged then don't update it. This will prevent
                # empty form values from causing the property to be deleted if the
                # property was already empty.
                continue

            # TODO: Handle parse exceptions.
            entity[property_name] = data_type.parse(form_value)

        _put_entity(ds_access, entity)
        redirect_url = self.request.get(
            'next', '/datastore_viewer/{}'.format(project_id))
        self.redirect(str(redirect_url))
Example #3
0
  def get(self, project_id, entity_key_string=None):
    """ Displays the fields for a given entity.

    Args:
      project_id: A string specifying the project ID.
      entity_key_string: A string specifying the entity key.
    """
    self.ensure_user_has_admin(project_id)

    ds_access = DatastoreDistributed(project_id, DATASTORE_LOCATION,
                                     trusted=True)

    if entity_key_string:
      entity_key = datastore.Key(entity_key_string)
      entity_key_name = entity_key.name()
      entity_key_id = entity_key.id()
      namespace = entity_key.namespace()
      kind = entity_key.kind()
      entities = [_get_entity_by_key(ds_access, entity_key)]
      parent_key = entity_key.parent()
      if parent_key:
        parent_key_string = _format_datastore_key(parent_key)
      else:
        parent_key_string = None
    else:
      entity_key = None
      entity_key_string = None
      entity_key_name = None
      entity_key_id = None
      namespace = self.request.get('namespace')
      kind = self.request.get('kind')
      entities, _ = _get_entities(ds_access, kind, namespace, order=None,
                                  start=0, count=20)
      parent_key = None
      parent_key_string = None

      if not entities:
        params = urllib.urlencode(
          [('kind', kind),
           ('message', 'Cannot create the kind "%s" in the "%s" namespace '
                       'because no template entity '
                       'exists.' % (kind, namespace)),
           ('namespace', namespace)])
        self.redirect('/datastore_viewer/%s?%s' % (project_id, params))
        return

    property_name_to_values = _property_name_to_values(entities)
    fields = []
    for property_name, values in sorted(property_name_to_values.iteritems()):
      data_type = DataType.get(values[0])
      field = data_type.input_field('%s|%s' % (data_type.name(), property_name),
                                    values[0] if entity_key else None,
                                    values,
                                    self.request.uri)
      fields.append((property_name, data_type.name(), field))

    context = {
      'page_content': self.TEMPLATE,
      'project_id': project_id,
      'fields': fields,
      'key': entity_key_string,
      'key_id': entity_key_id,
      'key_name': entity_key_name,
      'kind': kind,
      'namespace': namespace,
      'next': self.request.get('next',
                               '/datastore_viewer/{}'.format(project_id)),
      'parent_key': parent_key,
      'parent_key_string': parent_key_string,
      'request': self.request
    }
    self.render_app_page(page='datastore_editor', values=context)
Example #4
0
  def get(self, project_id):
    """ Displays a list of entities for a given kind.

    Args:
      project_id: A string specifying the project ID.
    """
    self.ensure_user_has_admin(project_id)

    ds_access = DatastoreDistributed(project_id, DATASTORE_LOCATION,
                                     trusted=True)

    kind = self.request.get('kind', None)
    namespace = self.request.get('namespace', '')
    order = self.request.get('order', None)
    message = self.request.get('message', None)
    gql_string = self.request.get('gql', None)

    try:
      page = int(self.request.get('page', '1'))
    except ValueError:
      page = 1

    kinds = self._get_kinds(ds_access, namespace)

    if gql_string is not None:
      start = (page - 1) * self.NUM_ENTITIES_PER_PAGE

      total_entities = 0
      entities = []
      try:
        gql_query = gql.GQL(gql_string, _app=project_id, namespace=namespace)
        kind = gql_query.kind()
        query = gql_query.Bind([], {})

        total_entities = query.Count()
        entities = list(
          query.Run(limit=self.NUM_ENTITIES_PER_PAGE, offset=start))
      except datastore.datastore_errors.NeedIndexError as error:
        message = ('Error during GQL query: <pre>{}</pre> Note: Queries '
                   'requiring a composite index are not yet supported by the '
                   'AppScale datastore viewer.'.format(error))
      except datastore.datastore_errors.Error as error:
        message = 'Error during GQL query: <pre>{}</pre>'.format(error)

      headers, template_entities, total_entities = (
        self._format_entity_template_data(ds_access, self.request.uri,
                                          entities, total_entities))
      num_pages = int(math.ceil(float(total_entities) /
                                self.NUM_ENTITIES_PER_PAGE))
    else:
      if not kind and kinds:
        self.redirect(self._construct_url(add={'kind': kinds[0]}))
        return

      if kind:
        start = (page-1) * self.NUM_ENTITIES_PER_PAGE
        entities, total_entities = _get_entities(
          ds_access, kind, namespace, order, start, self.NUM_ENTITIES_PER_PAGE)
        headers, template_entities, total_entities = (
          self._format_entity_template_data(ds_access, self.request.uri,
                                            entities, total_entities))
        num_pages = int(math.ceil(float(total_entities) /
                                  self.NUM_ENTITIES_PER_PAGE))
      else:
        start = 0
        headers = []
        template_entities = []
        total_entities = 0
        num_pages = 0

    select_namespace_url = self._construct_url(
      remove=['message'],
      add={'namespace': self.request.get('namespace')})
    context = {
      'entities': template_entities,
      'gql_string': gql_string,
      'headers': headers,
      'kind': kind,
      'kinds': kinds,
      'message': message,
      'namespace': namespace,
      'num_pages': num_pages,
      'order': order,
      'order_base_url': self._construct_url(remove=['message', 'order']),
      'page': page,
      'page_content': self.TEMPLATE,
      'paging_base_url': self._construct_url(remove=['message', 'page']),
      'project_id': project_id,
      'request': self.request,
      'select_namespace_url': select_namespace_url,
      'show_namespace': self.request.get('namespace', None) is not None,
      'start': start,
      'total_entities': total_entities
    }
    self.render_app_page(page='datastore_viewer', values=context)