summaryrefslogtreecommitdiff
path: root/horizon/dashboards/nova
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-08-12 10:47:12 +0000
committerGerrit Code Review <review@openstack.org>2012-08-12 10:47:12 +0000
commitb0066309fd57c0d20f754d3ecea94b617235f40e (patch)
tree09c6c775ee6dc5410ed186cae3909e99a8e69d3a /horizon/dashboards/nova
parentcaf166eacba9bb4f47fc668a8ea74688cd4e4b5e (diff)
parent89d3d11cb1fc237b9366d630ab67de49b338e7a6 (diff)
downloadtuskar-ui-b0066309fd57c0d20f754d3ecea94b617235f40e.tar.gz
Merge "Adds ResourceBrowser and ResourceBrowserView class"
Diffstat (limited to 'horizon/dashboards/nova')
-rw-r--r--horizon/dashboards/nova/containers/browsers.py32
-rw-r--r--horizon/dashboards/nova/containers/forms.py2
-rw-r--r--horizon/dashboards/nova/containers/tables.py83
-rw-r--r--horizon/dashboards/nova/containers/templates/containers/_copy.html2
-rw-r--r--horizon/dashboards/nova/containers/templates/containers/_upload.html2
-rw-r--r--horizon/dashboards/nova/containers/templates/containers/detail.html32
-rw-r--r--horizon/dashboards/nova/containers/templates/containers/index.html20
-rw-r--r--horizon/dashboards/nova/containers/tests.py60
-rw-r--r--horizon/dashboards/nova/containers/urls.py11
-rw-r--r--horizon/dashboards/nova/containers/views.py115
10 files changed, 193 insertions, 166 deletions
diff --git a/horizon/dashboards/nova/containers/browsers.py b/horizon/dashboards/nova/containers/browsers.py
new file mode 100644
index 00000000..0b986a8c
--- /dev/null
+++ b/horizon/dashboards/nova/containers/browsers.py
@@ -0,0 +1,32 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# 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.utils.translation import ugettext_lazy as _
+
+from horizon import browsers
+from .tables import ContainersTable, ObjectsTable
+
+
+LOG = logging.getLogger(__name__)
+
+
+class ContainerBrowser(browsers.ResourceBrowser):
+ name = "swift"
+ verbose_name = _("Swift")
+ navigation_table_class = ContainersTable
+ content_table_class = ObjectsTable
diff --git a/horizon/dashboards/nova/containers/forms.py b/horizon/dashboards/nova/containers/forms.py
index 9be240b8..bde2f32c 100644
--- a/horizon/dashboards/nova/containers/forms.py
+++ b/horizon/dashboards/nova/containers/forms.py
@@ -114,7 +114,7 @@ class CopyObject(forms.SelfHandlingForm):
self.fields['new_container_name'].choices = containers
def handle(self, request, data):
- object_index = "horizon:nova:containers:object_index"
+ object_index = "horizon:nova:containers:index"
orig_container = data['orig_container_name']
orig_object = data['orig_object_name']
new_container = data['new_container_name']
diff --git a/horizon/dashboards/nova/containers/tables.py b/horizon/dashboards/nova/containers/tables.py
index 72ae557f..65b2db35 100644
--- a/horizon/dashboards/nova/containers/tables.py
+++ b/horizon/dashboards/nova/containers/tables.py
@@ -25,14 +25,21 @@ from django.utils.translation import ugettext_lazy as _
from horizon import api
from horizon import messages
from horizon import tables
+from horizon.api import FOLDER_DELIMITER
+from horizon.tables import DataTable
LOG = logging.getLogger(__name__)
+def wrap_delimiter(name):
+ return name + FOLDER_DELIMITER
+
+
class DeleteContainer(tables.DeleteAction):
data_type_singular = _("Container")
data_type_plural = _("Containers")
+ completion_url = "horizon:nova:containers:index"
def delete(self, request, obj_id):
try:
@@ -42,6 +49,18 @@ class DeleteContainer(tables.DeleteAction):
_('Containers must be empty before deletion.'))
raise
+ def get_success_url(self, request=None):
+ """
+ Returns the URL to redirect to after a successful action.
+ """
+ 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.completion_url
+ return request.get_full_path()
+
class CreateContainer(tables.LinkAction):
name = "create"
@@ -53,9 +72,14 @@ class CreateContainer(tables.LinkAction):
class ListObjects(tables.LinkAction):
name = "list_objects"
verbose_name = _("View Container")
- url = "horizon:nova:containers:object_index"
+ url = "horizon:nova:containers:index"
classes = ("btn-list",)
+ def get_link_url(self, datum=None):
+ container_name = http.urlquote(datum.name)
+ args = (wrap_delimiter(container_name),)
+ return reverse(self.url, args=args)
+
class UploadObject(tables.LinkAction):
name = "upload"
@@ -76,6 +100,11 @@ class UploadObject(tables.LinkAction):
(container_name, subfolders) if bit)
return reverse(self.url, args=args)
+ def allowed(self, request, datum=None):
+ if self.table.kwargs.get('container_name', None):
+ return True
+ return False
+
def update(self, request, obj):
# This will only be called for the row, so we can remove the button
# styles meant for the table action version.
@@ -86,15 +115,14 @@ def get_size_used(container):
return filesizeformat(container.size_used)
+def get_container_link(container):
+ return reverse("horizon:nova:containers:index",
+ args=(http.urlquote(wrap_delimiter(container.name)),))
+
+
class ContainersTable(tables.DataTable):
- name = tables.Column("name", link='horizon:nova:containers:object_index',
+ name = tables.Column("name", link=get_container_link,
verbose_name=_("Container Name"))
- objects = tables.Column("object_count",
- verbose_name=_('Objects'),
- empty_value="0")
- size = tables.Column(get_size_used,
- verbose_name=_('Size'),
- attrs={'data-type': 'size'})
def get_object_id(self, container):
return container.name
@@ -102,8 +130,9 @@ class ContainersTable(tables.DataTable):
class Meta:
name = "containers"
verbose_name = _("Containers")
- table_actions = (CreateContainer, DeleteContainer)
+ table_actions = (CreateContainer,)
row_actions = (ListObjects, UploadObject, DeleteContainer)
+ browser_table = "navigation"
class DeleteObject(tables.DeleteAction):
@@ -127,8 +156,8 @@ class DeleteSubfolder(DeleteObject):
class DeleteMultipleObjects(DeleteObject):
name = "delete_multiple_objects"
- data_type_singular = _("Object/Folder")
- data_type_plural = _("Objects/Folders")
+ data_type_singular = _("Object")
+ data_type_plural = _("Objects")
allowed_data_types = ("subfolders", "objects",)
@@ -161,7 +190,7 @@ class ObjectFilterAction(tables.FilterAction):
request = table._meta.request
container = self.table.kwargs['container_name']
subfolder = self.table.kwargs['subfolder_path']
- path = subfolder + '/' if subfolder else ''
+ path = subfolder + FOLDER_DELIMITER if subfolder else ''
self.filtered_data = api.swift_filter_objects(request,
filter_string,
container,
@@ -178,9 +207,14 @@ class ObjectFilterAction(tables.FilterAction):
return [datum for datum in data if
datum.content_type != "application/directory"]
+ def allowed(self, request, datum=None):
+ if self.table.kwargs.get('container_name', None):
+ return True
+ return False
+
def sanitize_name(name):
- return name.split("/")[-1]
+ return name.split(FOLDER_DELIMITER)[-1]
def get_size(obj):
@@ -188,9 +222,10 @@ def get_size(obj):
def get_link_subfolder(subfolder):
- return reverse("horizon:nova:containers:object_index",
- args=(http.urlquote(subfolder.container.name),
- http.urlquote(subfolder.name + "/")))
+ container_name = subfolder.container.name
+ return reverse("horizon:nova:containers:index",
+ args=(http.urlquote(wrap_delimiter(container_name)),
+ http.urlquote(wrap_delimiter(subfolder.name))))
class CreateSubfolder(CreateContainer):
@@ -200,9 +235,15 @@ class CreateSubfolder(CreateContainer):
def get_link_url(self):
container = self.table.kwargs['container_name']
subfolders = self.table.kwargs['subfolder_path']
- parent = "/".join((bit for bit in [container, subfolders] if bit))
- parent = parent.rstrip("/")
- return reverse(self.url, args=(http.urlquote(parent + "/"),))
+ parent = FOLDER_DELIMITER.join((bit for bit in [container,
+ subfolders] if bit))
+ parent = parent.rstrip(FOLDER_DELIMITER)
+ return reverse(self.url, args=[http.urlquote(wrap_delimiter(parent))])
+
+ def allowed(self, request, datum=None):
+ if self.table.kwargs.get('container_name', None):
+ return True
+ return False
class ObjectsTable(tables.DataTable):
@@ -211,6 +252,7 @@ class ObjectsTable(tables.DataTable):
allowed_data_types=("subfolders",),
verbose_name=_("Object Name"),
filters=(sanitize_name,))
+
size = tables.Column(get_size, verbose_name=_('Size'))
def get_object_id(self, obj):
@@ -218,9 +260,10 @@ class ObjectsTable(tables.DataTable):
class Meta:
name = "objects"
- verbose_name = _("Subfolders and Objects")
+ verbose_name = _("Objects")
table_actions = (ObjectFilterAction, CreateSubfolder,
UploadObject, DeleteMultipleObjects)
row_actions = (DownloadObject, CopyObject, DeleteObject,
DeleteSubfolder)
data_types = ("subfolders", "objects")
+ browser_table = "content"
diff --git a/horizon/dashboards/nova/containers/templates/containers/_copy.html b/horizon/dashboards/nova/containers/templates/containers/_copy.html
index 870c8689..aef4431d 100644
--- a/horizon/dashboards/nova/containers/templates/containers/_copy.html
+++ b/horizon/dashboards/nova/containers/templates/containers/_copy.html
@@ -20,5 +20,5 @@
{% block modal-footer %}
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Copy Object" %}" />
- <a href="{% url horizon:nova:containers:object_index container_name %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
+ <a href="{% url horizon:nova:containers:index container_name|add:'/' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
{% endblock %}
diff --git a/horizon/dashboards/nova/containers/templates/containers/_upload.html b/horizon/dashboards/nova/containers/templates/containers/_upload.html
index 22d137ae..fd838571 100644
--- a/horizon/dashboards/nova/containers/templates/containers/_upload.html
+++ b/horizon/dashboards/nova/containers/templates/containers/_upload.html
@@ -21,5 +21,5 @@
{% block modal-footer %}
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Upload Object" %}" />
- <a href="{% url horizon:nova:containers:object_index container_name %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
+ <a href="{% url horizon:nova:containers:index container_name|add:'/' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
{% endblock %}
diff --git a/horizon/dashboards/nova/containers/templates/containers/detail.html b/horizon/dashboards/nova/containers/templates/containers/detail.html
deleted file mode 100644
index a2e15f49..00000000
--- a/horizon/dashboards/nova/containers/templates/containers/detail.html
+++ /dev/null
@@ -1,32 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Objects" %}{% endblock %}
-
-{% block page_header %}
- <div class='page-header'>
- <h2>{% trans "Container" %}:
- {% if subfolders %}
- <a href="{% url horizon:nova:containers:object_index container_name=container_name %}">{{container_name}}</a>
- <small>/</small>
- {% else %}
- {{container_name}}
- {% endif %}
- {% for subfolder, path in subfolders %}
- <small>
- {% if not forloop.last %}
- <a href="{% url horizon:nova:containers:object_index container_name=container_name subfolder_path=path %}">
- {% endif %}{{ subfolder }}{% if not forloop.last %}</a> /{% endif %}
- </small>
- {% endfor %}
- </h2>
- </div>
-{% endblock page_header %}
-
-{% block main %}
- <div id="subfolders">
- {{ subfolders_table.render }}
- </div>
- <div id="objects">
- {{ objects_table.render }}
- </div>
-{% endblock %}
diff --git a/horizon/dashboards/nova/containers/templates/containers/index.html b/horizon/dashboards/nova/containers/templates/containers/index.html
index 2060972c..1dc45d98 100644
--- a/horizon/dashboards/nova/containers/templates/containers/index.html
+++ b/horizon/dashboards/nova/containers/templates/containers/index.html
@@ -3,9 +3,25 @@
{% block title %}Containers{% endblock %}
{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Containers") %}
+ <div class='page-header'>
+ <h2>{% trans "Container" %}
+ {% if subfolders %}
+ : <a href="{% url horizon:nova:containers:index container_name|add:'/' %}">{{container_name}}</a>
+ <small>/</small>
+ {% elif container_name %}
+ : {{container_name}}
+ {% endif %}
+ {% for subfolder, path in subfolders %}
+ <small>
+ {% if not forloop.last %}
+ <a href="{% url horizon:nova:containers:index container_name|add:'/' path %}">
+ {% endif %}{{ subfolder }}{% if not forloop.last %}</a> /{% endif %}
+ </small>
+ {% endfor %}
+ </h2>
+ </div>
{% endblock page_header %}
{% block main %}
- {{ table.render }}
+ {{ swift_browser.render }}
{% endblock %}
diff --git a/horizon/dashboards/nova/containers/tests.py b/horizon/dashboards/nova/containers/tests.py
index 7e7bbe8d..a39ac220 100644
--- a/horizon/dashboards/nova/containers/tests.py
+++ b/horizon/dashboards/nova/containers/tests.py
@@ -28,7 +28,7 @@ from mox import IsA
from horizon import api
from horizon import test
-from .tables import ContainersTable, ObjectsTable
+from .tables import ContainersTable, ObjectsTable, wrap_delimiter
from . import forms
@@ -93,50 +93,30 @@ class ContainerViewTests(test.TestCase):
'method': forms.CreateContainer.__name__}
res = self.client.post(reverse('horizon:nova:containers:create'),
formData)
- url = reverse('horizon:nova:containers:object_index',
- args=[self.containers.first().name])
+ url = reverse('horizon:nova:containers:index',
+ args=[wrap_delimiter(self.containers.first().name)])
self.assertRedirectsNoFollow(res, url)
-class ObjectViewTests(test.TestCase):
- @test.create_stubs({api: ('swift_get_objects',)})
+class IndexViewTests(test.TestCase):
def test_index(self):
+ self.mox.StubOutWithMock(api, 'swift_get_containers')
+ self.mox.StubOutWithMock(api, 'swift_get_objects')
+ containers = (self.containers.list(), False)
ret = (self.objects.list(), False)
+ api.swift_get_containers(IsA(http.HttpRequest),
+ marker=None).AndReturn(containers)
api.swift_get_objects(IsA(http.HttpRequest),
self.containers.first().name,
marker=None,
path=None).AndReturn(ret)
self.mox.ReplayAll()
- res = self.client.get(reverse('horizon:nova:containers:object_index',
- args=[self.containers.first().name]))
- self.assertEquals(res.context['container_name'],
- self.containers.first().name)
- self.assertTemplateUsed(res, 'nova/containers/detail.html')
- # UTF8 encoding here to ensure there aren't problems with Nose output.
- expected = [obj.name.encode('utf8') for obj in self.objects.list()]
- self.assertQuerysetEqual(res.context['objects_table'].data,
- expected,
- lambda obj: obj.name.encode('utf8'))
-
- @test.create_stubs({api: ('swift_get_objects',)})
- def test_index_subfolders(self):
- ret = (self.objects.list(), False)
- api.swift_get_objects(IsA(http.HttpRequest),
- self.containers.first().name,
- marker=None,
- path='sub1/sub2').AndReturn(ret)
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:nova:containers:object_index',
- args=[self.containers.first().name,
- u'sub1/sub2/']))
- self.assertEquals(res.context['container_name'],
- self.containers.first().name)
- self.assertListEqual(res.context['subfolders'],
- [('sub1', 'sub1/'),
- ('sub2', 'sub1/sub2/'), ])
- self.assertTemplateUsed(res, 'nova/containers/detail.html')
+ res = self.client.get(reverse('horizon:nova:containers:index',
+ args=[wrap_delimiter(self.containers
+ .first()
+ .name)]))
+ self.assertTemplateUsed(res, 'nova/containers/index.html')
# UTF8 encoding here to ensure there aren't problems with Nose output.
expected = [obj.name.encode('utf8') for obj in self.objects.list()]
self.assertQuerysetEqual(res.context['objects_table'].data,
@@ -177,8 +157,8 @@ class ObjectViewTests(test.TestCase):
'object_file': temp_file}
res = self.client.post(upload_url, formData)
- index_url = reverse('horizon:nova:containers:object_index',
- args=[container.name])
+ index_url = reverse('horizon:nova:containers:index',
+ args=[wrap_delimiter(container.name)])
self.assertRedirectsNoFollow(res, index_url)
# Test invalid filename
@@ -197,8 +177,8 @@ class ObjectViewTests(test.TestCase):
def test_delete(self):
container = self.containers.first()
obj = self.objects.first()
- index_url = reverse('horizon:nova:containers:object_index',
- args=[container.name])
+ index_url = reverse('horizon:nova:containers:index',
+ args=[wrap_delimiter(container.name)])
self.mox.StubOutWithMock(api, 'swift_delete_object')
api.swift_delete_object(IsA(http.HttpRequest),
container.name,
@@ -269,6 +249,6 @@ class ObjectViewTests(test.TestCase):
copy_url = reverse('horizon:nova:containers:object_copy',
args=[container_1.name, obj.name])
res = self.client.post(copy_url, formData)
- index_url = reverse('horizon:nova:containers:object_index',
- args=[container_2.name])
+ index_url = reverse('horizon:nova:containers:index',
+ args=[wrap_delimiter(container_2.name)])
self.assertRedirectsNoFollow(res, index_url)
diff --git a/horizon/dashboards/nova/containers/urls.py b/horizon/dashboards/nova/containers/urls.py
index c72f1fc1..363b19c7 100644
--- a/horizon/dashboards/nova/containers/urls.py
+++ b/horizon/dashboards/nova/containers/urls.py
@@ -20,22 +20,19 @@
from django.conf.urls.defaults import patterns, url
-from .views import IndexView, CreateView, UploadView, ObjectIndexView, CopyView
+from .views import CreateView, UploadView, CopyView, ContainerView
# Swift containers and objects.
urlpatterns = patterns('horizon.dashboards.nova.containers.views',
- url(r'^$', IndexView.as_view(), name='index'),
+ url(r'^((?P<container_name>.+?)/)?(?P<subfolder_path>(.+/)+)?$',
+ ContainerView.as_view(), name='index'),
url(r'^(?P<container_name>(.+/)+)?create$',
CreateView.as_view(),
name='create'),
- url(r'^(?P<container_name>[^/]+)/(?P<subfolder_path>(.+/)+)?$',
- ObjectIndexView.as_view(),
- name='object_index'),
-
- url(r'^(?P<container_name>[^/]+)/(?P<subfolder_path>(.+/)+)?upload$',
+ url(r'^(?P<container_name>.+?)/(?P<subfolder_path>(.+/)+)?upload$',
UploadView.as_view(),
name='object_upload'),
diff --git a/horizon/dashboards/nova/containers/views.py b/horizon/dashboards/nova/containers/views.py
index 91b9aaca..e2d5d9a8 100644
--- a/horizon/dashboards/nova/containers/views.py
+++ b/horizon/dashboards/nova/containers/views.py
@@ -21,7 +21,6 @@
"""
Views for managing Swift containers.
"""
-import logging
import os
from django import http
@@ -29,24 +28,20 @@ from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from horizon import api
+from horizon import browsers
from horizon import exceptions
from horizon import forms
-from horizon import tables
+from horizon.api import FOLDER_DELIMITER
+from .browsers import ContainerBrowser
from .forms import CreateContainer, UploadObject, CopyObject
-from .tables import ContainersTable, ObjectsTable
+from .tables import wrap_delimiter
-LOG = logging.getLogger(__name__)
+class ContainerView(browsers.ResourceBrowserView):
+ browser_class = ContainerBrowser
+ template_name = "nova/containers/index.html"
-
-class IndexView(tables.DataTableView):
- table_class = ContainersTable
- template_name = 'nova/containers/index.html'
-
- def has_more_data(self, table):
- return self._more
-
- def get_data(self):
+ def get_containers_data(self):
containers = []
self._more = None
marker = self.request.GET.get('marker', None)
@@ -58,35 +53,6 @@ class IndexView(tables.DataTableView):
exceptions.handle(self.request, msg)
return containers
-
-class CreateView(forms.ModalFormView):
- form_class = CreateContainer
- template_name = 'nova/containers/create.html'
- success_url = "horizon:nova:containers:object_index"
-
- def get_success_url(self):
- parent = self.request.POST.get('parent', None)
- if parent:
- container, slash, remainder = parent.partition("/")
- if remainder and not remainder.endswith("/"):
- remainder = "".join([remainder, "/"])
- return reverse(self.success_url, args=(container, remainder))
- else:
- return reverse(self.success_url, args=[self.request.POST['name']])
-
- def get_initial(self):
- initial = super(CreateView, self).get_initial()
- initial['parent'] = self.kwargs['container_name']
- return initial
-
-
-class ObjectIndexView(tables.MixedDataTableView):
- table_class = ObjectsTable
- template_name = 'nova/containers/detail.html'
-
- def has_more_data(self, table):
- return self._more
-
@property
def objects(self):
""" Returns a list of objects given the subfolder's path.
@@ -99,20 +65,20 @@ class ObjectIndexView(tables.MixedDataTableView):
marker = self.request.GET.get('marker', None)
container_name = self.kwargs['container_name']
subfolders = self.kwargs['subfolder_path']
- if subfolders:
- prefix = subfolders.rstrip("/")
- else:
- prefix = None
- try:
- objects, self._more = api.swift_get_objects(self.request,
- container_name,
- marker=marker,
- path=prefix)
- except:
- self._more = None
- objects = []
- msg = _('Unable to retrieve object list.')
- exceptions.handle(self.request, msg)
+ prefix = None
+ if container_name:
+ if subfolders:
+ prefix = subfolders.rstrip(FOLDER_DELIMITER)
+ try:
+ objects, self._more = api.swift_get_objects(self.request,
+ container_name,
+ marker=marker,
+ path=prefix)
+ except:
+ self._more = None
+ objects = []
+ msg = _('Unable to retrieve object list.')
+ exceptions.handle(self.request, msg)
self._objects = objects
return self._objects
@@ -134,7 +100,7 @@ class ObjectIndexView(tables.MixedDataTableView):
return filtered_objects
def get_context_data(self, **kwargs):
- context = super(ObjectIndexView, self).get_context_data(**kwargs)
+ context = super(ContainerView, self).get_context_data(**kwargs)
context['container_name'] = self.kwargs["container_name"]
context['subfolders'] = []
if self.kwargs["subfolder_path"]:
@@ -147,14 +113,38 @@ class ObjectIndexView(tables.MixedDataTableView):
return context
+class CreateView(forms.ModalFormView):
+ form_class = CreateContainer
+ template_name = 'nova/containers/create.html'
+ success_url = "horizon:nova:containers:index"
+
+ def get_success_url(self):
+ parent = self.request.POST.get('parent', None)
+ if parent:
+ container, slash, remainder = parent.partition(FOLDER_DELIMITER)
+ container += FOLDER_DELIMITER
+ if remainder and not remainder.endswith(FOLDER_DELIMITER):
+ remainder = "".join([remainder, FOLDER_DELIMITER])
+ return reverse(self.success_url, args=(container, remainder))
+ else:
+ return reverse(self.success_url, args=[self.request.POST['name'] +
+ FOLDER_DELIMITER])
+
+ def get_initial(self):
+ initial = super(CreateView, self).get_initial()
+ initial['parent'] = self.kwargs['container_name']
+ return initial
+
+
class UploadView(forms.ModalFormView):
form_class = UploadObject
template_name = 'nova/containers/upload.html'
- success_url = "horizon:nova:containers:object_index"
+ success_url = "horizon:nova:containers:index"
def get_success_url(self):
+ container_name = self.request.POST['container_name']
return reverse(self.success_url,
- args=(self.request.POST['container_name'],
+ args=(wrap_delimiter(container_name),
self.request.POST.get('path', '')))
def get_initial(self):
@@ -171,7 +161,7 @@ def object_download(request, container_name, object_path):
obj = api.swift.swift_get_object(request, container_name, object_path)
# Add the original file extension back on if it wasn't preserved in the
# name given to the object.
- filename = object_path.rsplit("/")[-1]
+ filename = object_path.rsplit(FOLDER_DELIMITER)[-1]
if not os.path.splitext(obj.name)[1]:
name, ext = os.path.splitext(obj.metadata.get('orig-filename', ''))
filename = "%s%s" % (filename, ext)
@@ -196,11 +186,12 @@ def object_download(request, container_name, object_path):
class CopyView(forms.ModalFormView):
form_class = CopyObject
template_name = 'nova/containers/copy.html'
- success_url = "horizon:nova:containers:object_index"
+ success_url = "horizon:nova:containers:index"
def get_success_url(self):
+ new_container_name = self.request.POST['new_container_name']
return reverse(self.success_url,
- args=(self.request.POST['new_container_name'],
+ args=(wrap_delimiter(new_container_name),
self.request.POST.get('path', '')))
def get_form_kwargs(self):