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 %} -
+
{% if not embed %} {% get_current_language as CURRENT_LANGUAGE %} @@ -37,6 +37,9 @@

+
+ +