From 87d989f918b8894717365c5bc26c7c55e58d5b7a Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Jan 17 2017 20:35:00 +0000 Subject: Merge PR#223 convert the packages page to use paginateMethod() Merges #223 https://pagure.io/koji/pull-request/223 --- diff --git a/hub/kojihub.py b/hub/kojihub.py index 521442d..ea52947 100644 --- a/hub/kojihub.py +++ b/hub/kojihub.py @@ -9811,7 +9811,7 @@ class RootExports(object): getPackage = staticmethod(lookup_package) - def listPackages(self, tagID=None, userID=None, pkgID=None, prefix=None, inherited=False, with_dups=False, event=None): + def listPackages(self, tagID=None, userID=None, pkgID=None, prefix=None, inherited=False, with_dups=False, event=None, queryOpts=None): """List if tagID and/or userID is specified, limit the list to packages belonging to the given user or with the given tag. @@ -9833,8 +9833,7 @@ class RootExports(object): - blocked """ if tagID is None and userID is None and pkgID is None: - query = """SELECT id, name from package""" - results = _multiRow(query, {}, ('package_id', 'package_name')) + return self.listPackagesSimple(prefix, queryOpts) else: if tagID is not None: tagID = get_tag_id(tagID, strict=True) @@ -9858,9 +9857,36 @@ class RootExports(object): prefix = prefix.lower() results = [package for package in results if package['package_name'].lower().startswith(prefix)] - return results + return _applyQueryOpts(results, queryOpts) + - def checkTagPackage(self, tag, pkg): + def listPackagesSimple(self, prefix=None, queryOpts=None): + """list packages that starts with prefix and are filted + and ordered by queryOpts. + + Args: + prefix: default is None. If is not None will filter out + packages which name doesn't start with the prefix. + queryOpts: query options used by the QueryProcessor. + + Returns: + A list of maps is returned, and each map contains key + 'package_name' and 'package_id'. + """ + fields = (('package.id', 'package_id'), + ('package.name', 'package_name')) + if prefix is None: + clauses = None + else: + clauses = ["""package.name ILIKE %(prefix)s || '%%'"""] + query = QueryProcessor( + tables=['package'], clauses=clauses, values=locals(), + columns=[f[0] for f in fields], aliases=[f[1] for f in fields], + opts=queryOpts) + return query.execute() + + + def checkTagPackage(self,tag,pkg): """Check that pkg is in the list for tag. Returns true/false""" tag_id = get_tag_id(tag, strict=False) pkg_id = get_package_id(pkg, strict=False) @@ -10535,12 +10561,41 @@ class RootExports(object): NULL higher than all other values; default to True for consistency with database sorts """ + return self.countAndFilterResults(methodName, *args, **kw)[1] + + + def countAndFilterResults(self, methodName, *args, **kw): + """Filter results by a given name and count total results account. + + Execute the XML-RPC method with the given name and filter the results + based on the options specified in the keywork option "filterOpts". + The method must return a list of maps. Any other return type will + result in a TypeError. + + Args: + offset: the number of elements to trim off the front of the list + limit: the maximum number of results to return + order: the map key to use to sort the list; the list will be sorted + before offset or limit are applied + noneGreatest: when sorting, consider 'None' to be greater than all + other values; python considers None less than all other values, + but Postgres sorts NULL higher than all other values; default + to True for consistency with database sorts + + Returns: + Tuple of total results amount and the filtered results. + """ filterOpts = kw.pop('filterOpts', {}) results = getattr(self, methodName)(*args, **kw) if results is None: - return None - elif not isinstance(results, list): + return 0, None + elif isinstance(results, list): + _count = len(results) + else: + _count = 1 + + if not isinstance(results, list): raise TypeError, '%s() did not return a list' % methodName order = filterOpts.get('order') @@ -10554,7 +10609,8 @@ class RootExports(object): if limit is not None: results = results[:limit] - return results + return _count, results + def getBuildNotifications(self, userID=None): """Get build notifications for the user with the given ID. If no ID diff --git a/www/kojiweb/index.py b/www/kojiweb/index.py index 7bcd82a..c529abf 100644 --- a/www/kojiweb/index.py +++ b/www/kojiweb/index.py @@ -352,8 +352,7 @@ def notificationedit(environ, notificationID): values = _initValues(environ, 'Edit Notification') values['notif'] = notification - packages = server.listPackages() - packages.sort(kojiweb.util.sortByKeyFunc('package_name')) + packages = server.listPackagesSimple(queryOpts={'order': 'package_name'}) values['packages'] = packages tags = server.listTags(queryOpts={'order': 'name'}) values['tags'] = tags @@ -397,8 +396,7 @@ def notificationcreate(environ): values = _initValues(environ, 'Edit Notification') values['notif'] = None - packages = server.listPackages() - packages.sort(kojiweb.util.sortByKeyFunc('package_name')) + packages = server.listPackagesSimple(queryOpts={'order': 'package_name'}) values['packages'] = packages tags = server.listTags(queryOpts={'order': 'name'}) values['tags'] = tags @@ -835,9 +833,9 @@ def packages(environ, tagID=None, userID=None, order='package_name', start=None, inherited = int(inherited) values['inherited'] = inherited - kojiweb.util.paginateResults(server, values, 'listPackages', - kw={'tagID': tagID, 'userID': userID, 'prefix': prefix, 'inherited': bool(inherited)}, - start=start, dataName='packages', prefix='package', order=order) + kojiweb.util.paginateMethod(server, values, 'listPackages', + kw={'tagID': tagID, 'userID': userID, 'prefix': prefix, 'inherited': bool(inherited)}, + start=start, dataName='packages', prefix='package', order=order) values['chars'] = _PREFIX_CHARS diff --git a/www/lib/kojiweb/util.py b/www/lib/kojiweb/util.py index 82e572f..03d0272 100644 --- a/www/lib/kojiweb/util.py +++ b/www/lib/kojiweb/util.py @@ -331,12 +331,11 @@ def paginateResults(server, values, methodName, args=None, kw=None, if not dataName: raise StandardError, 'dataName must be specified' - totalRows = server.count(methodName, *args, **kw) - kw['filterOpts'] = {'order': order, 'offset': start, 'limit': pageSize} - data = server.filterResults(methodName, *args, **kw) + + totalRows, data = server.countAndFilterResults(methodName, *args, **kw) count = len(data) _populateValues(values, dataName, prefix, data, totalRows, start, count, pageSize, order)