team-3/src/c3nav/mapdata/models/update.py

61 lines
2 KiB
Python
Raw Normal View History

from contextlib import contextmanager
2017-07-05 22:04:22 +02:00
from django.conf import settings
from django.core.cache import cache
from django.db import models, transaction
2017-07-05 23:38:47 +02:00
from django.utils.http import int_to_base36
from django.utils.timezone import make_naive
2017-07-05 22:04:22 +02:00
from django.utils.translation import ugettext_lazy as _
2017-10-20 17:00:14 +02:00
from c3nav.mapdata.tasks import delete_old_cached_tiles
2017-07-05 22:04:22 +02:00
class MapUpdate(models.Model):
"""
A map update. created whenever mapdata is changed.
"""
datetime = models.DateTimeField(auto_now_add=True, db_index=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT)
type = models.CharField(max_length=32)
class Meta:
verbose_name = _('Map update')
verbose_name_plural = _('Map updates')
default_related_name = 'mapupdates'
get_latest_by = 'datetime'
@classmethod
def last_update(cls):
last_update = cache.get('mapdata:last_update', None)
if last_update is not None:
return last_update
with cls.lock():
2017-07-05 23:38:47 +02:00
last_update = cls.objects.latest()
cache.set('mapdata:last_update', (last_update.pk, last_update.datetime), 900)
return last_update.pk, last_update.datetime
@classmethod
def cache_key(cls):
pk, dt = cls.last_update()
return int_to_base36(pk)+'_'+int_to_base36(int(make_naive(dt).timestamp()))
@classmethod
@contextmanager
def lock(cls):
with transaction.atomic():
yield cls.objects.select_for_update().earliest()
2017-07-05 22:04:22 +02:00
def save(self, **kwargs):
if self.pk is not None:
raise TypeError
from c3nav.mapdata.models import AltitudeArea
from c3nav.mapdata.render.cache import GeometryChangeTracker
from c3nav.mapdata.render.base import LevelRenderData
AltitudeArea.recalculate()
GeometryChangeTracker()
LevelRenderData.rebuild()
super().save(**kwargs)
2017-07-05 23:38:47 +02:00
cache.set('mapdata:last_update', (self.pk, self.datetime), 900)
2017-10-20 17:00:14 +02:00
delete_old_cached_tiles.apply_async(countdown=5)