diff --git a/src/c3nav/mapdata/api.py b/src/c3nav/mapdata/api.py
index bdfe89c7..717c512a 100644
--- a/src/c3nav/mapdata/api.py
+++ b/src/c3nav/mapdata/api.py
@@ -418,7 +418,9 @@ class UpdatesViewSet(GenericViewSet):
except ValueError:
cache.set('api_updates_fetch_requests', 0, None)
+ from c3nav.site.models import SiteUpdate
response = Response({
+ 'last_site_update': SiteUpdate.last_update(),
'last_map_update': MapUpdate.current_processed_cache_key(),
'user': get_user_data(request),
})
diff --git a/src/c3nav/mapdata/models/update.py b/src/c3nav/mapdata/models/update.py
index dc536442..e5590a98 100644
--- a/src/c3nav/mapdata/models/update.py
+++ b/src/c3nav/mapdata/models/update.py
@@ -163,7 +163,7 @@ class MapUpdate(models.Model):
new_update.save()
transaction.on_commit(
- lambda: cache.set('mapdata:last_processed_update', new_updates[-1].to_tuple, 300)
+ lambda: cache.set('mapdata:last_processed_update', new_updates[-1].to_tuple, None)
)
return new_updates
@@ -188,7 +188,7 @@ class MapUpdate(models.Model):
if new:
transaction.on_commit(
- lambda: cache.set('mapdata:last_update', self.to_tuple, 300)
+ lambda: cache.set('mapdata:last_update', self.to_tuple, None)
)
if settings.HAS_CELERY:
transaction.on_commit(
diff --git a/src/c3nav/site/management/commands/createsiteupdate.py b/src/c3nav/site/management/commands/createsiteupdate.py
index bdc7a607..893cddba 100644
--- a/src/c3nav/site/management/commands/createsiteupdate.py
+++ b/src/c3nav/site/management/commands/createsiteupdate.py
@@ -8,7 +8,7 @@ class Command(BaseCommand):
result = input('Type YES to create a new site update: ')
if result == 'YES':
- from c3nav.mapdata.models import SiteUpdate
+ from c3nav.site.models import SiteUpdate
SiteUpdate.objects.create()
print('New site update created.')
else:
diff --git a/src/c3nav/site/models.py b/src/c3nav/site/models.py
index 025cbf1a..04bc34f1 100644
--- a/src/c3nav/site/models.py
+++ b/src/c3nav/site/models.py
@@ -1,6 +1,8 @@
+from contextlib import contextmanager
+
from django.conf import settings
from django.core.cache import cache
-from django.db import models
+from django.db import models, transaction
from django.db.models import Q
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
@@ -50,3 +52,42 @@ class SiteUpdate(models.Model):
A site update that asks the user to reload the page.
"""
created = models.DateTimeField(auto_now_add=True, verbose_name=_('create'))
+
+ class Meta:
+ verbose_name = _('Site update')
+ verbose_name_plural = _('Site updates')
+ default_related_name = 'siteupdates'
+ get_latest_by = 'created'
+
+ @classmethod
+ @contextmanager
+ def lock(cls):
+ with transaction.atomic():
+ try:
+ yield cls.objects.select_for_update().get(pk=cls.objects.earliest().pk)
+ except cls.DoesNotExist:
+ yield
+
+ @classmethod
+ def last_update(cls):
+ last_update = cache.get('site:last_site_update', None)
+ if last_update is not None:
+ return last_update
+ with cls.lock():
+ try:
+ last_update = cls.objects.latest()
+ except cls.DoesNotExist:
+ last_update = None
+ else:
+ last_update = last_update.pk
+ cache.set('site:last_site_update', last_update, None)
+ return last_update
+
+ def save(self, **kwargs):
+ new = self.pk is None
+ with transaction.atomic():
+ super().save(**kwargs)
+ if new:
+ transaction.on_commit(
+ lambda: cache.set('site:last_site_update', self.pk, None)
+ )
diff --git a/src/c3nav/site/static/site/js/c3nav.js b/src/c3nav/site/static/site/js/c3nav.js
index 853c63b3..94a0891b 100644
--- a/src/c3nav/site/static/site/js/c3nav.js
+++ b/src/c3nav/site/static/site/js/c3nav.js
@@ -68,6 +68,9 @@ c3nav = {
state = JSON.parse($main.attr('data-state'));
c3nav.embed = $main.is('[data-embed]');
+ c3nav.last_site_update = JSON.parse($main.attr('data-last-site-update'));
+ c3nav.new_site_update = false;
+
history.replaceState(state, window.location.path);
c3nav.load_state(state, true);
c3nav.update_map_locations();
@@ -549,10 +552,13 @@ c3nav = {
// console.log('state pushed');
history.pushState(state, '', url);
}
+
+ c3nav._maybe_load_site_update(state);
},
_onpopstate: function (e) {
// console.log('state popped');
c3nav.load_state(e.state);
+ c3nav._maybe_load_site_update(e.state);
},
load_state: function (state, nofly) {
if (state.modal) {
@@ -886,22 +892,24 @@ c3nav = {
}
},
- open_modal: function (content) {
+ modal_noclose: false,
+ open_modal: function (content, no_close) {
+ c3nav.modal_noclose = no_close;
var $modal = $('#modal');
- c3nav._set_modal_content(content);
+ c3nav._set_modal_content(content, no_close);
if (!$modal.is('.show')) {
c3nav._push_state({modal: true, sidebar: true});
$modal.addClass('show');
}
},
- _set_modal_content: function(content) {
+ _set_modal_content: function(content, no_close) {
$('#modal').toggleClass('loading', !content)
.find('#modal-content')
- .html('')
+ .html((!no_close) ? '' :'')
.append(content || '');
},
_modal_click: function(e) {
- if (e.target.id === 'modal' || e.target.id === 'close-modal') {
+ if (!c3nav.modal_noclose && (e.target.id === 'modal' || e.target.id === 'close-modal')) {
history.back();
}
},
@@ -1168,8 +1176,26 @@ c3nav = {
},
_fetch_updates_callback: function (data) {
c3nav.schedule_fetch_updates();
+ if (c3nav.last_site_update !== data.last_site_update) {
+ c3nav.new_site_update = true;
+ c3nav.last_site_update = data.last_site_update;
+ c3nav._maybe_load_site_update(c3nav.state);
+ }
c3nav._set_user_data(data.user);
},
+ _maybe_load_site_update: function(state) {
+ if (c3nav.new_site_update && !state.modal && (!state.routing || !state.origin || !state.destination)) {
+ c3nav._load_site_update();
+ }
+ },
+ _load_site_update: function() {
+ $('#modal-content').css({
+ width: 'auto',
+ minHeight: 0
+ });
+ c3nav.open_modal($('.reload-msg').html(), true);
+ window.location.reload();
+ },
_set_user_data: function (data) {
var $user = $('header #user');
$user.find('span').text(data.title);
diff --git a/src/c3nav/site/templates/site/map.html b/src/c3nav/site/templates/site/map.html
index 468b0ec9..0ba8bce9 100644
--- a/src/c3nav/site/templates/site/map.html
+++ b/src/c3nav/site/templates/site/map.html
@@ -4,7 +4,7 @@
{% load i18n %}
{% block content %}
-