diff --git a/src/c3nav/editor/hosters/github.py b/src/c3nav/editor/hosters/github.py index 544af48e..e66b7195 100644 --- a/src/c3nav/editor/hosters/github.py +++ b/src/c3nav/editor/hosters/github.py @@ -2,6 +2,8 @@ from .base import Hoster class GithubHoster(Hoster): + title = 'GitHub' + def __init__(self, app_id, app_secret, **kwargs): super().__init__(**kwargs) self._app_id = app_id diff --git a/src/c3nav/editor/hosters/gitlab.py b/src/c3nav/editor/hosters/gitlab.py index 31b7304d..61252987 100644 --- a/src/c3nav/editor/hosters/gitlab.py +++ b/src/c3nav/editor/hosters/gitlab.py @@ -2,6 +2,8 @@ from .base import Hoster class GitlabHoster(Hoster): + title = 'Gitlab' + def __init__(self, app_id, app_secret, **kwargs): super().__init__(**kwargs) self._app_id = app_id diff --git a/src/c3nav/editor/static/editor/css/editor.css b/src/c3nav/editor/static/editor/css/editor.css index b3942069..d33af6d2 100644 --- a/src/c3nav/editor/static/editor/css/editor.css +++ b/src/c3nav/editor/static/editor/css/editor.css @@ -1,3 +1,9 @@ +body { + font-size:16px; +} +.btn-lg { + font-size:18px; +} #map { position:absolute; top:54px; diff --git a/src/c3nav/editor/static/editor/js/editor.js b/src/c3nav/editor/static/editor/js/editor.js index 4a9cd716..ee5cd6e4 100644 --- a/src/c3nav/editor/static/editor/js/editor.js +++ b/src/c3nav/editor/static/editor/js/editor.js @@ -359,6 +359,7 @@ editor = { }); }, submit_editing: function(e) { + if ($(this).attr('name') == 'redirect') return; e.preventDefault(); var data = $(this).serialize(); var btn = $(this).data('btn'); @@ -374,6 +375,7 @@ editor = { if ($('
').append(content).find('form').length > 0) { $('#mapeditdetail').html(content); $('#mapeditcontrols').addClass('detail'); + $('#mapeditdetail').find('form[name=redirect]').submit(); if ($('#id_geometry').length) { editor._editing.enableEdit(); } diff --git a/src/c3nav/editor/templates/editor/base.html b/src/c3nav/editor/templates/editor/base.html index 3c4b4555..d9f7b02b 100644 --- a/src/c3nav/editor/templates/editor/base.html +++ b/src/c3nav/editor/templates/editor/base.html @@ -19,25 +19,8 @@ diff --git a/src/c3nav/editor/templates/editor/error.html b/src/c3nav/editor/templates/editor/error.html new file mode 100644 index 00000000..a8d52cdd --- /dev/null +++ b/src/c3nav/editor/templates/editor/error.html @@ -0,0 +1,7 @@ +{% extends 'editor/base.html' %} +{% block content %} + +{% endblock %} diff --git a/src/c3nav/editor/templates/editor/feature_success.html b/src/c3nav/editor/templates/editor/feature_success.html index e69de29b..96135ddb 100644 --- a/src/c3nav/editor/templates/editor/feature_success.html +++ b/src/c3nav/editor/templates/editor/feature_success.html @@ -0,0 +1,7 @@ +{% if data %} +
+ {% csrf_token %} + + +
+{% endif %} diff --git a/src/c3nav/editor/templates/editor/finalize.html b/src/c3nav/editor/templates/editor/finalize.html new file mode 100644 index 00000000..1a46ceec --- /dev/null +++ b/src/c3nav/editor/templates/editor/finalize.html @@ -0,0 +1,27 @@ +{% extends 'editor/base.html' %} +{% block content %} + {% if hoster %} +

Sign in with {{ hoster.title }}

+

Please sign in to continue and propose your edit.

+

+ Sign in with {{ hoster.title }}
+ + {{ hoster.name }} – {{ hoster.base_url }} + +

+

+

Alternatively, you can copy your edit below and send it to the maps maintainer.

+ {% else %} +

Copy your edit

+

In order to propose your edit, please copy it and send it to the maps maintainer.

+

You are seeing this message because there is no hoster defined for this map package.

+ {% endif %} +

Your Edit

+

Map Package: {{ package_name }}

+ {% if file_contents %} +

New content for file: {{ file_path }}

+
{{ file_contents }}
+ {% else %} +

Delete file: {{ file_path }}

+ {% endif %} +{% endblock %} diff --git a/src/c3nav/editor/urls.py b/src/c3nav/editor/urls.py index 7b80e5df..7ac56b7e 100644 --- a/src/c3nav/editor/urls.py +++ b/src/c3nav/editor/urls.py @@ -1,10 +1,11 @@ from django.conf.urls import url from django.views.generic import TemplateView -from c3nav.editor.views import add_feature, edit_feature +from c3nav.editor.views import add_feature, edit_feature, finalize urlpatterns = [ url(r'^$', TemplateView.as_view(template_name='editor/map.html'), name='editor.index'), url(r'^features/(?P[^/]+)/add/$', add_feature, name='editor.feature.add'), - url(r'^features/edit/(?P[^/]+)/$', edit_feature, name='editor.feature.edit') + url(r'^features/edit/(?P[^/]+)/$', edit_feature, name='editor.feature.edit'), + url(r'^finalize/$', finalize, name='editor.finalize') ] diff --git a/src/c3nav/editor/views.py b/src/c3nav/editor/views.py index 010e5384..95c087b4 100644 --- a/src/c3nav/editor/views.py +++ b/src/c3nav/editor/views.py @@ -1,11 +1,16 @@ from django.conf import settings +from django.core import signing from django.core.exceptions import PermissionDenied -from django.db import transaction from django.http.response import Http404 from django.shortcuts import get_object_or_404, render +from django.utils.translation import ugettext_lazy as _ +from django.views.decorators.http import require_POST from c3nav.editor.forms import FeatureForm +from c3nav.editor.hosters import get_hoster_for_package from c3nav.mapdata.models.feature import FEATURE_TYPES, Feature +from c3nav.mapdata.models.package import Package +from c3nav.mapdata.packageio.write import json_encode from c3nav.mapdata.permissions import can_access_package @@ -17,17 +22,19 @@ def add_feature(request, feature_type): if request.method == 'POST': form = FeatureForm(request.POST, feature_type=feature_type) if form.is_valid(): - if not settings.DIRECT_EDITING: - return render(request, 'editor/feature_success.html', {}) + feature = form.instance + feature.feature_type = feature_type.name + feature.titles = {} + for language, title in form.titles.items(): + if title: + feature.titles[language] = title - with transaction.atomic(): - feature = form.instance - feature.feature_type = feature_type.name - feature.titles = {} - for language, title in form.titles.items(): - if title: - feature.titles[language] = title - feature.save() + if not settings.DIRECT_EDITING: + return render(request, 'editor/feature_success.html', { + 'data': signing.dumps((feature.package.name, feature.tofilename(), json_encode(feature.tofile()))) + }) + + feature.save() return render(request, 'editor/feature_success.html', {}) else: @@ -51,7 +58,9 @@ def edit_feature(request, name): if request.POST.get('delete') == '1': if request.POST.get('delete_confirm') == '1': if not settings.DIRECT_EDITING: - return render(request, 'editor/feature_success.html', {}) + return render(request, 'editor/feature_success.html', { + 'data': signing.dumps((feature.package.name, feature.tofilename(), None)) + }) feature.delete() return render(request, 'editor/feature_success.html', {}) @@ -64,17 +73,19 @@ def edit_feature(request, name): form = FeatureForm(instance=feature, data=request.POST, feature_type=feature_type) if form.is_valid(): - if not settings.DIRECT_EDITING: - return render(request, 'editor/feature_success.html', {}) + feature = form.instance + feature.feature_type = feature_type.name + feature.titles = {} + for language, title in form.titles.items(): + if title: + feature.titles[language] = title - with transaction.atomic(): - feature = form.instance - feature.feature_type = feature_type.name - feature.titles = {} - for language, title in form.titles.items(): - if title: - feature.titles[language] = title - feature.save() + if not settings.DIRECT_EDITING: + return render(request, 'editor/feature_success.html', { + 'data': signing.dumps((feature.package.name, feature.tofilename(), json_encode(feature.tofile()))) + }) + + feature.save() return render(request, 'editor/feature_success.html', {}) else: @@ -86,3 +97,26 @@ def edit_feature(request, name): 'path': request.path, 'new': False }) + + +@require_POST +def finalize(request): + if 'data' not in request.POST: + return render(request, 'editor/error.html', { + 'title': _('Missing data.'), + 'description': _('Edit data is missing.') + }, status=400) + + package_name, file_path, file_contents = signing.loads(request.POST['data']) + + package = Package.objects.filter(name=package_name).first() + hoster = None + if package is not None: + hoster = get_hoster_for_package(package) + + return render(request, 'editor/finalize.html', { + 'package_name': package_name, + 'hoster': hoster, + 'file_path': file_path, + 'file_contents': file_contents + })