| {% extends "base.html" %} |
| {% block body %} |
| <h2>Datastore Admin of {{hosting_app_id}}</h2> |
| {% 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 unavailable. |
| {% endif %} |
| <a target="_blank" |
| href="https://developers.google.com/appengine/docs/adminconsole/datastorestats"> |
| <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. Size/Entity</th> |
| <th scope="col" class="id">Entities Size</th> |
| <th scope="col" class="id">Total Size</th> |
| </tr> |
| </thead> |
| <tbody> |
| {% for kind in kind_stats %} |
| <tr> |
| <td class="cbc"> |
| <input type="checkbox" name="kind" value="{{ kind.kind_name }}" |
| id="{{ kind.kind_name }}"> |
| </td> |
| <td class="id"> |
| <label for="{{ kind.kind_name }}">{{ kind.kind_name }}</label> |
| </td> |
| {% if kind.count %} |
| <td class="id">{{ kind.count }}</td> |
| <td class="id">{{ kind.average_bytes_str }}</td> |
| <td class="id">{{ kind.entity_bytes_str }}</td> |
| <td class="id">{{ kind.total_bytes_str }}</td> |
| {% else %} |
| <td class="id" style="color: #666667;">Stats not available</td> |
| <td class="id" style="color: #666667;">Stats not available</td> |
| <td class="id" style="color: #666667;">Stats not available</td> |
| <td class="id" style="color: #666667;">Stats not available</td> |
| {% endif %} |
| </tr> |
| {% endfor %} |
| {% if more_kinds %} |
| <tr> |
| <td colspan="6" class="cbc"> |
| Not all kinds could be displayed, possibly because there were too many. To back up a kind that does not appear in this list, use a <a href="https://developers.google.com/appengine/articles/scheduled_backups" target="_blank">scheduled backup</a>. |
| </td> |
| </tr> |
| {% endif %} |
| </tbody> |
| <tfoot> |
| <tr> |
| <td colspan="6"> |
| {% for action in action_list %} |
| <input type="submit" name="action" |
| class="goog-button" value="{{ action }}"> |
| {% endfor %} |
| </td> |
| </tr> |
| </tfoot> |
| </table> |
| </form> |
| {% else %} |
| <table class="ae-table"> |
| <tbody> |
| <tr> |
| <td> |
| <div class="ae-disabled" |
| style="padding-top: 0.75em; padding-bottom: 0.75em; |
| text-align: center;"> |
| Datastore is empty. |
| </div> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| {% endif %} |
| {% if pending_backups %} |
| <p> |
| <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>Pending Backups</strong> |
| </div> |
| </div> |
| </div> |
| </div> |
| <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 %} |
| <input type="hidden" name="app_id" value="{{ app_id|escape }}"> |
| <table id="pending_backups" class="ae-table ae-table-striped"> |
| <thead> |
| <tr> |
| <th scope="col" class="cbc tct-selectall"></th> |
| <th scope="col" class="id">Name</th> |
| <th scope="col" class="id">Start-Time</th> |
| </tr> |
| </thead> |
| <tbody> |
| {% for pending_backup in pending_backups %} |
| <tr> |
| <td class="cbc"> |
| <input type="checkbox" name="backup_id" value="{{ pending_backup.key }}" id="{{ pending_backup.key }}"> |
| </td> |
| <td class="id"> |
| <span title="Kinds: {{ pending_backup.kinds|join:', '|truncatewords:20|escape}}">{{ pending_backup.name }}{% if pending_backup.original_app %} (Imported from {{pending_backup.original_app|escape}}){% endif %}</span> |
| </td> |
| <td class="id"> |
| {{ pending_backup.start_time }} |
| </td> |
| </tr> |
| {% endfor %} |
| </tbody> |
| <tfoot> |
| <tr> |
| <td colspan="4" nowrap="nowrap"> |
| {% for pending_backup_action in pending_backup_action_list %} |
| <input type="submit" name="action" style="" class="goog-button" value="{{ pending_backup_action }}"> |
| {% endfor %} |
| </td> |
| </tr> |
| </tfoot> |
| </table> |
| </form> |
| {% endif %} |
| <p> |
| <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>Backups</strong> |
| </div> |
| </div> |
| </div> |
| </div> |
| {% if backups %} |
| <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 %} |
| <input type="hidden" name="app_id" value="{{ app_id|escape }}"> |
| <table id="backups" class="ae-table ae-table-striped"> |
| <thead> |
| <tr> |
| <th scope="col" class="cbc tct-selectall"></th> |
| <th scope="col" class="id">Name</th> |
| <th scope="col" class="id">Start-Time</th> |
| <th scope="col" class="id">End-Time</th> |
| </tr> |
| </thead> |
| <tbody> |
| {% for backup in backups %} |
| <tr> |
| <td class="cbc"> |
| <input type="checkbox" name="backup_id" value="{{ backup.key }}" id="{{ backup.key }}"> |
| </td> |
| <td class="id"> |
| <span title="Kinds: {{ backup.kinds|join:', '|truncatewords:20|escape }}">{{ backup.name }}{% if backup.original_app %} (Imported from {{backup.original_app|escape}}){% endif %}</span> |
| </td> |
| <td class="id"> |
| {{ backup.start_time }} |
| </td> |
| <td class="id"> |
| {{ backup.complete_time }} |
| </td> |
| </tr> |
| {% endfor %} |
| </tbody> |
| <tfoot> |
| <tr> |
| <td colspan="4" nowrap="nowrap"> |
| {% for backup_action in backup_action_list %} |
| <input type="submit" name="action" style="" class="goog-button" value="{{ backup_action }}"> |
| {% endfor %} |
| </td> |
| </tr> |
| </tfoot> |
| </table> |
| </form> |
| {% endif %} |
| <div class="ae-table-caption"> |
| <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 %} |
| <input type="submit" name="action" value="Import Backup Information" title="Import Backup Information or restore from Google Cloud Storage"/> |
| <input type="text" name="gs_handle" value="" size="50" title="Google Cloud Storage path of a backup info file or a bucket name"/> |
| </form> |
| </div> |
| {% if active_operations %} |
| <p> |
| <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>Active Operations</strong> |
| </div> |
| </div> |
| </div> |
| </div> |
| <table id="operations" class="ae-table ae-table-striped"> |
| <thead> |
| <tr> |
| <th scope="col" class="id">Description</th> |
| <th scope="col" class="id">Jobs</th> |
| </tr> |
| </thead> |
| <tbody> |
| {% for operation in active_operations %} |
| <tr> |
| <td class="id"> |
| {{ operation.description }} |
| </td> |
| <td class="id"> |
| ({{operation.completed_jobs}} steps completed, |
| {{operation.active_jobs}} active) |
| {% for job_id in operation.active_job_ids %} |
| <br/><a href="{{ map_reduce_path }}?mapreduce_id={{job_id}}">Job {{job_id}}</a> |
| {% endfor %} |
| </td> |
| </tr> |
| {% endfor %} |
| </tbody> |
| </table> |
| {% endif %} |
| {% if completed_operations %} |
| <p> |
| <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>Completed Operations</strong> |
| </div> |
| </div> |
| </div> |
| </div> |
| <table id="operations" class="ae-table ae-table-striped"> |
| <thead> |
| <tr> |
| <th scope="col" class="id">Description</th> |
| <th scope="col" class="id">Completed steps</th> |
| <th scope="col" class="id">Status</th> |
| <th scope="col" class="id">Status info</th> |
| </tr> |
| </thead> |
| <tbody> |
| {% for operation in completed_operations %} |
| <tr> |
| <td class="id"> |
| {{ operation.description }} |
| </td> |
| <td class="id"> |
| {{operation.completed_jobs}} steps |
| </td> |
| <td class="id"> |
| {{operation.status}} |
| </td> |
| <td class="id"> |
| {{operation.status_info}} |
| </td> |
| </tr> |
| {% endfor %} |
| </tbody> |
| </table> |
| {% endif %} |
| {% endblock %} |