in-between state, we now need to fix geometry field serialization
This commit is contained in:
parent
6db9e28a74
commit
f729efb9d4
6 changed files with 205 additions and 103 deletions
|
@ -1,5 +1,6 @@
|
|||
from abc import ABC, abstractmethod
|
||||
from collections import OrderedDict
|
||||
from contextlib import contextmanager
|
||||
from functools import wraps
|
||||
from typing import Optional
|
||||
|
||||
|
@ -17,19 +18,52 @@ from django.utils.translation import gettext_lazy as _
|
|||
|
||||
from c3nav.editor.models import ChangeSet
|
||||
from c3nav.editor.overlay import DatabaseOverlayManager
|
||||
from c3nav.mapdata.models import MapUpdate
|
||||
from c3nav.mapdata.models.access import AccessPermission
|
||||
from c3nav.mapdata.models.base import SerializableMixin
|
||||
from c3nav.mapdata.utils.cache.changes import changed_geometries
|
||||
from c3nav.mapdata.utils.user import can_access_editor
|
||||
|
||||
|
||||
@contextmanager
|
||||
def maybe_lock_changeset_to_edit(request):
|
||||
if request.changeset.pk:
|
||||
with request.changeset.lock_to_edit(request=request) as changeset:
|
||||
request.changeset = changeset
|
||||
yield
|
||||
else:
|
||||
yield
|
||||
|
||||
|
||||
def accesses_mapdata(func):
|
||||
@wraps(func)
|
||||
def wrapped(request, *args, **kwargs):
|
||||
changes = None if request.changeset.direct_editing is None else request.changeset.changes
|
||||
with DatabaseOverlayManager.enable(changes, commit=request.changeset.direct_editing) as manager:
|
||||
result = func(request, *args, **kwargs)
|
||||
print("operations", manager.new_operations)
|
||||
return result
|
||||
writable_method = request.method in ("POST", "PUT")
|
||||
|
||||
if request.changeset.direct_editing:
|
||||
with MapUpdate.lock():
|
||||
changed_geometries.reset()
|
||||
with DatabaseOverlayManager.enable(changes=None, commit=writable_method) as manager:
|
||||
result = func(request, *args, **kwargs)
|
||||
if manager.new_operations:
|
||||
if writable_method:
|
||||
MapUpdate.objects.create(user=request.user, type='direct_edit')
|
||||
else:
|
||||
raise ValueError # todo: good error message, but this shouldn't happen
|
||||
else:
|
||||
with maybe_lock_changeset_to_edit(request=request):
|
||||
with DatabaseOverlayManager.enable(changes=request.changeset.changes, commit=False) as manager:
|
||||
result = func(request, *args, **kwargs)
|
||||
if manager.new_operations:
|
||||
manager.save_new_operations()
|
||||
print(request.changeset.changes)
|
||||
print('saving to changeset!!')
|
||||
request.changeset.save()
|
||||
update = request.changeset.updates.create(user=request.user, objects_changed=True)
|
||||
request.changeset.last_update = update
|
||||
request.changeset.last_change = update
|
||||
request.changeset.save()
|
||||
return result
|
||||
|
||||
return wrapped
|
||||
|
||||
|
@ -48,7 +82,8 @@ def sidebar_view(func=None, select_related=None, api_hybrid=False):
|
|||
if not can_access_editor(request):
|
||||
raise PermissionDenied
|
||||
|
||||
request.changeset = ChangeSet.get_for_request(request, select_related)
|
||||
if getattr(request, "changeset", None) is None:
|
||||
request.changeset = ChangeSet.get_for_request(request, select_related)
|
||||
|
||||
if api:
|
||||
request.is_delete = request.method == 'DELETE'
|
||||
|
|
|
@ -38,24 +38,24 @@ def changeset_detail(request, pk):
|
|||
if request.method == 'POST':
|
||||
restore = request.POST.get('restore')
|
||||
if restore and restore.isdigit():
|
||||
with changeset.lock_to_edit(request) as changeset:
|
||||
if changeset.can_edit(request):
|
||||
try:
|
||||
changed_object = changeset.changed_objects_set.get(pk=restore)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
changed_object.restore()
|
||||
messages.success(request, _('Object has been successfully restored.'))
|
||||
except PermissionError:
|
||||
messages.error(request, _('You cannot restore this object, because it depends on '
|
||||
'a deleted object or it would violate a unique contraint.'))
|
||||
|
||||
else:
|
||||
messages.error(request, _('You can not edit changes on this change set.'))
|
||||
|
||||
return redirect(reverse('editor.changesets.detail', kwargs={'pk': changeset.pk}))
|
||||
raise NotImplementedError # todo: restore (no pun intended) this feature
|
||||
# if request.changeset.can_edit(request):
|
||||
# try:
|
||||
# changed_object = changeset.changed_objects_set.get(pk=restore)
|
||||
# except Exception:
|
||||
# pass
|
||||
# else:
|
||||
# try:
|
||||
# changed_object.restore()
|
||||
# messages.success(request, _('Object has been successfully restored.'))
|
||||
# except PermissionError:
|
||||
# messages.error(request, _('You cannot restore this object, because it depends on '
|
||||
# 'a deleted object or it would violate a unique contraint.'))
|
||||
#
|
||||
# else:
|
||||
# messages.error(request, _('You can not edit changes on this change set.'))
|
||||
#
|
||||
# return redirect(reverse('editor.changesets.detail', kwargs={'pk': changeset.pk}))
|
||||
|
||||
elif request.POST.get('activate') == '1':
|
||||
with changeset.lock_to_edit(request) as changeset:
|
||||
|
|
|
@ -128,7 +128,7 @@ def space_detail(request, level, pk):
|
|||
|
||||
|
||||
def get_changeset_exceeded(request):
|
||||
return request.user_permissions.max_changeset_changes <= request.changeset.changed_objects_count
|
||||
return request.user_permissions.max_changeset_changes <= len(request.changeset.changes.operations)
|
||||
|
||||
|
||||
@etag(editor_etag_func)
|
||||
|
@ -315,15 +315,14 @@ def edit(request, pk=None, model=None, level=None, space=None, on_top_of=None, e
|
|||
)
|
||||
|
||||
if request.POST.get('delete_confirm') == '1' or delete:
|
||||
with request.changeset.lock_to_edit(request) as changeset:
|
||||
if changeset.can_edit(request):
|
||||
obj.delete()
|
||||
else:
|
||||
return APIHybridMessageRedirectResponse(
|
||||
level='error',
|
||||
message=_('You can not edit changes on this changeset.'),
|
||||
redirect_to=request.path, status_code=403,
|
||||
)
|
||||
if request.changeset.can_edit(request): # todo: move this somewhere else
|
||||
obj.delete()
|
||||
else:
|
||||
return APIHybridMessageRedirectResponse(
|
||||
level='error',
|
||||
message=_('You can not edit changes on this changeset.'),
|
||||
redirect_to=request.path, status_code=403,
|
||||
)
|
||||
|
||||
if model == Level:
|
||||
if obj.on_top_of_id is not None:
|
||||
|
@ -360,28 +359,27 @@ def edit(request, pk=None, model=None, level=None, space=None, on_top_of=None, e
|
|||
if on_top_of is not None:
|
||||
obj.on_top_of = on_top_of
|
||||
|
||||
with request.changeset.lock_to_edit(request) as changeset:
|
||||
if changeset.can_edit(request):
|
||||
try:
|
||||
obj.save()
|
||||
except IntegrityError:
|
||||
error = APIHybridError(status_code=400, message=_('Duplicate entry.'))
|
||||
else:
|
||||
if form.redirect_slugs is not None:
|
||||
for slug in form.add_redirect_slugs:
|
||||
obj.redirects.create(slug=slug)
|
||||
|
||||
for slug in form.remove_redirect_slugs:
|
||||
obj.redirects.filter(slug=slug).delete()
|
||||
|
||||
form.save_m2m()
|
||||
return APIHybridMessageRedirectResponse(
|
||||
level='success',
|
||||
message=_('Object was successfully saved.'),
|
||||
redirect_to=ctx['back_url']
|
||||
)
|
||||
if request.changeset.can_edit(request): # todo: move this somewhere else
|
||||
try:
|
||||
obj.save()
|
||||
except IntegrityError:
|
||||
error = APIHybridError(status_code=400, message=_('Duplicate entry.'))
|
||||
else:
|
||||
error = APIHybridError(status_code=403, message=_('You can not edit changes on this changeset.'))
|
||||
if form.redirect_slugs is not None:
|
||||
for slug in form.add_redirect_slugs:
|
||||
obj.redirects.create(slug=slug)
|
||||
|
||||
for slug in form.remove_redirect_slugs:
|
||||
obj.redirects.filter(slug=slug).delete()
|
||||
|
||||
form.save_m2m()
|
||||
return APIHybridMessageRedirectResponse(
|
||||
level='success',
|
||||
message=_('Object was successfully saved.'),
|
||||
redirect_to=ctx['back_url']
|
||||
)
|
||||
else:
|
||||
error = APIHybridError(status_code=403, message=_('You can not edit changes on this changeset.'))
|
||||
|
||||
else:
|
||||
form = get_editor_form(model)(instance=obj, request=request, space_id=space_id,
|
||||
|
@ -640,14 +638,13 @@ def graph_edit(request, level=None, space=None):
|
|||
return redirect(request.path)
|
||||
|
||||
if request.POST.get('delete_confirm') == '1':
|
||||
with request.changeset.lock_to_edit(request) as changeset:
|
||||
if changeset.can_edit(request):
|
||||
node.edges_from_here.all().delete()
|
||||
node.edges_to_here.all().delete()
|
||||
node.delete()
|
||||
else:
|
||||
messages.error(request, _('You can not edit changes on this changeset.'))
|
||||
return redirect(request.path)
|
||||
if request.changeset.can_edit(request): # todo: move this somewhere else
|
||||
node.edges_from_here.all().delete()
|
||||
node.edges_to_here.all().delete()
|
||||
node.delete()
|
||||
else:
|
||||
messages.error(request, _('You can not edit changes on this changeset.'))
|
||||
return redirect(request.path)
|
||||
messages.success(request, _('Graph Node was successfully deleted.'))
|
||||
return redirect(request.path)
|
||||
return render(request, 'editor/delete.html', {
|
||||
|
@ -677,13 +674,12 @@ def graph_edit(request, level=None, space=None):
|
|||
active_node = None
|
||||
set_active_node = True
|
||||
else:
|
||||
with request.changeset.lock_to_edit(request) as changeset:
|
||||
if changeset.can_edit(request):
|
||||
connect_nodes(request, active_node, clicked_node, edge_settings_form)
|
||||
active_node = clicked_node if edge_settings_form.cleaned_data['activate_next'] else None
|
||||
set_active_node = True
|
||||
else:
|
||||
messages.error(request, _('You can not edit changes on this changeset.'))
|
||||
if request.changeset.can_edit(request): # todo: move this somewhere else
|
||||
connect_nodes(request, active_node, clicked_node, edge_settings_form)
|
||||
active_node = clicked_node if edge_settings_form.cleaned_data['activate_next'] else None
|
||||
set_active_node = True
|
||||
else:
|
||||
messages.error(request, _('You can not edit changes on this changeset.'))
|
||||
|
||||
elif (clicked_node is None and clicked_position is not None and
|
||||
active_node is None and space.geometry.contains(clicked_position)):
|
||||
|
@ -692,16 +688,15 @@ def graph_edit(request, level=None, space=None):
|
|||
messages.error(request, _('You can not add graph nodes because your changeset is full.'))
|
||||
return redirect(request.path)
|
||||
|
||||
with request.changeset.lock_to_edit(request) as changeset:
|
||||
if changeset.can_edit(request):
|
||||
node = GraphNode(space=space, geometry=clicked_position)
|
||||
node.save()
|
||||
messages.success(request, _('New graph node created.'))
|
||||
if request.changeset.can_edit(request): # todo: move this somewhere else
|
||||
node = GraphNode(space=space, geometry=clicked_position)
|
||||
node.save()
|
||||
messages.success(request, _('New graph node created.'))
|
||||
|
||||
active_node = None
|
||||
set_active_node = True
|
||||
else:
|
||||
messages.error(request, _('You can not edit changes on this changeset.'))
|
||||
active_node = None
|
||||
set_active_node = True
|
||||
else:
|
||||
messages.error(request, _('You can not edit changes on this changeset.'))
|
||||
|
||||
if set_active_node:
|
||||
connections = {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue