UPD: change grace period for purging registration and participant data.

This commit is contained in:
2019-06-05 11:33:45 +02:00
parent 61605a205c
commit 4c67995680
5 changed files with 66 additions and 46 deletions

View File

@@ -9,7 +9,6 @@ from django.utils.translation import ugettext_lazy as _
from dav_base.validators import DAVNumberValidator from dav_base.validators import DAVNumberValidator
midnight = datetime.time(00, 00, 00) midnight = datetime.time(00, 00, 00)
one_day = datetime.timedelta(1)
@python_2_unicode_compatible @python_2_unicode_compatible
@@ -54,7 +53,8 @@ class Participant(models.Model):
ordering = ['event', 'position'] ordering = ['event', 'position']
def __str__(self): def __str__(self):
return '{position}. {name}'.format( return '{eventnumber} - {position}. {name}'.format(
eventnumber=self.event.get_number(),
position=self.position, position=self.position,
name=self.get_full_name(), name=self.get_full_name(),
) )
@@ -78,4 +78,18 @@ class Participant(models.Model):
last_day = event.alt_first_day last_day = event.alt_first_day
else: else:
last_day = event.first_day last_day = event.first_day
return timezone.make_aware(datetime.datetime.combine(last_day + one_day * 7, midnight))
april = datetime.date(last_day.year, 4, 1)
july = datetime.date(last_day.year, 7, 1)
july_nextyear = datetime.date(last_day.year + 1, 7, 1)
october = datetime.date(last_day.year, 10, 1)
january_nextyear = datetime.date(last_day.year + 1, 1, 1)
if last_day < april:
purge_date = july
elif last_day < october:
purge_date = january_nextyear
else:
purge_date = july_nextyear
return timezone.make_aware(datetime.datetime.combine(purge_date, midnight))

View File

@@ -2,11 +2,21 @@ import logging
from django.apps import apps from django.apps import apps
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.db.models import Q from django.utils import timezone
# from .models import Participant
app_config = apps.get_containing_app_config(__package__) app_config = apps.get_containing_app_config(__package__)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# def purge_participants():
# now = timezone.now()
# for p in Participant.objects.filter(purge_at__lte=now):
# logger.info('Purge participant \'%s\'', p)
# p.delete()
# TODO: most of the functions here are auth stuff. # TODO: most of the functions here are auth stuff.
@@ -65,14 +75,3 @@ def has_role(user, role):
if group_names and user.groups.filter(name__in=group_names).count(): if group_names and user.groups.filter(name__in=group_names).count():
return True return True
return False return False
def get_users_by_permission(permission_name, include_superusers=False):
appname, codename = permission_name.split('.')
query = Q(user_permissions__codename=codename, user_permissions__content_type__app_label=appname)
query |= Q(groups__permissions__codename=codename, groups__permissions__content_type__app_label=appname)
if include_superusers:
query |= Q(is_superuser=True)
return get_user_model().objects.filter(query).distinct()

View File

@@ -3,6 +3,7 @@ import datetime
import logging import logging
import re import re
from django.apps import apps from django.apps import apps
from django.db.models.functions import Length
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@@ -286,8 +287,8 @@ class BasicWorkflow(object):
qs = event.__class__.objects.filter(number__isnull=False, qs = event.__class__.objects.filter(number__isnull=False,
sport=event.sport, sport=event.sport,
first_day__gte=year_begin, first_day__gte=year_begin,
first_day__lte=year_end).order_by('number') first_day__lte=year_end).annotate(number_length=Length('number'))
last = qs.last() last = qs.order_by('number_length', 'number').last()
if last: if last:
match = re.match(r'^(?P<sport>[A-Z])(?P<count>[0-9][0-9]*)/(?P<year>[0-9][0-9]*)', last.number) match = re.match(r'^(?P<sport>[A-Z])(?P<count>[0-9][0-9]*)/(?P<year>[0-9][0-9]*)', last.number)
if match: if match:

View File

@@ -2,7 +2,6 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime import datetime
import logging import logging
import uuid
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
@@ -17,7 +16,6 @@ from . import signals
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
midnight = datetime.time(00, 00, 00) midnight = datetime.time(00, 00, 00)
one_day = datetime.timedelta(1)
@python_2_unicode_compatible @python_2_unicode_compatible
@@ -150,4 +148,18 @@ Anmerkung:
last_day = event.alt_first_day last_day = event.alt_first_day
else: else:
last_day = event.first_day last_day = event.first_day
return timezone.make_aware(datetime.datetime.combine(last_day + one_day * 7, midnight))
april = datetime.date(last_day.year, 4, 1)
july = datetime.date(last_day.year, 7, 1)
july_nextyear = datetime.date(last_day.year + 1, 7, 1)
october = datetime.date(last_day.year, 10, 1)
january_nextyear = datetime.date(last_day.year + 1, 1, 1)
if last_day < april:
purge_date = july
elif last_day < october:
purge_date = january_nextyear
else:
purge_date = july_nextyear
return timezone.make_aware(datetime.datetime.combine(purge_date, midnight))

View File

@@ -2,6 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime import datetime
from django.test import TestCase from django.test import TestCase
from django.utils import timezone
from dav_events.tests.generic import EventMixin from dav_events.tests.generic import EventMixin
@@ -13,9 +14,10 @@ from .generic import RegistrationMixin
class UtilsTestCase(RegistrationMixin, EventMixin, TestCase): class UtilsTestCase(RegistrationMixin, EventMixin, TestCase):
def test_purge(self): def test_purge(self):
today = datetime.date.today() now = timezone.now()
today = now.date()
one_day = datetime.timedelta(1) one_day = datetime.timedelta(1)
purge_after_days = 7 registrations_per_event = 1
common_event_data = { common_event_data = {
'title': 'Daytrip', 'title': 'Daytrip',
'description': 'Test', 'description': 'Test',
@@ -28,21 +30,9 @@ class UtilsTestCase(RegistrationMixin, EventMixin, TestCase):
'trainer_email': 'trainer@localhost', 'trainer_email': 'trainer@localhost',
} }
# We will create 4 events with different dates in the past first_day = today - (one_day * 367)
# 1. an event, that is happening right now -> we would still need the participants data while first_day < today:
# 2. an event that will be finished few days ago, but the grace period were we have to keep first_day += one_day
# the participants data is not over right now -> do not purge registrations
# 3. an event that will be finished long enough, so that we can purge the registrations
# 4. event will be finished even longer ago
# To all events, we will create some registrations
event_data = (
(True, today),
(True, today - one_day * (purge_after_days - 1)),
(False, today - one_day * purge_after_days),
(False, today - one_day * (purge_after_days + 1)),
)
events = []
for registrations_still_needed, first_day in event_data:
data = common_event_data.copy() data = common_event_data.copy()
data['first_day'] = first_day data['first_day'] = first_day
@@ -50,15 +40,19 @@ class UtilsTestCase(RegistrationMixin, EventMixin, TestCase):
self.submit_event(event) self.submit_event(event)
self.accept_event(event) self.accept_event(event)
self.create_registration({'event': event}) for i in range(0, registrations_per_event):
self.create_registration({'event': event}) self.create_registration({'event': event})
self.create_registration({'event': event})
events.append((event, registrations_still_needed))
# Now we purge obsolete registrations
purge_registrations() purge_registrations()
# Now we test for all 4 events, if there are still registrations registrations = Registration.objects.all()
for event, registrations_still_needed in events: n_registrations = registrations.count()
self.assertEqual(Registration.objects.filter(event=event).exists(), registrations_still_needed) # We keep registrations at min three months (min 90 days)
# So there should be at least the registrations of the events in the last 90 days left.
self.assertGreater(n_registrations, registrations_per_event * 90)
# We keep registrations at max nine months (max 276 days)
# So there should be no more registrations left, than of the events from the last 276 days.
self.assertGreater(registrations_per_event * 276, n_registrations)
for registration in registrations:
self.assertGreater(registration.purge_at, now)