Swift Object filter improve and fix
bug#1013409 bug#1013412 Change-Id: Ib2efa534622793bfa9f190d74e3b91cc66e7516a
This commit is contained in:
parent
f6f2a91e14
commit
359a71e0b0
@ -102,6 +102,42 @@ def swift_get_objects(request, container_name, prefix=None, path=None,
|
|||||||
return (objects, False)
|
return (objects, False)
|
||||||
|
|
||||||
|
|
||||||
|
def swift_filter_objects(request, filter_string, container_name, prefix=None,
|
||||||
|
path=None, marker=None):
|
||||||
|
#FIXME(kewu): Cloudfiles currently has no filtering API, thus the marker
|
||||||
|
#parameter here won't actually help the pagination. For now I am just
|
||||||
|
#getting the largest number of objects from a container and filtering based
|
||||||
|
#on those objects.
|
||||||
|
limit = 10000
|
||||||
|
container = swift_api(request).get_container(container_name)
|
||||||
|
objects = container.get_objects(prefix=prefix,
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
delimiter="/",
|
||||||
|
path=path)
|
||||||
|
filter_string_list = filter_string.lower().strip().split(' ')
|
||||||
|
|
||||||
|
return filter(lambda obj: any([
|
||||||
|
obj.content_type != "application/directory"
|
||||||
|
and wildcard_search(obj.name.lower(), q)
|
||||||
|
for q in filter_string_list if q != ''
|
||||||
|
]), objects)
|
||||||
|
|
||||||
|
|
||||||
|
def wildcard_search(string, q):
|
||||||
|
q_list = q.split('*')
|
||||||
|
if all(map(lambda x: x == '', q_list)):
|
||||||
|
return True
|
||||||
|
elif q_list[0] not in string:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
if q_list[0] == '':
|
||||||
|
tail = string
|
||||||
|
else:
|
||||||
|
head, delimiter, tail = string.partition(q_list[0])
|
||||||
|
return wildcard_search(tail, '*'.join(q_list[1:]))
|
||||||
|
|
||||||
|
|
||||||
def swift_copy_object(request, orig_container_name, orig_object_name,
|
def swift_copy_object(request, orig_container_name, orig_object_name,
|
||||||
new_container_name, new_object_name):
|
new_container_name, new_object_name):
|
||||||
try:
|
try:
|
||||||
|
@ -138,15 +138,14 @@ class DownloadObject(tables.LinkAction):
|
|||||||
|
|
||||||
class ObjectFilterAction(tables.FilterAction):
|
class ObjectFilterAction(tables.FilterAction):
|
||||||
def filter(self, table, objects, filter_string):
|
def filter(self, table, objects, filter_string):
|
||||||
""" Really naive case-insensitive search. """
|
request = table._meta.request
|
||||||
q = filter_string.lower()
|
container = self.table.kwargs['container_name']
|
||||||
|
subfolder = self.table.kwargs['subfolder_path']
|
||||||
def comp(object):
|
path = subfolder + '/' if subfolder else ''
|
||||||
if q in object.name.lower():
|
return api.swift_filter_objects(request,
|
||||||
return True
|
filter_string,
|
||||||
return False
|
container,
|
||||||
|
path=path)
|
||||||
return filter(comp, objects)
|
|
||||||
|
|
||||||
|
|
||||||
def sanitize_name(name):
|
def sanitize_name(name):
|
||||||
|
@ -25,6 +25,28 @@ horizon.datatables.add_table_checkboxes = function(parent) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
horizon.datatables.set_table_filter = function (parent) {
|
||||||
|
$(parent).find('table').each(function (index, elm) {
|
||||||
|
var input = $($(elm).find('div.table_search input'));
|
||||||
|
if (input) {
|
||||||
|
input.quicksearch('table#' + $(elm).attr('id') + ' tbody tr', {
|
||||||
|
'delay': 300,
|
||||||
|
'loader': 'span.loading',
|
||||||
|
'bind': 'keyup click',
|
||||||
|
'show': this.show,
|
||||||
|
'hide': this.hide,
|
||||||
|
'prepareQuery': function (val) {
|
||||||
|
return new RegExp(val, "i");
|
||||||
|
},
|
||||||
|
'testQuery': function (query, txt, _row) {
|
||||||
|
return query.test($(_row).find('td:not(.hidden)').text());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
horizon.addInitFunction(function() {
|
horizon.addInitFunction(function() {
|
||||||
$('div.table_wrapper, div.modal_wrapper').on('click', 'table thead .multi_select_column :checkbox', function(evt) {
|
$('div.table_wrapper, div.modal_wrapper').on('click', 'table thead .multi_select_column :checkbox', function(evt) {
|
||||||
var $this = $(this),
|
var $this = $(this),
|
||||||
@ -33,31 +55,16 @@ horizon.addInitFunction(function() {
|
|||||||
checkboxes = $table.find('tbody :checkbox');
|
checkboxes = $table.find('tbody :checkbox');
|
||||||
checkboxes.prop('checked', is_checked);
|
checkboxes.prop('checked', is_checked);
|
||||||
});
|
});
|
||||||
$('.table_search input').quicksearch('tbody tr', {
|
|
||||||
'delay': 300,
|
|
||||||
'loader': 'span.loading',
|
|
||||||
'bind': 'keyup click',
|
|
||||||
'show': function () {
|
|
||||||
this.style.display = '';
|
|
||||||
},
|
|
||||||
'hide': function () {
|
|
||||||
this.style.display = 'none';
|
|
||||||
},
|
|
||||||
'prepareQuery': function (val) {
|
|
||||||
return new RegExp(val, "i");
|
|
||||||
},
|
|
||||||
'testQuery': function (query, txt, _row) {
|
|
||||||
return query.test($(_row).find('td:not(.hidden)').text());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
horizon.datatables.add_table_checkboxes($('body'));
|
horizon.datatables.add_table_checkboxes($('body'));
|
||||||
horizon.datatables.set_table_sorting($('body'));
|
horizon.datatables.set_table_sorting($('body'));
|
||||||
|
horizon.datatables.set_table_filter($('body'));
|
||||||
|
|
||||||
// Also apply on tables in modal views
|
// Also apply on tables in modal views
|
||||||
$('div.modal_wrapper').on('shown', '.modal', function(evt) {
|
$('div.modal_wrapper').on('shown', '.modal', function(evt) {
|
||||||
horizon.datatables.add_table_checkboxes(this);
|
horizon.datatables.add_table_checkboxes(this);
|
||||||
horizon.datatables.set_table_sorting(this);
|
horizon.datatables.set_table_sorting(this);
|
||||||
|
horizon.datatables.set_table_filter(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
horizon.datatables.update();
|
horizon.datatables.update();
|
||||||
|
@ -77,6 +77,29 @@ class SwiftApiTests(test.APITestCase):
|
|||||||
self.assertEqual(len(objs), len(objects))
|
self.assertEqual(len(objs), len(objects))
|
||||||
self.assertFalse(more)
|
self.assertFalse(more)
|
||||||
|
|
||||||
|
def test_swift_filter_objects(self):
|
||||||
|
container = self.containers.first()
|
||||||
|
objects = self.objects.list()
|
||||||
|
first_obj = self.objects.first()
|
||||||
|
expected_objs = [obj.name.encode('utf8') for obj in
|
||||||
|
self.objects.filter(name=first_obj.name)]
|
||||||
|
|
||||||
|
swift_api = self.stub_swiftclient()
|
||||||
|
swift_api.get_container(container.name).AndReturn(container)
|
||||||
|
self.mox.StubOutWithMock(container, 'get_objects')
|
||||||
|
container.get_objects(limit=10000,
|
||||||
|
marker=None,
|
||||||
|
prefix=None,
|
||||||
|
delimiter='/',
|
||||||
|
path=None).AndReturn(objects)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
result_objs = api.swift_filter_objects(self.request,
|
||||||
|
first_obj.name,
|
||||||
|
container.name)
|
||||||
|
self.assertQuerysetEqual(result_objs, expected_objs,
|
||||||
|
lambda obj: obj.name.encode('utf8'))
|
||||||
|
|
||||||
def test_swift_upload_object(self):
|
def test_swift_upload_object(self):
|
||||||
container = self.containers.first()
|
container = self.containers.first()
|
||||||
obj = self.objects.first()
|
obj = self.objects.first()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user