Swift Object filter improve and fix

bug#1013409
bug#1013412

Change-Id: Ib2efa534622793bfa9f190d74e3b91cc66e7516a
This commit is contained in:
Ke WU 2012-06-13 18:41:28 -07:00 committed by Ke Wu
parent f6f2a91e14
commit 359a71e0b0
4 changed files with 91 additions and 26 deletions

View File

@ -102,6 +102,42 @@ def swift_get_objects(request, container_name, prefix=None, path=None,
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,
new_container_name, new_object_name):
try:

View File

@ -138,15 +138,14 @@ class DownloadObject(tables.LinkAction):
class ObjectFilterAction(tables.FilterAction):
def filter(self, table, objects, filter_string):
""" Really naive case-insensitive search. """
q = filter_string.lower()
def comp(object):
if q in object.name.lower():
return True
return False
return filter(comp, objects)
request = table._meta.request
container = self.table.kwargs['container_name']
subfolder = self.table.kwargs['subfolder_path']
path = subfolder + '/' if subfolder else ''
return api.swift_filter_objects(request,
filter_string,
container,
path=path)
def sanitize_name(name):

View File

@ -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() {
$('div.table_wrapper, div.modal_wrapper').on('click', 'table thead .multi_select_column :checkbox', function(evt) {
var $this = $(this),
@ -33,31 +55,16 @@ horizon.addInitFunction(function() {
checkboxes = $table.find('tbody :checkbox');
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.set_table_sorting($('body'));
horizon.datatables.set_table_filter($('body'));
// Also apply on tables in modal views
$('div.modal_wrapper').on('shown', '.modal', function(evt) {
horizon.datatables.add_table_checkboxes(this);
horizon.datatables.set_table_sorting(this);
horizon.datatables.set_table_filter(this);
});
horizon.datatables.update();

View File

@ -77,6 +77,29 @@ class SwiftApiTests(test.APITestCase):
self.assertEqual(len(objs), len(objects))
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):
container = self.containers.first()
obj = self.objects.first()