2017-07-05 22:35:14 +02:00
|
|
|
from contextlib import contextmanager
|
|
|
|
|
2017-07-05 22:04:22 +02:00
|
|
|
from django.conf import settings
|
2017-07-05 22:35:14 +02:00
|
|
|
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 _
|
|
|
|
|
|
|
|
|
|
|
|
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'
|
|
|
|
|
2017-07-05 22:35:14 +02:00
|
|
|
@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()))
|
2017-07-05 22:35:14 +02:00
|
|
|
|
|
|
|
@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
|
2017-07-05 22:35:14 +02:00
|
|
|
super().save(**kwargs)
|
2017-07-05 23:38:47 +02:00
|
|
|
cache.set('mapdata:last_update', (self.pk, self.datetime), 900)
|