Source code for openstack_dashboard.dashboards.project.containers.tables

# Copyright 2012 Nebula, 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.
import logging

from django.core.urlresolvers import reverse  # noqa
from django import shortcuts
from django import template
from django.template import defaultfilters as filters
from django.utils import http
from django.utils import safestring
from django.utils.translation import ugettext_lazy as _  # noqa

from horizon import exceptions
from horizon import messages
from horizon import tables

from openstack_dashboard import api
from openstack_dashboard.api import swift


LOG = logging.getLogger(__name__)
LOADING_IMAGE = '<img src="/static/dashboard/img/loading.gif" />'


def wrap_delimiter(name):
    if name and not name.endswith(swift.FOLDER_DELIMITER):
[docs] return name + swift.FOLDER_DELIMITER return name class ViewContainer(tables.LinkAction): name = "view"
[docs] verbose_name = _("View Details") url = "horizon:project:containers:container_detail" classes = ("ajax-modal", "btn-view") def get_link_url(self, datum=None): obj_id = self.table.get_object_id(datum)
[docs] verbose_name = _("Make Public") classes = ("btn-edit", ) def allowed(self, request, container): # Container metadata have not been loaded
[docs] if not hasattr(container, 'is_public'): return False return not container.is_public def single(self, table, request, obj_id): try:
[docs] api.swift.swift_update_container(request, obj_id, metadata=({'is_public': True})) LOG.info('Updating container "%s" access to public.' % obj_id) messages.success(request, _('Successfully updated container access to ' 'public.')) except Exception: exceptions.handle(request, _('Unable to update container access.')) return shortcuts.redirect('horizon:project:containers:index') class MakePrivateContainer(tables.Action): name = "make_private"
[docs] verbose_name = _("Make Private") classes = ("btn-edit", ) def allowed(self, request, container): # Container metadata have not been loaded
[docs] if not hasattr(container, 'is_public'): return False return container.is_public def single(self, table, request, obj_id): try:
[docs] api.swift.swift_update_container(request, obj_id, metadata=({'is_public': False})) LOG.info('Updating container "%s" access to private.' % obj_id) messages.success(request, _('Successfully updated container access to ' 'private.')) except Exception: exceptions.handle(request, _('Unable to update container access.')) return shortcuts.redirect('horizon:project:containers:index') class DeleteContainer(tables.DeleteAction): data_type_singular = _("Container")
[docs] data_type_plural = _("Containers") success_url = "horizon:project:containers:index" def delete(self, request, obj_id): api.swift.swift_delete_container(request, obj_id)
[docs] def get_success_url(self, request=None): """Returns the URL to redirect to after a successful action.
[docs] """ current_container = self.table.kwargs.get("container_name", None) # If the current_container is deleted, then redirect to the default # completion url if current_container in self.success_ids: return self.success_url return request.get_full_path() class CreateContainer(tables.LinkAction): name = "create"
[docs] verbose_name = _("Create Container") url = "horizon:project:containers:create" classes = ("ajax-modal", "btn-create") class ListObjects(tables.LinkAction): name = "list_objects"
[docs] verbose_name = _("View Container") url = "horizon:project:containers:index" classes = ("btn-list",) def get_link_url(self, datum=None): container_name = http.urlquote(datum.name)
[docs] verbose_name = _("Create Pseudo-folder") url = "horizon:project:containers:create_pseudo_folder" classes = ("ajax-modal", "btn-create") def get_link_url(self, datum=None): # Usable for both the container and object tables
[docs] return True return False def update(self, request, obj): # This will only be called for the row, so we can remove the button
[docs] # styles meant for the table action version. self.attrs = {'class': 'ajax-modal'} class UploadObject(tables.LinkAction): name = "upload"
[docs] verbose_name = _("Upload Object") url = "horizon:project:containers:object_upload" classes = ("ajax-modal", "btn-upload") def get_link_url(self, datum=None): # Usable for both the container and object tables
[docs] return True return False def update(self, request, obj): # This will only be called for the row, so we can remove the button
[docs] # styles meant for the table action version. self.attrs = {'class': 'ajax-modal'} def get_size_used(container): return filters.filesizeformat(container.bytes)
[docs] def get_container_link(container): return reverse("horizon:project:containers:index",
[docs] def get_data(self, request, container_name): container = api.swift.swift_get_container(request, container_name)
[docs] return container def get_metadata(container): # If the metadata has not been loading, display a loading image
[docs] if not hasattr(container, 'is_public'): return safestring.mark_safe(LOADING_IMAGE) template_name = 'project/containers/_container_metadata.html' context = {"container": container} return template.loader.render_to_string(template_name, context) def get_metadata_loaded(container): # Determine if metadata has been loaded if the attribute is already set.
[docs] return hasattr(container, 'is_public') and container.is_public is not None class ContainersTable(tables.DataTable): METADATA_LOADED_CHOICES = (
[docs] (False, None), (True, True), ) name = tables.Column("name", link=get_container_link, verbose_name=_("Container Name")) metadata = tables.Column(get_metadata, verbose_name=_("Container Details"), classes=('nowrap-col', ),) metadata_loaded = tables.Column(get_metadata_loaded, verbose_name=_("Metadata Loaded"), status=True, status_choices=METADATA_LOADED_CHOICES, hidden=True) class Meta: name = "containers"
[docs] verbose_name = _("Containers") row_class = ContainerAjaxUpdateRow status_columns = ['metadata_loaded', ] table_actions = (CreateContainer,) row_actions = (ViewContainer, MakePublicContainer, MakePrivateContainer, DeleteContainer,) browser_table = "navigation" footer = False def get_object_id(self, container): return container.name
[docs] def get_absolute_url(self): url = super(ContainersTable, self).get_absolute_url()
[docs] return http.urlquote(url) class ViewObject(tables.LinkAction): name = "view"
[docs] verbose_name = _("View Details") url = "horizon:project:containers:object_detail" classes = ("ajax-modal", "btn-view") allowed_data_types = ("objects",) def get_link_url(self, obj): container_name = self.table.kwargs['container_name']
[docs] data_type_singular = _("Object") data_type_plural = _("Objects") allowed_data_types = ("objects",) def delete(self, request, obj_id): obj = self.table.get_object_by_id(obj_id)
[docs] container_name = obj.container_name api.swift.swift_delete_object(request, container_name, obj_id) def get_success_url(self, request): url = super(DeleteObject, self).get_success_url(request)
[docs] return http.urlquote(url) class DeleteMultipleObjects(DeleteObject): name = "delete_multiple_objects"
[docs] data_type_singular = _("Object") data_type_plural = _("Objects") allowed_data_types = ("objects",) class CopyObject(tables.LinkAction): name = "copy"
[docs] verbose_name = _("Copy") url = "horizon:project:containers:object_copy" classes = ("ajax-modal", "btn-copy") allowed_data_types = ("objects",) def get_link_url(self, obj): container_name = self.table.kwargs['container_name']
[docs] verbose_name = _("Download") url = "horizon:project:containers:object_download" classes = ("btn-download",) allowed_data_types = ("objects",) def get_link_url(self, obj): container_name = self.table.kwargs['container_name']
[docs] request = table.request container = self.table.kwargs['container_name'] subfolder = self.table.kwargs['subfolder_path'] prefix = wrap_delimiter(subfolder) if subfolder else '' self.filtered_data = api.swift.swift_filter_objects(request, filter_string, container, prefix=prefix) return self.filtered_data def filter_subfolders_data(self, table, objects, filter_string): data = self._filtered_data(table, filter_string)
[docs] return [datum for datum in data if datum.content_type == "application/pseudo-folder"] def filter_objects_data(self, table, objects, filter_string): data = self._filtered_data(table, filter_string)
[docs] return [datum for datum in data if datum.content_type != "application/pseudo-folder"] def allowed(self, request, datum=None): if self.table.kwargs.get('container_name', None):
[docs] return True return False def sanitize_name(name): return name.split(swift.FOLDER_DELIMITER)[-1]
[docs] def get_size(obj): if obj.bytes:
[docs] return filters.filesizeformat(obj.bytes) def get_link_subfolder(subfolder): container_name = subfolder.container_name
[docs] link=get_link_subfolder, allowed_data_types=("subfolders",), verbose_name=_("Object Name"), filters=(sanitize_name,)) size = tables.Column(get_size, verbose_name=_('Size')) class Meta: name = "objects"
[docs] verbose_name = _("Objects") table_actions = (ObjectFilterAction, CreatePseudoFolder, UploadObject, DeleteMultipleObjects) row_actions = (DownloadObject, CopyObject, ViewObject, DeleteObject) data_types = ("subfolders", "objects") browser_table = "content" footer = False def get_absolute_url(self): url = super(ObjectsTable, self).get_absolute_url()
[docs] return http.urlquote(url)