From f7bee306cece88b15f1f894d4e6d7327afdb90a2 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Sep 12 2016 11:01:57 +0000 Subject: [PATCH 1/11] Add the possibility to segment the issues and PRs retrieved from the DB This is required to paginating the results --- diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py index 6a631eb..87c2fd5 100644 --- a/pagure/lib/__init__.py +++ b/pagure/lib/__init__.py @@ -1643,7 +1643,7 @@ def get_project(session, name, user=None, namespace=None): def search_issues( session, repo, issueid=None, issueuid=None, status=None, closed=False, tags=None, assignee=None, author=None, private=None, - priority=None, count=False): + priority=None, count=False, offset=None, limit=None): ''' Retrieve one or more issues associated to a project with the given criterias. @@ -1832,6 +1832,10 @@ def search_issues( elif count: output = query.count() else: + if offset: + query = query.offset(offset) + if limit: + query = query.limit(limit) output = query.all() return output @@ -1874,7 +1878,8 @@ def get_tag(session, tag): def search_pull_requests( session, requestid=None, project_id=None, project_id_from=None, - status=None, author=None, assignee=None, count=False): + status=None, author=None, assignee=None, count=False, + offset=None, limit=None): ''' Retrieve the specified issue ''' @@ -1956,6 +1961,10 @@ def search_pull_requests( elif count: output = query.count() else: + if offset: + query = query.offset(offset) + if limit: + query = query.limit(limit) output = query.all() return output From cf77bc3a92ff5f0404a07028fa636940fa1c34bb Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Sep 12 2016 11:01:57 +0000 Subject: [PATCH 2/11] Retrieve and set offset, page and limit from the URLs if any are provided --- diff --git a/pagure/__init__.py b/pagure/__init__.py index c0af24a..1e91bbc 100644 --- a/pagure/__init__.py +++ b/pagure/__init__.py @@ -407,6 +407,32 @@ def set_variables(): flask.g.repo_admin = is_repo_admin(flask.g.repo) flask.g.branches = sorted(flask.g.repo_obj.listall_branches()) + flask.g.offset = 0 + flask.g.page = 1 + flask.g.limit = 10 + page = flask.request.args.get('page') + limit = flask.request.args.get('n') + if limit: + try: + limit = int(limit) + except ValueError: + limit = 10 + if limit > 500 or limit <= 0: + limit = 10 + + flask.g.limit = limit + + if page: + try: + page = abs(int(page)) + except ValueError: + page = 1 + if page <= 0: + page = 1 + + flask.g.page = page + flask.g.offset = (page - 1) * flask.g.limit + @APP.errorhandler(404) def not_found(error): From 325b837ca1807ff5b1fe0339bcf15deee6c65f45 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Sep 12 2016 11:01:57 +0000 Subject: [PATCH 3/11] Rework the view_issues endpoint to support pagination --- diff --git a/pagure/ui/issues.py b/pagure/ui/issues.py index b6edb11..579fac9 100644 --- a/pagure/ui/issues.py +++ b/pagure/ui/issues.py @@ -18,6 +18,7 @@ import flask import os from collections import defaultdict +from math import ceil import pygit2 from sqlalchemy.exc import SQLAlchemyError @@ -431,51 +432,59 @@ def view_issues(repo, username=None, namespace=None): oth_issues = None if status is not None: - if status.lower() == 'closed': - issues = pagure.lib.search_issues( - SESSION, - repo, - closed=True, - tags=tags, - assignee=assignee, - author=author, - private=private, - priority=priority, - ) - oth_issues = pagure.lib.search_issues( - SESSION, - repo, - status='Open', - tags=tags, - assignee=assignee, - author=author, - private=private, - priority=priority, - count=True, - ) - else: - issues = pagure.lib.search_issues( - SESSION, - repo, - status=status, - tags=tags, - assignee=assignee, - author=author, - private=private, - priority=priority, - ) - + issues = pagure.lib.search_issues( + SESSION, + repo, + closed=True if status.lower() == 'closed' else False, + status='Open' if status.lower() == 'open' else None, + tags=tags, + assignee=assignee, + author=author, + private=private, + priority=priority, + offset=flask.g.offset, + limit=flask.g.limit, + ) + issues_cnt = pagure.lib.search_issues( + SESSION, + repo, + closed=True if status.lower() == 'closed' else False, + status='Open' if status.lower() == 'open' else None, + tags=tags, + assignee=assignee, + author=author, + private=private, + priority=priority, + count=True + ) + oth_issues = pagure.lib.search_issues( + SESSION, + repo, + closed=False if status.lower() == 'closed' else True, + tags=tags, + assignee=assignee, + author=author, + private=private, + priority=priority, + count=True, + ) else: issues = pagure.lib.search_issues( SESSION, repo, tags=tags, assignee=assignee, - author=author, private=private, priority=priority) - oth_issues = [] + author=author, private=private, priority=priority, + offset=flask.g.offset, limit=flask.g.limit, + ) + issues_cnt = pagure.lib.search_issues( + SESSION, repo, tags=tags, assignee=assignee, + author=author, private=private, priority=priority, count=True) tag_list = pagure.lib.get_tags_of_project(SESSION, repo) reponame = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(reponame) + total_page = int(ceil(issues_cnt / float(flask.g.limit))) + return flask.render_template( 'issues.html', select='issues', @@ -484,11 +493,13 @@ def view_issues(repo, username=None, namespace=None): tag_list=tag_list, status=status, issues=issues, + issues_cnt=issues_cnt, oth_issues=oth_issues, tags=tags, assignee=assignee, author=author, priority=priority, + total_page=total_page, ) From 3f299a4db6cceb3a8e197b914764316423d23d8b Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Sep 12 2016 11:01:57 +0000 Subject: [PATCH 4/11] Rework the request_pulls endpoint to support pagination --- diff --git a/pagure/ui/fork.py b/pagure/ui/fork.py index bfcd8b7..0d6f07b 100644 --- a/pagure/ui/fork.py +++ b/pagure/ui/fork.py @@ -19,6 +19,7 @@ import flask import os +from math import ceil import pygit2 from sqlalchemy.exc import SQLAlchemyError @@ -159,7 +160,16 @@ def request_pulls(repo, username=None, namespace=None): project_id=repo.id, status=True, assignee=assignee, - author=author) + author=author, + offset=flask.g.offset, + limit=flask.g.limit) + requests_cnt = pagure.lib.search_pull_requests( + SESSION, + project_id=repo.id, + status=True, + assignee=assignee, + author=author, + count=True) oth_requests = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, @@ -173,7 +183,16 @@ def request_pulls(repo, username=None, namespace=None): project_id=repo.id, assignee=assignee, author=author, - status=status) + status=status, + offset=flask.g.offset, + limit=flask.g.limit) + requests_cnt = pagure.lib.search_pull_requests( + SESSION, + project_id=repo.id, + assignee=assignee, + author=author, + status=status, + count=True) oth_requests = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, @@ -189,18 +208,22 @@ def request_pulls(repo, username=None, namespace=None): else: head = 'master' + total_page = int(ceil(requests_cnt / float(flask.g.limit))) + return flask.render_template( 'requests.html', select='requests', repo=repo, username=username, requests=requests, + requests_cnt=requests_cnt, oth_requests=oth_requests, status=status, assignee=assignee, author=author, form=pagure.forms.ConfirmationForm(), head=head, + total_page=total_page, ) From a5aa6b76197e047279998f1434b12d4a7a72d195 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Sep 12 2016 11:01:57 +0000 Subject: [PATCH 5/11] Adjust the pagination_link macro to be more flexible This way the url generated for next/previous pages will keep the arguments they have and will just adjust the page one --- diff --git a/pagure/templates/_render_repo.html b/pagure/templates/_render_repo.html index cb01766..0fd735d 100644 --- a/pagure/templates/_render_repo.html +++ b/pagure/templates/_render_repo.html @@ -42,13 +42,11 @@ {%- endmacro %} -{% macro pagination_link(pagetitle, page, total, sorting=None) -%} -{% set prev_page = "%s?%s=%s" % (request.base_url, pagetitle, page - 1) %} -{% set next_page = "%s?%s=%s" % (request.base_url, pagetitle, page + 1) %} -{% if sorting %} -{% set prev_page = "%s&sorting=%s" % (prev_page, sorting) %} -{% set next_page = "%s&sorting=%s" % (next_page, sorting) %} -{% endif %} +{% macro pagination_link(pagetitle, page, total) -%} +{% set prev_page = request.url | combine_url( + page=page-1, pagetitle=pagetitle, **kwargs) %} +{% set next_page = request.url | combine_url( + page=page+1, pagetitle=pagetitle, **kwargs) %}