files: #!/usr/bin/env python
  #
  # Copyright 2007 Google Inc.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  #
  
  
  
  
  
  """Handler for data backup operation.
  
  Generic datastore admin console transfers control to ConfirmBackupHandler
  after selection of entities. The ConfirmBackupHandler confirms with user
  his choice, enters a backup name and transfers control to
  DoBackupHandler. DoBackupHandler starts backup mappers and displays confirmation
  page.
  
  This module also contains actual mapper code for backing data over.
  """
  
  
  
  
  
  
  
  
  from __future__ import with_statement
  
  
  
  import copy
  import cStringIO
  import datetime
  import itertools
  import logging
  import os
  import random
  import re
  import time
  import urllib
  import xml.dom.minidom
  
  from google.appengine._internal import cloudstorage
  
  # AppScale: Use bundled mapreduce library.
  from google.appengine.ext.mapreduce import context
  from google.appengine.ext.mapreduce import datastore_range_iterators as db_iters
  from google.appengine.ext.mapreduce import input_readers
  from google.appengine.ext.mapreduce import json_util
  from google.appengine.ext.mapreduce import operation as op
  from google.appengine.ext.mapreduce import output_writers
  from google.appengine.ext.mapreduce import parameters
  from google.appengine.ext.mapreduce import records
  
  from google.appengine.api import apiproxy_stub_map
  from google.appengine.api import app_identity
  from google.appengine.api import blobstore as blobstore_api
  from google.appengine.api import capabilities
  from google.appengine.api import datastore
  from google.appengine.api import datastore_errors
  from google.appengine.api import datastore_types
  from google.appengine.api import taskqueue
  from google.appengine.api import urlfetch
  from google.appengine.api.taskqueue import taskqueue_service_pb
  from google.appengine.datastore import entity_pb
  from google.appengine.ext import blobstore
  from google.appengine.ext import db
  from google.appengine.ext import deferred
  import webapp2 as webapp
  from google.appengine.runtime import apiproxy_errors
  from google.appengine.ext.datastore_admin import backup_pb2
  from google.appengine.ext.datastore_admin import config
  from google.appengine.ext.datastore_admin import utils
  
  
  XSRF_ACTION = 'backup'
  BUCKET_PATTERN = (r'^([a-zA-Z0-9]+([\-_]+[a-zA-Z0-9]+)*)'
                    r'(\.([a-zA-Z0-9]+([\-_]+[a-zA-Z0-9]+)*))*$')
  MAX_B
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/backup_handler.py
files: #!/usr/bin/env python
  #
  # Copyright 2007 Google Inc.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  #
  
  
  
  
  
  """Handler for data backup operation.
  
  Generic datastore admin console transfers control to ConfirmBackupHandler
  after selection of entities. The ConfirmBackupHandler confirms with user
  his choice, enters a backup name and transfers control to
  DoBackupHandler. DoBackupHandler starts backup mappers and displays confirmation
  page.
  
  This module also contains actual mapper code for backing data over.
  """
  
  
  
  
  
  
  
  
  from __future__ import with_statement
  
  
  
  import copy
  import cStringIO
  import datetime
  import itertools
  import json
  import logging
  import os
  import random
  import re
  import time
  import urllib
  import xml.dom.minidom
  
  from google.appengine._internal import cloudstorage
  
  # AppScale: Use bundled mapreduce library.
  from google.appengine.ext.mapreduce import context
  from google.appengine.ext.mapreduce import datastore_range_iterators as db_iters
  from google.appengine.ext.mapreduce import input_readers
  from google.appengine.ext.mapreduce import json_util
  from google.appengine.ext.mapreduce import operation as op
  from google.appengine.ext.mapreduce import output_writers
  from google.appengine.ext.mapreduce import parameters
  from google.appengine.ext.mapreduce import records
  
  from google.appengine.api import apiproxy_stub_map
  from google.appengine.api import app_identity
  from google.appengine.api import blobstore as blobstore_api
  from google.appengine.api import capabilities
  from google.appengine.api import datastore
  from google.appengine.api import datastore_errors
  from google.appengine.api import datastore_types
  from google.appengine.api import taskqueue
  from google.appengine.api import urlfetch
  from google.appengine.api.taskqueue import taskqueue_service_pb
  from google.appengine.datastore import entity_pb
  from google.appengine.ext import blobstore
  from google.appengine.ext import db
  from google.appengine.ext import deferred
  import webapp2 as webapp
  from google.appengine.runtime import apiproxy_errors
  from google.appengine.ext.datastore_admin import backup_pb2
  from google.appengine.ext.datastore_admin import config
  from google.appengine.ext.datastore_admin import utils
  
  
  XSRF_ACTION = 'backup'
  BUCKET_PATTERN = (r'^([a-zA-Z0-9]+([\-_]+[a-zA-Z0-9]+)*)'
                    r'(\.([a-zA-Z0-9]+([\-_]+[a-zA-Z0-9]+)*))*$
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/backup_handler.py
files: #!/usr/bin/env python
  #
  # Copyright 2007 Google Inc.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  #
  
  
  
  
  """Main module for datastore admin receiver.
  
  To use, add this to app.yaml:
    builtins:
    - datastore_admin: on
  """
  
  
  
  import logging
  import operator
  import os
  
  from google.appengine.api import app_identity
  from google.appengine.api import datastore_errors
  from google.appengine.api import users
  from google.appengine.ext import deferred
  import webapp2 as webapp
  from google.appengine.ext.db import stats
  from google.appengine.ext.webapp import util
  from google.appengine.runtime import apiproxy_errors
  from google.appengine.ext.datastore_admin import backup_handler
  from google.appengine.ext.datastore_admin import config
  from google.appengine.ext.datastore_admin import delete_handler
  from google.appengine.ext.datastore_admin import utils
  
  
  
  
  
  
  ENTITY_ACTIONS = {
      'Delete Entities': delete_handler.ConfirmDeleteHandler.Render,
      'Backup Entities': backup_handler.ConfirmBackupHandler.Render,
  }
  
  
  BACKUP_ACTIONS = {
      'Delete': backup_handler.ConfirmDeleteBackupHandler.Render,
      'Restore': backup_handler.ConfirmRestoreFromBackupHandler.Render,
      'Info': backup_handler.BackupInformationHandler.Render,
  }
  
  PENDING_BACKUP_ACTIONS = {
      'Abort': backup_handler.ConfirmAbortBackupHandler.Render,
      'Info': backup_handler.BackupInformationHandler.Render,
  }
  
  GET_ACTIONS = ENTITY_ACTIONS.copy()
  GET_ACTIONS.update(BACKUP_ACTIONS)
  GET_ACTIONS.update(PENDING_BACKUP_ACTIONS)
  GET_ACTIONS.update({'Import Backup Information':
                      backup_handler.ConfirmBackupImportHandler.Render})
  
  
  def _GetDatastoreStats(kinds_list, use_stats_kinds=False):
    """Retrieves stats for kinds.
  
    Args:
      kinds_list: List of known kinds.
      use_stats_kinds: If stats are available, kinds_list will be ignored and
        all kinds found in stats will be used instead.
  
    Returns:
      timestamp: records time that statistics were last updated.
      kind_dict: dictionary of kind objects with the following members:
      - kind_name: the name of this kind.
      - count: number of known entities of this type.
      - total_bytes_str: total bytes for this kind as a string.
      - average_bytes_str: average bytes per entity as a string.
    """
    global_stat = stats.GlobalStat.all().fetch(1)
  
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/main.py
files: #!/usr/bin/env python
  #
  # Copyright 2007 Google Inc.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  #
  
  
  
  
  """Main module for datastore admin receiver.
  
  To use, add this to app.yaml:
    builtins:
    - datastore_admin: on
  """
  
  
  
  import logging
  import operator
  import os
  
  from google.appengine.api import app_identity
  from google.appengine.api import datastore_errors
  from google.appengine.api import users
  from google.appengine.ext import deferred
  import webapp2 as webapp
  from google.appengine.ext.db import stats
  from google.appengine.ext.webapp import util
  from google.appengine.runtime import apiproxy_errors
  from google.appengine.ext.datastore_admin import backup_handler
  from google.appengine.ext.datastore_admin import config
  from google.appengine.ext.datastore_admin import delete_handler
  from google.appengine.ext.datastore_admin import utils
  
  
  
  
  
  
  ENTITY_ACTIONS = {
      'Delete Entities': delete_handler.ConfirmDeleteHandler.Render,
      'Backup Entities': backup_handler.ConfirmBackupHandler.Render,
  }
  
  
  BACKUP_ACTIONS = {
      'Delete': backup_handler.ConfirmDeleteBackupHandler.Render,
      'Restore': backup_handler.ConfirmRestoreFromBackupHandler.Render,
      'Info': backup_handler.BackupInformationHandler.Render,
  }
  
  PENDING_BACKUP_ACTIONS = {
      'Abort': backup_handler.ConfirmAbortBackupHandler.Render,
      'Info': backup_handler.BackupInformationHandler.Render,
  }
  
  GET_ACTIONS = ENTITY_ACTIONS.copy()
  GET_ACTIONS.update(BACKUP_ACTIONS)
  GET_ACTIONS.update(PENDING_BACKUP_ACTIONS)
  GET_ACTIONS.update({'Import Backup Information':
                      backup_handler.ConfirmBackupImportHandler.Render})
  
  
  def _GetDatastoreStats(kinds_list, use_stats_kinds=False):
    """Retrieves stats for kinds.
  
    Args:
      kinds_list: List of known kinds.
      use_stats_kinds: If stats are available, kinds_list will be ignored and
        all kinds found in stats will be used instead.
  
    Returns:
      timestamp: records time that statistics were last updated.
      kind_dict: dictionary of kind objects with the following members:
      - kind_name: the name of this kind.
      - count: number of known entities of this type.
      - total_bytes_str: total bytes for this kind as a string.
      - average_bytes_str: average bytes per entity as a string.
    """
    global_stat = stats.GlobalStat.all().fetch(1)
  
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/main.py
files: {% extends "base.html" %}
  {% block title %}Confirm Import of backup information{% endblock %}
  {% block body %}
    <h2>Datastore Admin: Import backup information</h2>
    {% if error %}
      <div class="ae-errorbox">{{ error|escape }}</div>
      <a href="{{ datastore_admin_home }}"><button>Back</button></a>
    {% else %}
      {% if not other_backup_info_files and not selected_backup_info_file %}
        <div class="ae-errorbox">No backup information files were found.</div>
        <a href="{{ datastore_admin_home }}"><button>Back</button></a>
      {% else %}
        <form action="{{base_path}}/{{form_target}}" method="post" style="width:39.39em;">
          <input type="hidden" name="xsrf_token" value="{{xsrf_token|escape}}">
          {% if not other_backup_info_files %}
            <b>Confirm import of:</b>
            <input type="hidden" name="gs_handle" value="{{selected_backup_info_file}}">{{selected_backup_info_file|escape}}
          {% else %}
            {% if selected_backup_info_file %}
              <b>Confirm import of:</b><br/>
              <input type="radio" name="gs_handle" value="{{selected_backup_info_file}}" checked>{{selected_backup_info_file|escape}}</br>
            {% else %}
              {% if backup_info_specified %}
                <b>Requested backup was not found, available backups:</b><br/>
              {% else %}
                <b>Select an available backup:</b><br/>
              {% endif %}
            {% endif %}
            {% for backup_info_file in other_backup_info_files %}
              <input type="radio" name="gs_handle" value="{{backup_info_file}}">{{backup_info_file|escape}}</br>
            {% endfor %}
          {% endif %}
          {% if run_as_a_service %}
            <input type="hidden" name="run_as_a_service" value="{{ run_as_a_service|escape }}">
          {% endif %}
          <input type="hidden" name="service_account_name" value="{{ service_account_name }}">
          <input type="Submit" name="Import" value="Add to backup list">
          <input type="Submit" name="Restore" value="Restore from backup">
          <a href="{{ datastore_admin_home }}">Cancel</a>
        </form>
      {% endif %}
    {% endif %}
  {% endblock %}
  
  
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/templates/confirm_backup_import.html
files: {% extends "base.html" %}
  {% block title %}Confirm Import of backup information{% endblock %}
  {% block body %}
    <h2>Datastore Admin: Import backup information</h2>
    {% if error %}
      <div class="ae-errorbox">{{ error|escape }}</div>
      <a href="{{ datastore_admin_home }}"><button>Back</button></a>
    {% else %}
      {% if not other_backup_info_files and not selected_backup_info_file %}
        <div class="ae-errorbox">No backup information files were found.</div>
        <a href="{{ datastore_admin_home }}"><button>Back</button></a>
      {% else %}
        <form action="{{base_path}}/{{form_target}}" method="post" style="width:39.39em;">
          <input type="hidden" name="xsrf_token" value="{{xsrf_token|escape}}">
          {% if not other_backup_info_files %}
            <b>Confirm import of:</b>
            <input type="hidden" name="gs_handle" value="{{selected_backup_info_file}}">{{selected_backup_info_file|escape}}
          {% else %}
            {% if selected_backup_info_file %}
              <b>Confirm import of:</b><br/>
              <input type="radio" name="gs_handle" value="{{selected_backup_info_file}}" checked>{{selected_backup_info_file|escape}}</br>
            {% else %}
              {% if backup_info_specified %}
                <b>Requested backup was not found, available backups:</b><br/>
              {% else %}
                <b>Select an available backup:</b><br/>
              {% endif %}
            {% endif %}
            {% for backup_info_file in other_backup_info_files %}
              <input type="radio" name="gs_handle" value="{{backup_info_file}}">{{backup_info_file|escape}}</br>
            {% endfor %}
          {% endif %}
          {% if run_as_a_service %}
            <input type="hidden" name="run_as_a_service" value="{{ run_as_a_service|escape }}">
          {% endif %}
          <input type="Submit" name="Import" value="Add to backup list">
          <input type="Submit" name="Restore" value="Restore from backup">
          <a href="{{ datastore_admin_home }}">Cancel</a>
        </form>
      {% endif %}
    {% endif %}
  {% endblock %}
  
  
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/templates/confirm_backup_import.html
files: {% extends "base.html" %}
  {% block title %}Confirm Restore from a backup copy{% endblock %}
  {% block body %}
    <h2>Datastore Admin: Restore from a backup copy</h2>
    {% if backup %}
      Are you sure you want to restore from {{ backup.name }}?
      <br/>Restore does not delete any new entities added since the backup.
      However, it will replace existing entities with the backed-up version for the following kinds:
      <form action="{{base_path}}/{{form_target}}" method="post" style="width:39.39em;">
        {% if run_as_a_service %}
          <input type="hidden" name="run_as_a_service" value="{{ run_as_a_service|escape }}">
        {% endif %}
        <input type="hidden" name="backup_id" value="{{backup.key}}">
        <input type="hidden" name="xsrf_token" value="{{xsrf_token|escape}}">
        <input type="hidden" name="delete_backup_after_restore" value="{{ delete_backup_after_restore|escape }}">
        <ul>
          {% for kind in backup.kinds %}
            <li><input type="checkbox" name="kind" value="{{kind}}" checked="checked"/>{{ kind }}</li>
          {% endfor %}
        </ul>
        {% if notreadonly_warning %}
        <div>
          <h4 style="padding:0;margin-top:1em;margin-bottom:0.46em;">WARNING</h4>
          {% if original_app_warning %}
            <ul><li>
          {% else %}
            <p>
          {% endif %}
          The application is not in read-only mode and restore may
          conflict with other changes.
          To place the application in read-only mode,
          please follow the instructions at
          <a href="https://developers.google.com/appengine/docs/adminconsole/applicationsettings#Disable_Datastore_Writes" target="_blank">
          Disable Datastore Writes</a>
          {% if not original_app_warning %}
            </p>
            </div>
          {% endif %}
        {% endif %}
        {% if original_app_warning %}
          {% if not notreadonly_warning %}
            <div>
            <h4 style="padding:0;margin-top:1em;margin-bottom:0.46em;">WARNING</h4>
            <p>
          {% else %}
            <li>
          {% endif %}
          The backup data comes from a different application, {{original_app_warning|escape}}.
          {% if not notreadonly_warning %}
            </p>
          {% else %}
            </li>
          {% endif %}
          </div>
        {% endif %}
        <p>Operation will be performed using the selected queue:
          {% if queues %}
          <select name="queue">
            {% for queue in queues %}
              <option value="{{ queue }}">{{ queue }}</option>
            {% endfor %}
          </select>
          {% else %}
          <input type="text" name="queue" value="default"/>
          {% endif %}
        </p>
        <p>
          <label for
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/templates/confirm_restore_from_backup.html
files: {% extends "base.html" %}
  {% block title %}Confirm Restore from a backup copy{% endblock %}
  {% block body %}
    <h2>Datastore Admin: Restore from a backup copy</h2>
    {% if backup %}
      Are you sure you want to restore from {{ backup.name }}?
      <br/>Restore does not delete any new entities added since the backup.
      However, it will replace existing entities with the backed-up version for the following kinds:
      <form action="{{base_path}}/{{form_target}}" method="post" style="width:39.39em;">
        {% if run_as_a_service %}
          <input type="hidden" name="run_as_a_service" value="{{ run_as_a_service|escape }}">
        {% endif %}
        <input type="hidden" name="backup_id" value="{{backup.key}}">
        <input type="hidden" name="xsrf_token" value="{{xsrf_token|escape}}">
        <input type="hidden" name="delete_backup_after_restore" value="{{ delete_backup_after_restore|escape }}">
        <ul>
          {% for kind in backup.kinds %}
            <li><input type="checkbox" name="kind" value="{{kind}}" checked="checked"/>{{ kind }}</li>
          {% endfor %}
        </ul>
        {% if notreadonly_warning %}
        <div>
          <h4 style="padding:0;margin-top:1em;margin-bottom:0.46em;">WARNING</h4>
          {% if original_app_warning %}
            <ul><li>
          {% else %}
            <p>
          {% endif %}
          The application is not in read-only mode and restore may
          conflict with other changes.
          To place the application in read-only mode,
          please follow the instructions at
          <a href="https://developers.google.com/appengine/docs/adminconsole/applicationsettings#Disable_Datastore_Writes" target="_blank">
          Disable Datastore Writes</a>
          {% if not original_app_warning %}
            </p>
            </div>
          {% endif %}
        {% endif %}
        {% if original_app_warning %}
          {% if not notreadonly_warning %}
            <div>
            <h4 style="padding:0;margin-top:1em;margin-bottom:0.46em;">WARNING</h4>
            <p>
          {% else %}
            <li>
          {% endif %}
          The backup data comes from a different application, {{original_app_warning|escape}}.
          {% if not notreadonly_warning %}
            </p>
          {% else %}
            </li>
          {% endif %}
          </div>
        {% endif %}
        <p>Operation will be performed using the selected queue:
          {% if queues %}
          <select name="queue">
            {% for queue in queues %}
              <option value="{{ queue }}">{{ queue }}</option>
            {% endfor %}
          </select>
          {% else %}
          <input type="text" name="queue" value="default"/>
          {% endif %}
        </p>
        <input type="submit" value
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/templates/confirm_restore_from_backup.html
files: {% extends "base.html" %}
  {% block body %}
    <h2>Datastore Admin of {{hosting_app_id}}</h2>
    {% if run_as_a_service or offer_service %}
      <div class="ae-promo ae-rounded-sml">
        <strong>
          The managed backup service is deprecated, and will no longer be available as of
          Mar 27th, 2018.
        </strong>
      </div>
    {% endif %}
    {% if run_as_a_service %}
      <div class="ae-message ae-rounded-sml">
        Backup/Restore running as a service.
        <a href="{{datastore_admin_home}}?service=T">Disable</a>
      </div>
    {% else %}
      {% if offer_service %}
        <div class="ae-message ae-rounded-sml">
          This application may run backup/restore as a service.
          <a href="{{datastore_admin_home}}?run_as_a_service=True">Enable</a>
        </div>
      {% endif %}
    {% endif %}
    {% if error %}
    <div class="ae-errorbox">
      {{ error|escape }}
    </div>
    {% endif %}
    <div class="ae-table-caption">
      <div class="ae-paginate">
        <div class="g-section g-tpl-50-50 g-split">
          <div class="g-unit g-first">
            <strong>Entities</strong>
          </div>
          <div class="g-unit">
            <span id="ae-dash-quota-refresh-info">
            {% if last_stats_update %}
              Entity statistics last updated
              {{ last_stats_update|date:"M j, Y g:i a T" }}
            {% else %}
              Entity statistics are temporarily unavailable and should appear within 48 hours.
            {% endif %}
            <a target="_blank"
               href="https://cloud.google.com/appengine/docs/standard/python/console/datastore-statistics">
              <img class="ae-help-icon" src="{{ base_path }}/static/img/help.gif"
                height="14" width="14" alt="help">
            </a>
            </span>
          </div>
        </div>
      </div>
    </div>
    {% if kind_stats %}
    <form action="{{ base_path }}/" method="post">
      {% if run_as_a_service %}
        <input type="hidden" name="run_as_a_service" value="{{ run_as_a_service|escape }}">
      {% endif %}
      {% if has_namespace %}
      <input type="hidden" name="namespace" value="{{ namespace|escape }}">
      {% endif %}
      <input type="hidden" name="app_id" value="{{ app_id|escape }}">
      <table id="kinds" class="ae-table ae-table-striped">
        <thead>
          <tr>
            <th scope="col" class="cbc tct-selectall"></th>
            <th scope="col" class="id">Entity Kind</th>
            <th scope="col" class="id"># Entities</th>
            <th scope="col" class="id">Avg
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/templates/list_actions.html
files: {% extends "base.html" %}
  {% block body %}
    <h2>Datastore Admin of {{hosting_app_id}}</h2>
    {% if run_as_a_service or offer_service %}
      <div class="ae-promo ae-rounded-sml">
        <strong>
          The managed backup service is deprecated, and will no longer be available as of
          Mar 27th, 2018.
        </strong>
      </div>
    {% endif %}
    {% if run_as_a_service %}
      <div class="ae-message ae-rounded-sml">
        Backup/Restore running as a service.
        <a href="{{datastore_admin_home}}?service=T">Disable</a>
      </div>
    {% else %}
      {% if offer_service %}
        <div class="ae-message ae-rounded-sml">
          This application may run backup/restore as a service.
          <a href="{{datastore_admin_home}}?run_as_a_service=True">Enable</a>
        </div>
      {% endif %}
    {% endif %}
    {% if error %}
    <div class="ae-errorbox">
      {{ error|escape }}
    </div>
    {% endif %}
    <div class="ae-table-caption">
      <div class="ae-paginate">
        <div class="g-section g-tpl-50-50 g-split">
          <div class="g-unit g-first">
            <strong>Entities</strong>
          </div>
          <div class="g-unit">
            <span id="ae-dash-quota-refresh-info">
            {% if last_stats_update %}
              Entity statistics last updated
              {{ last_stats_update|date:"M j, Y g:i a T" }}
            {% else %}
              Entity statistics are temporarily unavailable and should appear within 48 hours.
            {% endif %}
            <a target="_blank"
               href="https://cloud.google.com/appengine/docs/standard/python/console/datastore-statistics">
              <img class="ae-help-icon" src="{{ base_path }}/static/img/help.gif"
                height="14" width="14" alt="help">
            </a>
            </span>
          </div>
        </div>
      </div>
    </div>
    {% if kind_stats %}
    <form action="{{ base_path }}/" method="post">
      {% if run_as_a_service %}
        <input type="hidden" name="run_as_a_service" value="{{ run_as_a_service|escape }}">
      {% endif %}
      {% if has_namespace %}
      <input type="hidden" name="namespace" value="{{ namespace|escape }}">
      {% endif %}
      <input type="hidden" name="app_id" value="{{ app_id|escape }}">
      <table id="kinds" class="ae-table ae-table-striped">
        <thead>
          <tr>
            <th scope="col" class="cbc tct-selectall"></th>
            <th scope="col" class="id">Entity Kind</th>
            <th scope="col" class="id"># Entities</th>
            <th scope="col" class="id">Avg
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/templates/list_actions.html
files: #!/usr/bin/env python
  #
  # Copyright 2007 Google Inc.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  #
  
  
  
  
  """Used render templates for datastore admin."""
  
  
  
  import base64
  import datetime
  import json
  import logging
  import os
  import random
  import time
  
  # AppScale: Use bundled mapreduce library.
  from google.appengine.ext.mapreduce import context
  from google.appengine.ext.mapreduce import control
  from google.appengine.ext.mapreduce import model
  from google.appengine.ext.mapreduce import operation as mr_operation
  from google.appengine.ext.mapreduce import util
  
  from google.appengine.api import app_identity
  from google.appengine.api import datastore
  from google.appengine.api import datastore_errors
  from google.appengine.api import memcache
  from google.appengine.api import urlfetch
  from google.appengine.api import users
  from google.appengine.datastore import datastore_rpc
  from google.appengine.datastore import entity_pb
  from google.appengine.ext import db
  import webapp2 as webapp
  from google.appengine.ext.datastore_admin import config
  from google.appengine.ext.db import metadata
  from google.appengine.ext.db import stats
  from google.appengine.ext.webapp import _template
  from google.appengine.runtime import apiproxy_errors
  
  
  MEMCACHE_NAMESPACE = '_ah-datastore_admin'
  XSRF_VALIDITY_TIME = 600
  KINDS_AND_SIZES_VAR = 'kinds_and_sizes'
  MAPREDUCE_MIN_SHARDS = 8
  MAPREDUCE_DEFAULT_SHARDS = 32
  MAPREDUCE_MAX_SHARDS = 256
  RESERVE_KEY_POOL_MAX_SIZE = 1000
  
  DATASTORE_ADMIN_OPERATION_KIND = '_AE_DatastoreAdmin_Operation'
  BACKUP_INFORMATION_KIND = '_AE_Backup_Information'
  BACKUP_INFORMATION_FILES_KIND = '_AE_Backup_Information_Kind_Files'
  BACKUP_INFORMATION_KIND_TYPE_INFO = '_AE_Backup_Information_Kind_Type_Info'
  DATASTORE_ADMIN_KINDS = (DATASTORE_ADMIN_OPERATION_KIND,
                           BACKUP_INFORMATION_KIND,
                           BACKUP_INFORMATION_FILES_KIND,
                           BACKUP_INFORMATION_KIND_TYPE_INFO)
  
  
  MAX_RPCS = 10
  
  
  def IsKindNameVisible(kind_name):
    return not (kind_name.startswith('__') or
                kind_name in DATASTORE_ADMIN_KINDS or
                kind_name in model._MAP_REDU
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/utils.py
files: #!/usr/bin/env python
  #
  # Copyright 2007 Google Inc.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  #
  
  
  
  
  """Used render templates for datastore admin."""
  
  
  
  import base64
  import datetime
  import logging
  import os
  import random
  import time
  
  # AppScale: Use bundled mapreduce library.
  from google.appengine.ext.mapreduce import context
  from google.appengine.ext.mapreduce import control
  from google.appengine.ext.mapreduce import model
  from google.appengine.ext.mapreduce import operation as mr_operation
  from google.appengine.ext.mapreduce import util
  
  from google.appengine.api import datastore
  from google.appengine.api import datastore_errors
  from google.appengine.api import memcache
  from google.appengine.api import users
  from google.appengine.datastore import datastore_rpc
  from google.appengine.datastore import entity_pb
  from google.appengine.ext import db
  import webapp2 as webapp
  from google.appengine.ext.datastore_admin import config
  from google.appengine.ext.db import metadata
  from google.appengine.ext.db import stats
  from google.appengine.ext.webapp import _template
  from google.appengine.runtime import apiproxy_errors
  
  
  MEMCACHE_NAMESPACE = '_ah-datastore_admin'
  XSRF_VALIDITY_TIME = 600
  KINDS_AND_SIZES_VAR = 'kinds_and_sizes'
  MAPREDUCE_MIN_SHARDS = 8
  MAPREDUCE_DEFAULT_SHARDS = 32
  MAPREDUCE_MAX_SHARDS = 256
  RESERVE_KEY_POOL_MAX_SIZE = 1000
  
  DATASTORE_ADMIN_OPERATION_KIND = '_AE_DatastoreAdmin_Operation'
  BACKUP_INFORMATION_KIND = '_AE_Backup_Information'
  BACKUP_INFORMATION_FILES_KIND = '_AE_Backup_Information_Kind_Files'
  BACKUP_INFORMATION_KIND_TYPE_INFO = '_AE_Backup_Information_Kind_Type_Info'
  DATASTORE_ADMIN_KINDS = (DATASTORE_ADMIN_OPERATION_KIND,
                           BACKUP_INFORMATION_KIND,
                           BACKUP_INFORMATION_FILES_KIND,
                           BACKUP_INFORMATION_KIND_TYPE_INFO)
  
  
  MAX_RPCS = 10
  
  
  def IsKindNameVisible(kind_name):
    return not (kind_name.startswith('__') or
                kind_name in DATASTORE_ADMIN_KINDS or
                kind_name in model._MAP_REDUCE_KINDS)
  
  
  def RenderToResponse(handler, template_file, template_params):
    """Render the
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/datastore_admin/utils.py