add do_submit task management stuff
This commit is contained in:
parent
1d56f10ec1
commit
cd99ba1c0a
6 changed files with 131 additions and 58 deletions
|
@ -5,7 +5,7 @@ from django.conf import settings
|
|||
from django.urls.base import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from c3nav.editor.tasks import check_access_token, request_access_token
|
||||
from c3nav.editor.tasks import check_access_token, request_access_token, submit_edit
|
||||
from c3nav.mapdata.models import Package
|
||||
|
||||
|
||||
|
@ -114,6 +114,11 @@ class Hoster(ABC):
|
|||
session_data['checking_progress_id'] = task.id
|
||||
self._handle_checking_task(request, task, session_data)
|
||||
|
||||
def submit_edit(self, request, data):
|
||||
session_data = self._get_session_data(request)
|
||||
task = submit_edit.apply_async(access_token=session_data['access_token'], data=data)
|
||||
return task
|
||||
|
||||
@abstractmethod
|
||||
def get_auth_uri(self, request):
|
||||
"""
|
||||
|
@ -133,7 +138,7 @@ class Hoster(ABC):
|
|||
"""
|
||||
Task method for requesting the access token asynchroniously.
|
||||
Returns a dict with a 'state' key containing the new hoster state, an optional 'error' key containing an
|
||||
error message and an optional 'access_token' keys containing a new access token.
|
||||
error message and an optional 'access_token' key containing a new access token.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
@ -144,3 +149,13 @@ class Hoster(ABC):
|
|||
Returns a dict with a 'state' key containing the new hoster state.
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def do_submit_edit(self, access_token, data):
|
||||
"""
|
||||
Task method for submitting an edit (e.g. creating a pull request).
|
||||
|
||||
Returns a dict with a 'success' key that contains a boolean, an optional 'error' key containing an error
|
||||
message and an optional 'url' key containing an URL to the created pull request.
|
||||
"""
|
||||
pass
|
||||
|
|
|
@ -80,3 +80,6 @@ class GithubHoster(Hoster):
|
|||
return {'state': 'missing_permissions'}
|
||||
|
||||
return {'state': 'logged_in'}
|
||||
|
||||
def do_submit_edit(self, access_token, data):
|
||||
raise NotImplementedError
|
||||
|
|
|
@ -75,3 +75,6 @@ class GitlabHoster(Hoster):
|
|||
return {'state': 'logged_out'}
|
||||
|
||||
return {'state': 'logged_in'}
|
||||
|
||||
def do_submit_edit(self, access_token, data):
|
||||
raise NotImplementedError
|
||||
|
|
|
@ -11,3 +11,9 @@ def request_access_token(hoster, *args, **kwargs):
|
|||
def check_access_token(hoster, access_token):
|
||||
from c3nav.editor.hosters import hosters
|
||||
return hosters[hoster].do_check_access_token(access_token)
|
||||
|
||||
|
||||
@app.task()
|
||||
def submit_edit(hoster, access_token, data):
|
||||
from c3nav.editor.hosters import hosters
|
||||
return hosters[hoster].do_submit_edit(access_token, data)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
{% load bootstrap3 %}
|
||||
{% block content %}
|
||||
{% if hoster %}
|
||||
{% if not task %}
|
||||
|
||||
{% if hoster_error %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<p>{{ hoster_error }}</p>
|
||||
|
@ -14,6 +16,8 @@
|
|||
<form action="{% url 'editor.finalize' %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="data" value="{{ data }}">
|
||||
<input type="hidden" name="action" value="submit">
|
||||
<input type="hidden" name="editor_submit_token" value="{{ editor_submit_token }}">
|
||||
{% bootstrap_form commit_form %}
|
||||
|
||||
{% buttons %}
|
||||
|
@ -42,7 +46,7 @@
|
|||
<h2>Sign in with {{ hoster.title }}</h2>
|
||||
<p>Please sign in to continue and propose your edit.</p>
|
||||
{% endif %}
|
||||
<form action="{% url 'editor.finalize' %}" method="POST" data-task="{{ task }}">
|
||||
<form action="{% url 'editor.finalize' %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="data" value="{{ data }}">
|
||||
<input type="hidden" name="action" value="oauth">
|
||||
|
@ -55,6 +59,22 @@
|
|||
</form>
|
||||
{% endif %}
|
||||
<p>Alternatively, you can copy your edit below and send it to the maps maintainer.</p>
|
||||
{% else %}
|
||||
{% if not task.ready or redirect %}
|
||||
<h2>Creating Pull Request…</h2>
|
||||
<form action="{% url 'editor.finalize' %}" method="POST"{% if redirect %} name="redirect"{% else %} data-check-task="{{ task.id }}"{% endif %}>
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="data" value="{{ data }}">
|
||||
<input type="hidden" name="action" value="result">
|
||||
<input type="hidden" name="task" value="{{ task.id }}">
|
||||
<p><img src="{% static 'img/loader.gif' %}"></p>
|
||||
<p><em>Creating Pull Request…</em></p>
|
||||
</form>
|
||||
{% else %}
|
||||
<h2>Pull Request created</h2>
|
||||
<p>You can find it here:</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<h2>Copy your edit</h2>
|
||||
<p>In order to propose your edit, please copy it and send it to the maps maintainer.</p>
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
import string
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import signing
|
||||
from django.core.exceptions import PermissionDenied, SuspiciousOperation
|
||||
from django.http.response import Http404
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.views.decorators.http import require_POST
|
||||
|
||||
from c3nav.editor.forms import CommitForm, FeatureForm
|
||||
from c3nav.editor.hosters import get_hoster_for_package, hosters
|
||||
from c3nav.editor.tasks import submit_edit
|
||||
from c3nav.mapdata.models.feature import FEATURE_TYPES, Feature
|
||||
from c3nav.mapdata.models.package import Package
|
||||
from c3nav.mapdata.packageio.write import json_encode
|
||||
|
@ -112,22 +116,41 @@ def finalize(request):
|
|||
hoster = get_hoster_for_package(package)
|
||||
|
||||
action = request.POST.get('action')
|
||||
|
||||
if 'commit_msg' in request.POST or action == 'submit':
|
||||
form = CommitForm(request.POST)
|
||||
else:
|
||||
form = CommitForm({'commit_msg': data['commit_msg']})
|
||||
|
||||
task = None
|
||||
new_submit_token = False
|
||||
if action == 'check':
|
||||
hoster.check_state(request)
|
||||
elif action == 'oauth':
|
||||
hoster.set_tmp_data(request, raw_data)
|
||||
return redirect(hoster.get_auth_uri(request))
|
||||
elif action == 'submit' and hoster.get_state(request) == 'logged_in':
|
||||
if request.POST.get('editor_submit_token', '') != request.session.get('editor_submit_token', None):
|
||||
raise SuspiciousOperation('Invalid submit token.')
|
||||
if form.is_valid():
|
||||
new_submit_token = True
|
||||
data['commit_msg'] = form.cleaned_data['commit_msg']
|
||||
task = hoster.submit_edit(request, data)
|
||||
elif action == 'result':
|
||||
if 'task' not in request.POST:
|
||||
raise SuspiciousOperation('Missing task id.')
|
||||
task = submit_edit.AsyncResult(task_id=request.POST['task'])
|
||||
try:
|
||||
task.ready()
|
||||
except:
|
||||
raise Http404()
|
||||
|
||||
if 'editor_submit_token' not in request.session or new_submit_token:
|
||||
request.session['editor_submit_token'] = get_random_string(42, string.ascii_letters + string.digits)
|
||||
|
||||
hoster_state = hoster.get_state(request)
|
||||
hoster_error = hoster.get_error(request) if hoster_state == 'logged_out' else None
|
||||
|
||||
if request.method == 'POST' and 'commit_msg' in request.POST:
|
||||
form = CommitForm(request.POST)
|
||||
if form.is_valid() and hoster_state == 'logged_in':
|
||||
pass
|
||||
else:
|
||||
form = CommitForm({'commit_msg': data['commit_msg']})
|
||||
|
||||
return render(request, 'editor/finalize.html', {
|
||||
'data': raw_data,
|
||||
'action': data['action'],
|
||||
|
@ -137,6 +160,9 @@ def finalize(request):
|
|||
'hoster': hoster,
|
||||
'hoster_state': hoster_state,
|
||||
'hoster_error': hoster_error,
|
||||
'redirect': action == 'submit' and not settings.CELERY_ALWAYS_EAGER,
|
||||
'editor_submit_token': request.session['editor_submit_token'],
|
||||
'task': {'id': task.id, 'ready': task.ready(), 'result': task.result} if task is not None else None,
|
||||
'file_path': data['file_path'],
|
||||
'file_contents': data.get('content')
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue