Allow hiding a user from the frontpage task list.
This adds new query arguments to the taskList hub xmlrpc endpoint, and then makes use of those arguments in koji-web. A new optional configuration value is added for koji-web: `HiddenUser`, which can be used to specify which user account should be hidden. This could be useful for deployments that have a continuous-integration account, the spam from which makes the frontpage difficult to read. Unit test cases are also added for some functions of the hub taskList endpoint. Signed-off-by: Ralph Bean <rbean@redhat.com>
This commit is contained in:
parent
1febe4f7fe
commit
708b6a411c
6 changed files with 99 additions and 4 deletions
2
Makefile
2
Makefile
|
|
@ -64,7 +64,7 @@ git-clean:
|
|||
@git clean -d -q -x
|
||||
|
||||
test:
|
||||
nosetests --with-coverage --cover-package .
|
||||
PYTHONPATH=hub/. nosetests --with-coverage --cover-package .
|
||||
|
||||
subdirs:
|
||||
for d in $(SUBDIRS); do make -C $$d; [ $$? = 0 ] || exit 1; done
|
||||
|
|
|
|||
|
|
@ -9708,11 +9708,17 @@ class RootExports(object):
|
|||
Options(dictionary):
|
||||
option[type]: meaning
|
||||
arch[list]: limit to tasks for given arches
|
||||
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
|
||||
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
|
||||
|
|
@ -9752,17 +9758,32 @@ class RootExports(object):
|
|||
aliases = [f[1] for f in flist]
|
||||
|
||||
conditions = []
|
||||
for f in ['arch','state']:
|
||||
|
||||
for f in ['arch', 'state']:
|
||||
# Include list types
|
||||
if opts.has_key(f):
|
||||
conditions.append('%s IN %%(%s)s' % (f, f))
|
||||
# Exclude list types
|
||||
if opts.has_key('not_' + f):
|
||||
conditions.append('%s NOT IN %%(not_%s)s' % (f, f))
|
||||
|
||||
for f in ['owner', 'host_id', 'channel_id', 'parent']:
|
||||
# Include int types
|
||||
if opts.has_key(f):
|
||||
if opts[f] is None:
|
||||
conditions.append('%s IS NULL' % 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)
|
||||
else:
|
||||
conditions.append('%s != %%(not_%s)i' % (f, f))
|
||||
|
||||
if opts.has_key('method'):
|
||||
conditions.append('method = %(method)s')
|
||||
|
||||
time_opts = [
|
||||
['createdBefore', 'create_time', '<'],
|
||||
['createdAfter', 'create_time', '>'],
|
||||
|
|
|
|||
0
tests/test_hub/__init__.py
Normal file
0
tests/test_hub/__init__.py
Normal file
60
tests/test_hub/test_listing.py
Normal file
60
tests/test_hub/test_listing.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import unittest
|
||||
import mock
|
||||
|
||||
import kojihub
|
||||
|
||||
|
||||
class TestListing(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.hub = kojihub.RootExports()
|
||||
self.standard_processor_kwargs = dict(
|
||||
tables=mock.ANY,
|
||||
columns=mock.ANY,
|
||||
values=mock.ANY,
|
||||
joins=mock.ANY,
|
||||
clauses=mock.ANY,
|
||||
opts=mock.ANY,
|
||||
aliases=mock.ANY,
|
||||
)
|
||||
|
||||
@mock.patch('kojihub.QueryProcessor')
|
||||
def test_list_tasks_basic_invocation(self, processor):
|
||||
generator = self.hub.listTasks()
|
||||
results = list(generator) # Exhaust the generator
|
||||
processor.assert_called_once_with(**self.standard_processor_kwargs)
|
||||
|
||||
@mock.patch('kojihub.QueryProcessor')
|
||||
def test_list_tasks_by_owner(self, processor):
|
||||
generator = self.hub.listTasks(opts={'owner': 1})
|
||||
results = list(generator) # Exhaust the generator
|
||||
arguments = self.standard_processor_kwargs.copy()
|
||||
arguments['clauses'] = ['owner = %(owner)i']
|
||||
processor.assert_called_once_with(**arguments)
|
||||
self.assertEqual(results, [])
|
||||
|
||||
@mock.patch('kojihub.QueryProcessor')
|
||||
def test_list_tasks_by_not_owner(self, processor):
|
||||
generator = self.hub.listTasks(opts={'not_owner': 1})
|
||||
results = list(generator) # Exhaust the generator
|
||||
arguments = self.standard_processor_kwargs.copy()
|
||||
arguments['clauses'] = ['owner != %(not_owner)i']
|
||||
processor.assert_called_once_with(**arguments)
|
||||
self.assertEqual(results, [])
|
||||
|
||||
@mock.patch('kojihub.QueryProcessor')
|
||||
def test_list_tasks_by_arch(self, processor):
|
||||
generator = self.hub.listTasks(opts={'arch': ['x86_64']})
|
||||
results = list(generator) # Exhaust the generator
|
||||
arguments = self.standard_processor_kwargs.copy()
|
||||
arguments['clauses'] = ['arch IN %(arch)s']
|
||||
processor.assert_called_once_with(**arguments)
|
||||
self.assertEqual(results, [])
|
||||
|
||||
@mock.patch('kojihub.QueryProcessor')
|
||||
def test_list_tasks_by_not_arch(self, processor):
|
||||
generator = self.hub.listTasks(opts={'not_arch': ['x86_64']})
|
||||
results = list(generator) # Exhaust the generator
|
||||
arguments = self.standard_processor_kwargs.copy()
|
||||
arguments['clauses'] = ['arch NOT IN %(not_arch)s']
|
||||
processor.assert_called_once_with(**arguments)
|
||||
self.assertEqual(results, [])
|
||||
|
|
@ -28,3 +28,8 @@ LibPath = /usr/share/koji-web/lib
|
|||
# If False, then the footer will be included as another Kid Template.
|
||||
# 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
|
||||
|
|
|
|||
|
|
@ -272,14 +272,23 @@ def index(environ, packageOrder='package_name', packageStart=None):
|
|||
values = _initValues(environ)
|
||||
server = _getServer(environ)
|
||||
|
||||
opts = environ['koji.options']
|
||||
user = environ['koji.currentUser']
|
||||
|
||||
values['builds'] = server.listBuilds(userID=(user and user['id'] or None), queryOpts={'order': '-build_id', 'limit': 10})
|
||||
values['builds'] = server.listBuilds(
|
||||
userID=(user and user['id'] or None),
|
||||
queryOpts={'order': '-build_id', 'limit': 10}
|
||||
)
|
||||
|
||||
taskOpts = {'parent': None, 'decode': True}
|
||||
if user:
|
||||
taskOpts['owner'] = user['id']
|
||||
values['tasks'] = server.listTasks(opts=taskOpts, queryOpts={'order': '-id', 'limit': 10})
|
||||
if opts.get('HiddenUser'):
|
||||
taskOpts['not_owner'] = opts['HiddenUser']
|
||||
values['tasks'] = server.listTasks(
|
||||
opts=taskOpts,
|
||||
queryOpts={'order': '-id', 'limit': 10}
|
||||
)
|
||||
|
||||
values['order'] = '-id'
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue