set coordinates for position
This commit is contained in:
parent
171a183cef
commit
da07faf3cb
10 changed files with 118 additions and 15 deletions
31
src/c3nav/mapdata/migrations/0083_auto_20191227_1642.py
Normal file
31
src/c3nav/mapdata/migrations/0083_auto_20191227_1642.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# Generated by Django 2.2.8 on 2019-12-27 15:42
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mapdata', '0082_dynamiclocation_position'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='position',
|
||||||
|
name='last_location_update',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='position',
|
||||||
|
name='location_id',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='position',
|
||||||
|
name='coordinates_id',
|
||||||
|
field=models.CharField(max_length=48, null=True, verbose_name='coordinates'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='position',
|
||||||
|
name='last_coordinates_update',
|
||||||
|
field=models.DateTimeField(null=True, verbose_name='last coordinates update'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -496,8 +496,8 @@ class Position(models.Model):
|
||||||
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
||||||
name = models.CharField(_('name'), max_length=32)
|
name = models.CharField(_('name'), max_length=32)
|
||||||
secret = models.CharField(_('secret'), unique=True, max_length=32, default=get_position_secret)
|
secret = models.CharField(_('secret'), unique=True, max_length=32, default=get_position_secret)
|
||||||
last_location_update = models.DateTimeField(_('last location update'), null=True)
|
last_coordinates_update = models.DateTimeField(_('last coordinates update'), null=True)
|
||||||
location_id = models.CharField(_('location'), null=True, max_length=48)
|
coordinates_id = models.CharField(_('coordinates'), null=True, max_length=48)
|
||||||
api_secret = models.CharField(_('api secret'), max_length=64, default=get_position_api_secret)
|
api_secret = models.CharField(_('api secret'), max_length=64, default=get_position_api_secret)
|
||||||
|
|
||||||
coordinates = LocationById()
|
coordinates = LocationById()
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.forms import ModelForm
|
from django.forms import Form, ModelChoiceField, ModelForm
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from c3nav.mapdata.forms import I18nModelFormMixin
|
from c3nav.mapdata.forms import I18nModelFormMixin
|
||||||
|
@ -53,3 +55,12 @@ class PositionForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Position
|
model = Position
|
||||||
fields = ['name']
|
fields = ['name']
|
||||||
|
|
||||||
|
|
||||||
|
class PositionSetForm(Form):
|
||||||
|
position = ModelChoiceField(Position.objects.none())
|
||||||
|
|
||||||
|
def __init__(self, request, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.fields['position'].queryset = Position.objects.filter(owner=request.user)
|
||||||
|
self.fields['position'].label_from_instance = attrgetter('name')
|
||||||
|
|
|
@ -1290,7 +1290,7 @@ main form > p, #modal form > p {
|
||||||
resize: none;
|
resize: none;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
}
|
}
|
||||||
select {
|
select[multiple] {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1361,21 +1361,24 @@ c3nav = {
|
||||||
_click_anywhere: function(e) {
|
_click_anywhere: function(e) {
|
||||||
if (e.originalEvent.target.id !== 'map') return;
|
if (e.originalEvent.target.id !== 'map') return;
|
||||||
var popup = L.popup(c3nav._add_map_padding({className: 'location-popup', maxWidth: 500}, 'autoPanPaddingTopLeft', 'autoPanPaddingBottomRight')),
|
var popup = L.popup(c3nav._add_map_padding({className: 'location-popup', maxWidth: 500}, 'autoPanPaddingTopLeft', 'autoPanPaddingBottomRight')),
|
||||||
level = c3nav._levelControl.currentLevel,
|
name = c3nav._latlng_to_name(e.latlng);
|
||||||
name = 'c:'+String(c3nav.level_labels_by_id[level])+':'+Math.round(e.latlng.lng*100)/100+':'+Math.round(e.latlng.lat*100)/100;
|
|
||||||
var buttons = $('#anywhere-popup-buttons').clone();
|
var buttons = $('#anywhere-popup-buttons').clone();
|
||||||
buttons.find('.report').attr('href', '/report/l/' + name + '/');
|
buttons.find('.report').attr('href', '/report/l/' + name + '/');
|
||||||
|
buttons.find('.set-position').attr('href', '/positions/set/' + name + '/');
|
||||||
popup.setLatLng(e.latlng).setContent(buttons.html());
|
popup.setLatLng(e.latlng).setContent(buttons.html());
|
||||||
c3nav._click_anywhere_popup = popup;
|
c3nav._click_anywhere_popup = popup;
|
||||||
popup.on('remove', function() { c3nav._click_anywhere_popup = null }).openOn(c3nav.map);
|
popup.on('remove', function() { c3nav._click_anywhere_popup = null }).openOn(c3nav.map);
|
||||||
},
|
},
|
||||||
|
_latlng_to_name: function(latlng) {
|
||||||
|
var level = c3nav._levelControl.currentLevel;
|
||||||
|
return 'c:'+String(c3nav.level_labels_by_id[level])+':'+Math.round(latlng.lng*100)/100+':'+Math.round(latlng.lat*100)/100;
|
||||||
|
},
|
||||||
_click_anywhere_load: function(nearby) {
|
_click_anywhere_load: function(nearby) {
|
||||||
if (!c3nav._click_anywhere_popup) return;
|
if (!c3nav._click_anywhere_popup) return;
|
||||||
var latlng = c3nav._click_anywhere_popup.getLatLng();
|
var latlng = c3nav._click_anywhere_popup.getLatLng();
|
||||||
c3nav._click_anywhere_popup.remove();
|
c3nav._click_anywhere_popup.remove();
|
||||||
var popup = L.popup().setLatLng(latlng).setContent('<div class="loader"></div>'),
|
var popup = L.popup().setLatLng(latlng).setContent('<div class="loader"></div>'),
|
||||||
level = c3nav._levelControl.currentLevel,
|
name = c3nav._latlng_to_name(latlng);
|
||||||
name = 'c:'+String(c3nav.level_labels_by_id[level])+':'+Math.round(latlng.lng*100)/100+':'+Math.round(latlng.lat*100)/100;
|
|
||||||
c3nav._click_anywhere_popup = popup;
|
c3nav._click_anywhere_popup = popup;
|
||||||
popup.on('remove', function() { c3nav._click_anywhere_popup = null }).openOn(c3nav.map);
|
popup.on('remove', function() { c3nav._click_anywhere_popup = null }).openOn(c3nav.map);
|
||||||
$.getJSON('/api/locations/'+name+'/', function(data) {
|
$.getJSON('/api/locations/'+name+'/', function(data) {
|
||||||
|
@ -1621,6 +1624,7 @@ c3nav = {
|
||||||
var $user = $('header #user');
|
var $user = $('header #user');
|
||||||
$user.find('span').text(data.title);
|
$user.find('span').text(data.title);
|
||||||
$user.find('small').text(data.subtitle || '');
|
$user.find('small').text(data.subtitle || '');
|
||||||
|
$('.position-buttons').toggle(data.has_positions);
|
||||||
if (window.mobileclient) mobileclient.setUserData(JSON.stringify(data));
|
if (window.mobileclient) mobileclient.setUserData(JSON.stringify(data));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,12 @@
|
||||||
{% trans 'Show nearby locations' %}
|
{% trans 'Show nearby locations' %}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="buttons position-buttons">
|
||||||
|
<a class="button button-clear set-position">
|
||||||
|
<i class="material-icons">my_location</i>
|
||||||
|
{% trans 'Set my position' %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a class="button button-clear report report-missing">
|
<a class="button button-clear report report-missing">
|
||||||
<i class="material-icons">feedback</i>
|
<i class="material-icons">feedback</i>
|
||||||
|
|
|
@ -7,6 +7,13 @@
|
||||||
<h2>{% trans 'Position:' %} {{ position.name }}</h2>
|
<h2>{% trans 'Position:' %} {{ position.name }}</h2>
|
||||||
<p><a href="{% url 'site.position_list' %}">« {% trans 'back to overview' %}</a></p>
|
<p><a href="{% url 'site.position_list' %}">« {% trans 'back to overview' %}</a></p>
|
||||||
|
|
||||||
|
{% if position.coordinates %}
|
||||||
|
{% include 'site/fragment_location.html' with location=position.coordinates %}
|
||||||
|
{% else %}
|
||||||
|
<p><em>{% trans 'currently no coordinates' %}</em></p>
|
||||||
|
{% endif %}
|
||||||
|
<p><em>{% trans 'last coordinates update:' %} {{ position.last_coordinates_update }}</em></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<strong>{% trans 'Secret' %}:</strong>
|
<strong>{% trans 'Secret' %}:</strong>
|
||||||
<code>{{ position.secret }}</code>
|
<code>{{ position.secret }}</code>
|
||||||
|
@ -21,9 +28,10 @@
|
||||||
<form method="post" action="{{ request.path_info }}">
|
<form method="post" action="{{ request.path_info }}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form.as_p }}
|
{{ form.as_p }}
|
||||||
|
<label><input type="checkbox" name="set_null" value="1"> {% trans 'unset coordinates' %}</label>
|
||||||
<label><input type="checkbox" name="reset_secret" value="1"> {% trans 'reset secret' %}</label>
|
<label><input type="checkbox" name="reset_secret" value="1"> {% trans 'reset secret' %}</label>
|
||||||
<label><input type="checkbox" name="reset_api_secret" value="1"> {% trans 'reset API secret' %}</label>
|
<label><input type="checkbox" name="reset_api_secret" value="1"> {% trans 'reset API secret' %}</label>
|
||||||
<label><input type="checkbox" name="delete" value="1"> {% trans 'delete this position' %}</label>
|
<label><input type="checkbox" name="delete" value="1"> {% trans 'delete this position' %}</label>
|
||||||
<button type="submit">{% trans 'Update position' %}</button>
|
<button type="submit">{% trans 'Update position' %}</button>
|
||||||
</form>
|
</form>
|
||||||
</main>
|
</main>
|
||||||
|
|
16
src/c3nav/site/templates/site/position_set.html
Normal file
16
src/c3nav/site/templates/site/position_set.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{% extends 'site/base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<main class="account">
|
||||||
|
{% include 'site/fragment_messages.html' %}
|
||||||
|
<h2>{% trans 'Set position coordinates' %}</h2>
|
||||||
|
<p>{% trans 'Please select the position to set to these coordinates:' %}</p>
|
||||||
|
{% include 'site/fragment_location.html' with location=coordinates %}
|
||||||
|
<form method="post" action="{{ request.path_info }}">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.as_p }}
|
||||||
|
<button type="submit">{% trans 'Set coordinates' %}</button>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
|
@ -2,7 +2,7 @@ from django.conf.urls import url
|
||||||
|
|
||||||
from c3nav.site.views import (about_view, access_redeem_view, account_view, change_password_view, choose_language,
|
from c3nav.site.views import (about_view, access_redeem_view, account_view, change_password_view, choose_language,
|
||||||
login_view, logout_view, map_index, position_create, position_detail, position_list,
|
login_view, logout_view, map_index, position_create, position_detail, position_list,
|
||||||
qr_code, register_view, report_create, report_detail, report_list)
|
position_set, qr_code, register_view, report_create, report_detail, report_list)
|
||||||
|
|
||||||
slug = r'(?P<slug>[a-z0-9-_.:]+)'
|
slug = r'(?P<slug>[a-z0-9-_.:]+)'
|
||||||
coordinates = r'(?P<coordinates>[a-z0-9-_:]+:-?\d+(\.\d+)?:-?\d+(\.\d+)?)'
|
coordinates = r'(?P<coordinates>[a-z0-9-_:]+:-?\d+(\.\d+)?:-?\d+(\.\d+)?)'
|
||||||
|
@ -38,4 +38,5 @@ urlpatterns = [
|
||||||
url(r'^positions/$', position_list, name='site.position_list'),
|
url(r'^positions/$', position_list, name='site.position_list'),
|
||||||
url(r'^positions/create/$', position_create, name='site.position_create'),
|
url(r'^positions/create/$', position_create, name='site.position_create'),
|
||||||
url(r'^positions/(?P<pk>\d+)/$', position_detail, name='site.position_detail'),
|
url(r'^positions/(?P<pk>\d+)/$', position_detail, name='site.position_detail'),
|
||||||
|
url(r'^positions/set/%s/$' % coordinates, position_set, name='site.position_set'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -36,7 +36,7 @@ from c3nav.mapdata.utils.locations import (get_location_by_id_for_request, get_l
|
||||||
from c3nav.mapdata.utils.user import can_access_editor, get_user_data
|
from c3nav.mapdata.utils.user import can_access_editor, get_user_data
|
||||||
from c3nav.mapdata.views import set_tile_access_cookie
|
from c3nav.mapdata.views import set_tile_access_cookie
|
||||||
from c3nav.routing.models import RouteOptions
|
from c3nav.routing.models import RouteOptions
|
||||||
from c3nav.site.forms import PositionForm, ReportUpdateForm
|
from c3nav.site.forms import PositionForm, PositionSetForm, ReportUpdateForm
|
||||||
from c3nav.site.models import Announcement, SiteUpdate
|
from c3nav.site.models import Announcement, SiteUpdate
|
||||||
|
|
||||||
|
|
||||||
|
@ -514,12 +514,11 @@ def position_create(request):
|
||||||
'form': form,
|
'form': form,
|
||||||
})
|
})
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@login_required(login_url='site.login')
|
@login_required(login_url='site.login')
|
||||||
def position_detail(request, pk):
|
def position_detail(request, pk):
|
||||||
position = get_object_or_404(Position.objects.filter(owner=request.user), pk=pk)
|
position = get_object_or_404(Position.objects.filter(owner=request.user), pk=pk)
|
||||||
|
position.request = request
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
|
@ -528,6 +527,10 @@ def position_detail(request, pk):
|
||||||
messages.success(request, _('Position deleted.'))
|
messages.success(request, _('Position deleted.'))
|
||||||
return redirect(reverse('site.position_list'))
|
return redirect(reverse('site.position_list'))
|
||||||
|
|
||||||
|
if request.POST.get('set_null', None):
|
||||||
|
position.last_coordinates_update = timezone.now()
|
||||||
|
position.coordinates = None
|
||||||
|
|
||||||
if request.POST.get('reset_secret', None):
|
if request.POST.get('reset_secret', None):
|
||||||
position.secret = get_position_secret()
|
position.secret = get_position_secret()
|
||||||
|
|
||||||
|
@ -546,4 +549,27 @@ def position_detail(request, pk):
|
||||||
'position': position,
|
'position': position,
|
||||||
'form': form,
|
'form': form,
|
||||||
})
|
})
|
||||||
pass
|
|
||||||
|
|
||||||
|
@login_required(login_url='site.login')
|
||||||
|
def position_set(request, coordinates):
|
||||||
|
coordinates = get_location_by_id_for_request(coordinates, request)
|
||||||
|
if coordinates is None:
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = PositionSetForm(request, data=request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
position = form.cleaned_data['position']
|
||||||
|
position.last_coordinates_update = timezone.now()
|
||||||
|
position.coordinates = coordinates
|
||||||
|
position.save()
|
||||||
|
messages.success(request, _('Position set.'))
|
||||||
|
return redirect(reverse('site.position_detail', kwargs={'pk': position.pk}))
|
||||||
|
else:
|
||||||
|
form = PositionSetForm(request)
|
||||||
|
|
||||||
|
return render(request, 'site/position_set.html', {
|
||||||
|
'coordinates': coordinates,
|
||||||
|
'form': form,
|
||||||
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue