From b729b012b1d7928212872bef2620e34217a363ca Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jun 18 2015 11:04:26 +0000 Subject: Add a new endpoint streaming information about a given issue This endpoint streams all information about a given issue put in the redis queue and sends it to the browser. The browser can then listen to this stream and adjust the UI on the fly --- diff --git a/pagure/ui/issues.py b/pagure/ui/issues.py index bd80924..cf8ee0e 100644 --- a/pagure/ui/issues.py +++ b/pagure/ui/issues.py @@ -21,8 +21,8 @@ import mimetypes import pagure.doc_utils import pagure.lib import pagure.forms -from pagure import (APP, SESSION, LOG, __get_file_in_tree, cla_required, - is_repo_admin, authenticated) +from pagure import (APP, SESSION, REDIS, LOG, __get_file_in_tree, + cla_required, is_repo_admin, authenticated) # pylint: disable=E1101 @@ -497,6 +497,42 @@ def view_issue(repo, issueid, username=None): ) +@APP.route('//issue//stream') +@APP.route('/fork///issue//stream') +def stream_issue(repo, issueid, username=None): + """ Streams the changes made to an issue live + """ + + repo = pagure.lib.get_project(SESSION, repo, user=username) + + if repo is None: + flask.abort(404, 'Project not found') + + if not repo.settings.get('issue_tracker', True): + flask.abort(404, 'No issue tracker found for this project') + + issue = pagure.lib.search_issues(SESSION, repo, issueid=issueid) + + if issue is None or issue.project != repo: + flask.abort(404, 'Issue not found') + + if issue.private and not is_repo_admin(repo) \ + and (not authenticated() or + not issue.user.user == flask.g.fas_user.username): + flask.abort( + 403, 'This issue is private and you are not allowed to view it') + + pubsub = REDIS.pubsub() + pubsub.subscribe(issue.uid) + def event_stream(pubsub): + for message in pubsub.listen(): + yield 'data: %s\n\n' % message['data'] + + return flask.Response( + event_stream(pubsub), + mimetype="text/event-stream") + + @APP.route('//issue//drop', methods=['POST']) @APP.route('/fork///issue//drop', methods=['POST'])