From 04c0845892f106fe348ce6cb3d48fac3517ff14c Mon Sep 17 00:00:00 2001
From: Patrick Uiterwijk <patrick@puiterwijk.org>
Date: Sep 28 2017 09:14:13 +0000
Subject: Add button to refresh external pull requests


Fixes: #2625

Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>

---

diff --git a/pagure/lib/tasks.py b/pagure/lib/tasks.py
index b95608a..7fadeca 100644
--- a/pagure/lib/tasks.py
+++ b/pagure/lib/tasks.py
@@ -30,6 +30,7 @@ from pagure import APP
 import pagure.lib
 import pagure.lib.git
 import pagure.lib.git_auth
+import pagure.lib.repo
 
 logging.config.dictConfig(APP.config.get('LOGGING') or {'version': 1})
 _log = logging.getLogger(__name__)
@@ -460,6 +461,34 @@ def pull_remote_repo(remote_git, branch_from):
 
 
 @conn.task
+def refresh_remote_pr(name, namespace, user, requestid):
+    session = pagure.lib.create_session()
+
+    project = pagure.lib._get_project(
+        session, namespace=namespace, name=name, user=user,
+        case=APP.config.get('CASE_SENSITIVE', False))
+
+    request = pagure.lib.search_pull_requests(
+        session, project_id=project.id, requestid=requestid)
+    _log.debug(
+        'refreshing remote pull-request: %s/#%s', request.project.fullname,
+        request.id)
+
+    clonepath = pagure.get_remote_repo_path(request.remote_git,
+                                            request.branch_from)
+
+    repo = pagure.lib.repo.PagureRepo(clonepath)
+    repo.pull(branch=request.branch_from, force=True)
+
+    refresh_pr_cache.delay(name, namespace, user)
+    session.remove()
+    del repo
+    gc_clean()
+    return ret('request_pull', username=user, namespace=namespace, repo=name,
+               requestid=requestid)
+
+
+@conn.task
 def refresh_pr_cache(name, namespace, user):
     session = pagure.lib.create_session()
 
diff --git a/pagure/templates/pull_request.html b/pagure/templates/pull_request.html
index 877915a..d915e0c 100644
--- a/pagure/templates/pull_request.html
+++ b/pagure/templates/pull_request.html
@@ -39,6 +39,19 @@
      <span class="pull-xs-right">
      {% if pull_request.status == 'Open' and authenticated and
         (g.repo_committer or g.fas_user.username == pull_request.user.username) %}
+          {% if mergeform and pull_request.remote %}
+            <form style="display:inline;" action="{{ url_for(
+              'refresh_request_pull', username=username,
+              namespace=repo.namespace,
+              repo=repo.name, requestid=requestid) }}" method="POST">
+                <button type="submit" value="Refresh" id="refresh_pr"
+                        class="btn btn-warning btn-sm" title="Refresh the remote pull request">
+                  <span class="oi" data-glyph="reload"></span>
+                </button>
+                {{ mergeform.csrf_token }}
+            </form>
+	  {% endif %}
+
         <form style="display:inline;" action="{{ url_for(
             'cancel_request_pull', username=username,
             namespace=repo.namespace,
diff --git a/pagure/ui/fork.py b/pagure/ui/fork.py
index e5a85f0..f889a36 100644
--- a/pagure/ui/fork.py
+++ b/pagure/ui/fork.py
@@ -808,6 +808,55 @@ def cancel_request_pull(repo, requestid, username=None, namespace=None):
         'view_repo', repo=repo, username=username, namespace=namespace))
 
 
+@APP.route('/<repo>/pull-request/refresh/<int:requestid>',
+           methods=['POST'])
+@APP.route('/<namespace>/<repo>/pull-request/refresh/<int:requestid>',
+           methods=['POST'])
+@APP.route('/fork/<username>/<repo>/pull-request/refresh/<int:requestid>',
+           methods=['POST'])
+@APP.route(
+    '/fork/<username>/<namespace>/<repo>/pull-request/refresh/<int:requestid>',
+    methods=['POST'])
+@login_required
+def refresh_request_pull(repo, requestid, username=None, namespace=None):
+    """ Refresh a remote pull request.
+    """
+
+    form = pagure.forms.ConfirmationForm()
+    if form.validate_on_submit():
+
+        if not flask.g.repo.settings.get('pull_requests', True):
+            flask.abort(404, 'No pull-requests found for this project')
+
+        request = pagure.lib.search_pull_requests(
+            SESSION, project_id=flask.g.repo.id, requestid=requestid)
+
+        if not request:
+            flask.abort(404, 'Pull-request not found')
+
+        if not flask.g.repo_committer \
+                and not flask.g.fas_user.username == request.user.username:
+            flask.abort(
+                403,
+                'You are not allowed to refresh this pull request')
+
+        taskid = pagure.lib.tasks.refresh_remote_pr.delay(
+            flask.g.repo.name, namespace, username, requestid)
+        return pagure.wait_for_task(
+            taskid,
+            prev=flask.url_for('request_pull',
+                               repo=flask.g.repo.name,
+                               namespace=namespace,
+                               username=username,
+                               requestid=requestid))
+    else:
+        flask.flash('Invalid input submitted', 'error')
+
+    return flask.redirect(flask.url_for(
+        'request_pull', username=username, namespace=namespace,
+        repo=flask.g.repo.name, requestid=requestid))
+
+
 @APP.route(
     '/<repo>/pull-request/<int:requestid>/assign', methods=['POST'])
 @APP.route(

