diff --git a/hub/kojihub.py b/hub/kojihub.py index 72a20853..1e483f61 100644 --- a/hub/kojihub.py +++ b/hub/kojihub.py @@ -9711,14 +9711,14 @@ class RootExports(object): not_arch[list]: limit to tasks without the given arches state[list]: limit to tasks of given state not_state[list]: limit to tasks not of the given state - owner[int]: limit to tasks owned by the user with the given ID - not_owner[int]: limit to tasks not owned by the user with the given ID - host_id[int]: limit to tasks running on the host with the given ID - not_host_id[int]: limit to tasks running on the hosts with IDs other than the given ID - channel_id[int]: limit to tasks in the specified channel - not_channel_id[int]: limit to tasks not in the specified channel - parent[int]: limit to tasks with the given parent - not_parent[int]: limit to tasks without the given parent + owner[int|list]: limit to tasks owned by the user with the given ID + not_owner[int|list]: limit to tasks not owned by the user with the given ID + host_id[int|list]: limit to tasks running on the host with the given ID + not_host_id[int|list]: limit to tasks running on the hosts with IDs other than the given ID + channel_id[int|list]: limit to tasks in the specified channel + not_channel_id[int|list]: limit to tasks not in the specified channel + parent[int|list]: limit to tasks with the given parent + not_parent[int|list]: limit to tasks without the given parent decode[bool]: whether or not xmlrpc data in the 'request' and 'result' fields should be decoded; defaults to False method[str]: limit to tasks of the given method @@ -9772,12 +9772,16 @@ class RootExports(object): if opts.has_key(f): if opts[f] is None: conditions.append('%s IS NULL' % f) + elif isinstance(opts[f], types.ListType): + conditions.append('%s IN %%(%s)s' % (f, f)) else: conditions.append('%s = %%(%s)i' % (f, f)) # Exclude int types if opts.has_key('not_' + f): if opts['not_' + f] is None: conditions.append('%s IS NOT NULL' % f) + elif isinstance(opts['not_' + f], types.ListType): + conditions.append('%s NOT IN %%(not_%s)s' % (f, f)) else: conditions.append('%s != %%(not_%s)i' % (f, f)) diff --git a/tests/test_hub/test_listing.py b/tests/test_hub/test_listing.py index b2198761..a39f2b05 100644 --- a/tests/test_hub/test_listing.py +++ b/tests/test_hub/test_listing.py @@ -24,7 +24,7 @@ class TestListing(unittest.TestCase): processor.assert_called_once_with(**self.standard_processor_kwargs) @mock.patch('kojihub.QueryProcessor') - def test_list_tasks_by_owner(self, processor): + def test_list_tasks_by_owner_as_int(self, processor): generator = self.hub.listTasks(opts={'owner': 1}) results = list(generator) # Exhaust the generator arguments = self.standard_processor_kwargs.copy() @@ -33,7 +33,7 @@ class TestListing(unittest.TestCase): self.assertEqual(results, []) @mock.patch('kojihub.QueryProcessor') - def test_list_tasks_by_not_owner(self, processor): + def test_list_tasks_by_not_owner_as_int(self, processor): generator = self.hub.listTasks(opts={'not_owner': 1}) results = list(generator) # Exhaust the generator arguments = self.standard_processor_kwargs.copy() @@ -58,3 +58,21 @@ class TestListing(unittest.TestCase): arguments['clauses'] = ['arch NOT IN %(not_arch)s'] processor.assert_called_once_with(**arguments) self.assertEqual(results, []) + + @mock.patch('kojihub.QueryProcessor') + def test_list_tasks_by_owner_as_list(self, processor): + generator = self.hub.listTasks(opts={'owner': [1, 2]}) + results = list(generator) # Exhaust the generator + arguments = self.standard_processor_kwargs.copy() + arguments['clauses'] = ['owner IN %(owner)s'] + processor.assert_called_once_with(**arguments) + self.assertEqual(results, []) + + @mock.patch('kojihub.QueryProcessor') + def test_list_tasks_by_not_owner_as_list(self, processor): + generator = self.hub.listTasks(opts={'not_owner': [1, 2]}) + results = list(generator) # Exhaust the generator + arguments = self.standard_processor_kwargs.copy() + arguments['clauses'] = ['owner NOT IN %(not_owner)s'] + processor.assert_called_once_with(**arguments) + self.assertEqual(results, []) diff --git a/www/conf/web.conf b/www/conf/web.conf index 1b167be4..f7dd34d2 100644 --- a/www/conf/web.conf +++ b/www/conf/web.conf @@ -29,7 +29,7 @@ LibPath = /usr/share/koji-web/lib # Defaults to True LiteralFooter = True -# This can be the numeric ID of a user that you want to hide from tasks listed -# on the front page. You might want to, for instance, hide the activity of an -# account used for continuous integration. -#HiddenUser = 5372 +# This can be a comma-delimited list of the numeric IDs of users that you want +# to hide from tasks listed on the front page. You might want to, for instance, +# hide the activity of an account used for continuous integration. +#HiddenUsers = 5372,1234 diff --git a/www/kojiweb/index.py b/www/kojiweb/index.py index 84d4a74b..1fdcc5b9 100644 --- a/www/kojiweb/index.py +++ b/www/kojiweb/index.py @@ -283,8 +283,8 @@ def index(environ, packageOrder='package_name', packageStart=None): taskOpts = {'parent': None, 'decode': True} if user: taskOpts['owner'] = user['id'] - if opts.get('HiddenUser'): - taskOpts['not_owner'] = opts['HiddenUser'] + if opts.get('HiddenUsers'): + taskOpts['not_owner'] = opts['HiddenUsers'] values['tasks'] = server.listTasks( opts=taskOpts, queryOpts={'order': '-id', 'limit': 10}