summaryrefslogtreecommitdiff
path: root/openstack_dashboard/dashboards/project/containers
diff options
context:
space:
mode:
authorLin Hua Cheng <lin-hua.cheng@hp.com>2013-08-19 09:44:12 -0700
committerLin Hua Cheng <lin-hua.cheng@hp.com>2013-08-20 11:08:43 -0700
commit7f51d554019e02269ebda98f1d097e89862c8da0 (patch)
tree63cfae6b0634a847ecd574612d8216be535aa4d4 /openstack_dashboard/dashboards/project/containers
parentc17a29390d482768e5baebe800ebcf62e5972a92 (diff)
downloadhorizon-7f51d554019e02269ebda98f1d097e89862c8da0.tar.gz
Display the container and object metadata
Display some of the useful metadata information from swift: Container Details - Container Name, Object Count, Size Object Details - Name, Hash, Content Type, Last Modified, Size Change-Id: I6611cab08946a81624176c1836ceadaf16a68e45 Implements: blueprint swift-display-metadata
Diffstat (limited to 'openstack_dashboard/dashboards/project/containers')
-rw-r--r--openstack_dashboard/dashboards/project/containers/tables.py23
-rw-r--r--openstack_dashboard/dashboards/project/containers/templates/containers/_container_detail.html22
-rw-r--r--openstack_dashboard/dashboards/project/containers/templates/containers/_object_detail.html26
-rw-r--r--openstack_dashboard/dashboards/project/containers/templates/containers/container_detail.html12
-rw-r--r--openstack_dashboard/dashboards/project/containers/templates/containers/object_detail.html12
-rw-r--r--openstack_dashboard/dashboards/project/containers/tests.py36
-rw-r--r--openstack_dashboard/dashboards/project/containers/urls.py15
-rw-r--r--openstack_dashboard/dashboards/project/containers/views.py46
8 files changed, 189 insertions, 3 deletions
diff --git a/openstack_dashboard/dashboards/project/containers/tables.py b/openstack_dashboard/dashboards/project/containers/tables.py
index ccb9d1bfd..9757a7746 100644
--- a/openstack_dashboard/dashboards/project/containers/tables.py
+++ b/openstack_dashboard/dashboards/project/containers/tables.py
@@ -36,6 +36,13 @@ def wrap_delimiter(name):
return name
+class ViewContainer(tables.LinkAction):
+ name = "view"
+ verbose_name = _("View Details")
+ url = "horizon:project:containers:container_detail"
+ classes = ("ajax-modal", "btn-view")
+
+
class DeleteContainer(tables.DeleteAction):
data_type_singular = _("Container")
data_type_plural = _("Containers")
@@ -127,11 +134,23 @@ class ContainersTable(tables.DataTable):
name = "containers"
verbose_name = _("Containers")
table_actions = (CreateContainer,)
- row_actions = (DeleteContainer,)
+ row_actions = (ViewContainer, DeleteContainer,)
browser_table = "navigation"
footer = False
+class ViewObject(tables.LinkAction):
+ name = "view"
+ verbose_name = _("View Details")
+ url = "horizon:project:containers:object_detail"
+ classes = ("ajax-modal", "btn-view")
+
+ def get_link_url(self, obj):
+ container_name = self.table.kwargs['container_name']
+ return reverse(self.url, args=(http.urlquote(container_name),
+ http.urlquote(obj.name)))
+
+
class DeleteObject(tables.DeleteAction):
name = "delete_object"
data_type_singular = _("Object")
@@ -235,7 +254,7 @@ class ObjectsTable(tables.DataTable):
verbose_name = _("Objects")
table_actions = (ObjectFilterAction, UploadObject,
DeleteMultipleObjects)
- row_actions = (DownloadObject, CopyObject, DeleteObject)
+ row_actions = (DownloadObject, CopyObject, ViewObject, DeleteObject)
data_types = ("subfolders", "objects")
browser_table = "content"
footer = False
diff --git a/openstack_dashboard/dashboards/project/containers/templates/containers/_container_detail.html b/openstack_dashboard/dashboards/project/containers/templates/containers/_container_detail.html
new file mode 100644
index 000000000..691731df0
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/containers/templates/containers/_container_detail.html
@@ -0,0 +1,22 @@
+{% extends "horizon/common/_modal.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block modal-header %}{% trans "Container Details" %}{% endblock %}
+
+{% block modal-body %}
+<div class="info row-fluid detail clearfix">
+ <dl>
+ <dt>{% trans "Container Name" %}</dt>
+ <dd>{{ container.name }}</dd>
+ <dt>{% trans "Object Count" %}</dt>
+ <dd>{{ container.container_object_count }}</dd>
+ <dt>{% trans "Size" %}</dt>
+ <dd>{{ container.container_bytes_used|filesizeformat }}</dd>
+ </dl>
+</div>
+{% endblock %}
+
+{% block modal-footer %}
+ <a href="{% url 'horizon:project:containers:index' %}" class="btn secondary cancel close">{% trans "Close" %}</a>
+{% endblock %} \ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/containers/templates/containers/_object_detail.html b/openstack_dashboard/dashboards/project/containers/templates/containers/_object_detail.html
new file mode 100644
index 000000000..cd07538cd
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/containers/templates/containers/_object_detail.html
@@ -0,0 +1,26 @@
+{% extends "horizon/common/_modal.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block modal-header %}{% trans "Object Details" %}{% endblock %}
+
+{% block modal-body %}
+<div class="info row-fluid detail">
+ <dl>
+ <dt>{% trans "Name" %}</dt>
+ <dd>{{ object.name }}</dd>
+ <dt>{% trans "Hash" %}</dt>
+ <dd>{{ object.etag }}</dd>
+ <dt>{% trans "Content Type" %}</dt>
+ <dd>{{ object.content_type }}</dd>
+ <dt>{% trans "Last Modified" %}</dt>
+ <dd>{{ object.timestamp|parse_isotime }}</dd>
+ <dt>{% trans "Size" %}</dt>
+ <dd>{{ object.bytes|filesizeformat }}</dd>
+ </dl>
+</div>
+{% endblock %}
+
+{% block modal-footer %}
+ <a href="{% url 'horizon:project:containers:index' %}" class="btn secondary cancel close">{% trans "Close" %}</a>
+{% endblock %} \ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/containers/templates/containers/container_detail.html b/openstack_dashboard/dashboards/project/containers/templates/containers/container_detail.html
new file mode 100644
index 000000000..6fa77c384
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/containers/templates/containers/container_detail.html
@@ -0,0 +1,12 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% block title %}{% trans "Container Details" %}{% endblock %}
+
+{% block page_header %}
+ {% include "horizon/common/_page_header.html" with title=_("Container Details") %}
+{% endblock page_header %}
+
+{% block main %}
+ {% include 'project/containers/_container_detail.html' %}
+{% endblock %}
+
diff --git a/openstack_dashboard/dashboards/project/containers/templates/containers/object_detail.html b/openstack_dashboard/dashboards/project/containers/templates/containers/object_detail.html
new file mode 100644
index 000000000..7174389c8
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/containers/templates/containers/object_detail.html
@@ -0,0 +1,12 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% block title %}{% trans "Object Details" %}{% endblock %}
+
+{% block page_header %}
+ {% include "horizon/common/_page_header.html" with title=_("Object Details") %}
+{% endblock page_header %}
+
+{% block main %}
+ {% include 'project/containers/_object_detail.html' %}
+{% endblock %}
+
diff --git a/openstack_dashboard/dashboards/project/containers/tests.py b/openstack_dashboard/dashboards/project/containers/tests.py
index 193bb0e0c..36ea84ad3 100644
--- a/openstack_dashboard/dashboards/project/containers/tests.py
+++ b/openstack_dashboard/dashboards/project/containers/tests.py
@@ -237,3 +237,39 @@ class SwiftTests(test.TestCase):
index_url = reverse('horizon:project:containers:index',
args=[wrap_delimiter(container_2.name)])
self.assertRedirectsNoFollow(res, index_url)
+
+ @test.create_stubs({api.swift: ('swift_get_container', )})
+ def test_view_container(self):
+ container = self.containers.first()
+
+ api.swift.swift_get_container(IsA(http.HttpRequest),
+ container.name) \
+ .AndReturn(container)
+ self.mox.ReplayAll()
+
+ view_url = reverse('horizon:project:containers:container_detail',
+ args=[container.name])
+ res = self.client.get(view_url)
+
+ self.assertTemplateUsed(res,
+ 'project/containers/container_detail.html')
+ self.assertContains(res, container.name, 1, 200)
+
+ @test.create_stubs({api.swift: ('swift_get_object', )})
+ def test_view_object(self):
+ container = self.containers.first()
+ obj = self.objects.first()
+
+ api.swift.swift_get_object(IsA(http.HttpRequest),
+ container.name,
+ obj.name) \
+ .AndReturn(obj)
+ self.mox.ReplayAll()
+
+ view_url = reverse('horizon:project:containers:object_detail',
+ args=[container.name, obj.name])
+ res = self.client.get(view_url)
+
+ self.assertTemplateUsed(res,
+ 'project/containers/object_detail.html')
+ self.assertContains(res, obj.name, 1, 200)
diff --git a/openstack_dashboard/dashboards/project/containers/urls.py b/openstack_dashboard/dashboards/project/containers/urls.py
index 46c71cc73..dc93a212d 100644
--- a/openstack_dashboard/dashboards/project/containers/urls.py
+++ b/openstack_dashboard/dashboards/project/containers/urls.py
@@ -22,9 +22,13 @@ from django.conf.urls.defaults import patterns
from django.conf.urls.defaults import url
from openstack_dashboard.dashboards.project.containers.views import \
+ ContainerDetailView
+from openstack_dashboard.dashboards.project.containers.views import \
ContainerView
from openstack_dashboard.dashboards.project.containers.views import CopyView
from openstack_dashboard.dashboards.project.containers.views import CreateView
+from openstack_dashboard.dashboards.project.containers.views import \
+ ObjectDetailView
from openstack_dashboard.dashboards.project.containers.views import UploadView
@@ -39,6 +43,15 @@ urlpatterns = patterns(VIEW_MOD,
CreateView.as_view(),
name='create'),
+ url(r'^(?P<container_name>.+?)/(?P<subfolder_path>(.+/)+)'
+ '?container_detail$',
+ ContainerDetailView.as_view(),
+ name='container_detail'),
+
+ url(r'^(?P<container_name>[^/]+)/(?P<object_path>.+)/object_detail$',
+ ObjectDetailView.as_view(),
+ name='object_detail'),
+
url(r'^(?P<container_name>.+?)/(?P<subfolder_path>(.+/)+)?upload$',
UploadView.as_view(),
name='object_upload'),
@@ -51,5 +64,5 @@ urlpatterns = patterns(VIEW_MOD,
url(r'^(?P<container_name>[^/]+)/(?P<object_path>.+)/download$',
'object_download',
- name='object_download')
+ name='object_download'),
)
diff --git a/openstack_dashboard/dashboards/project/containers/views.py b/openstack_dashboard/dashboards/project/containers/views.py
index 674eaf699..a27e64164 100644
--- a/openstack_dashboard/dashboards/project/containers/views.py
+++ b/openstack_dashboard/dashboards/project/containers/views.py
@@ -25,6 +25,7 @@ Views for managing Swift containers.
from django.core.urlresolvers import reverse
from django import http
from django.utils.translation import ugettext_lazy as _
+from django.views import generic
from horizon import browsers
from horizon import exceptions
@@ -226,3 +227,48 @@ class CopyView(forms.ModalFormView):
context['container_name'] = self.kwargs["container_name"]
context['object_name'] = self.kwargs["object_name"]
return context
+
+
+class ContainerDetailView(forms.ModalFormMixin, generic.TemplateView):
+ template_name = 'project/containers/container_detail.html'
+
+ def get_object(self):
+ if not hasattr(self, "_object"):
+ try:
+ self._object = api.swift.swift_get_container(
+ self.request,
+ self.kwargs["container_name"])
+ except Exception:
+ redirect = reverse("horizon:project:containers:index")
+ exceptions.handle(self.request,
+ _('Unable to retrieve details.'),
+ redirect=redirect)
+ return self._object
+
+ def get_context_data(self, **kwargs):
+ context = super(ContainerDetailView, self).get_context_data(**kwargs)
+ context['container'] = self.get_object()
+ return context
+
+
+class ObjectDetailView(forms.ModalFormMixin, generic.TemplateView):
+ template_name = 'project/containers/object_detail.html'
+
+ def get_object(self):
+ if not hasattr(self, "_object"):
+ try:
+ self._object = api.swift.swift_get_object(
+ self.request,
+ self.kwargs["container_name"],
+ self.kwargs["object_path"])
+ except Exception:
+ redirect = reverse("horizon:project:containers:index")
+ exceptions.handle(self.request,
+ _('Unable to retrieve details.'),
+ redirect=redirect)
+ return self._object
+
+ def get_context_data(self, **kwargs):
+ context = super(ObjectDetailView, self).get_context_data(**kwargs)
+ context['object'] = self.get_object()
+ return context