UPD: dav_events: decoupled event model and eventflag model.
This commit is contained in:
@@ -52,6 +52,6 @@ class Migration(migrations.Migration):
|
||||
migrations.AddField(
|
||||
model_name='eventflag',
|
||||
name='user',
|
||||
field=models.ForeignKey(default=dav_events.models.event.get_system_user_id, on_delete=models.SET(dav_events.utils.get_ghost_user), related_name='+', to=settings.AUTH_USER_MODEL),
|
||||
field=models.ForeignKey(default=dav_events.models.eventflag.get_system_user_id, on_delete=models.SET(dav_events.utils.get_ghost_user), related_name='+', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from .event import Event, EventFlag
|
||||
from .event import Event
|
||||
from .eventflag import EventFlag
|
||||
from .eventstatus import EventStatus
|
||||
from .oneclickaction import OneClickAction
|
||||
|
||||
@@ -11,26 +11,22 @@ from django.contrib.auth import get_user_model
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.template.loader import get_template
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import get_language, ugettext_lazy as _
|
||||
from django_countries.fields import CountryField
|
||||
|
||||
from .. import choices
|
||||
from .. import config
|
||||
from .. import signals
|
||||
from ..utils import get_ghost_user, get_system_user
|
||||
from ..utils import get_ghost_user
|
||||
from ..workflow import DefaultWorkflow
|
||||
|
||||
from .eventflag import EventFlag
|
||||
from .eventstatus import EventStatus, get_or_create_event_status
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_system_user_id():
|
||||
return get_system_user().id
|
||||
|
||||
|
||||
class Event(models.Model):
|
||||
# Metadata
|
||||
owner = models.ForeignKey(settings.AUTH_USER_MODEL,
|
||||
@@ -314,17 +310,6 @@ class Event(models.Model):
|
||||
logger.info('Event updated: %s', self)
|
||||
signals.event_updated.send(sender=self.__class__, event=self, diff=diff_lines, user=self.editor)
|
||||
|
||||
# TODO: move this into workflow
|
||||
def set_flag(self, status, **kwargs):
|
||||
if not isinstance(status, EventStatus):
|
||||
status = get_or_create_event_status(status)
|
||||
kwargs['event'] = self
|
||||
kwargs['status'] = status
|
||||
flag = EventFlag(**kwargs)
|
||||
flag.save()
|
||||
logger.info('Flagging status \'%s\' for %s', status.code, self)
|
||||
return flag
|
||||
|
||||
def get_number(self):
|
||||
return self.workflow.get_number()
|
||||
|
||||
@@ -495,26 +480,3 @@ class Event(models.Model):
|
||||
template_name = os.path.join('dav_events', 'event', 'default.html')
|
||||
template = get_template(template_name)
|
||||
return template.render(self.get_template_context())
|
||||
|
||||
|
||||
# TODO: can we put this into a separated file?
|
||||
class EventFlag(models.Model):
|
||||
event = models.ForeignKey(Event, related_name='flags')
|
||||
status = models.ForeignKey(EventStatus,
|
||||
on_delete=models.PROTECT,
|
||||
related_name='+')
|
||||
timestamp = models.DateTimeField(default=timezone.now)
|
||||
user = models.ForeignKey(settings.AUTH_USER_MODEL,
|
||||
default=get_system_user_id,
|
||||
on_delete=models.SET(get_ghost_user),
|
||||
related_name='+')
|
||||
|
||||
class Meta:
|
||||
ordering = ['event', 'timestamp', 'status']
|
||||
|
||||
def __unicode__(self):
|
||||
s = u'{status} - {timestamp}'
|
||||
if self.user:
|
||||
s += u' by user {user}'
|
||||
return s.format(status=self.status, timestamp=self.timestamp.strftime('%d.%m.%Y %H:%M:%S'),
|
||||
user=self.user)
|
||||
|
||||
31
dav_events/models/eventflag.py
Normal file
31
dav_events/models/eventflag.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
from ..utils import get_ghost_user, get_system_user
|
||||
|
||||
|
||||
def get_system_user_id():
|
||||
return get_system_user().id
|
||||
|
||||
|
||||
class EventFlag(models.Model):
|
||||
event = models.ForeignKey('dav_events.Event', related_name='flags')
|
||||
status = models.ForeignKey('dav_events.EventStatus',
|
||||
on_delete=models.PROTECT,
|
||||
related_name='+')
|
||||
timestamp = models.DateTimeField(default=timezone.now)
|
||||
user = models.ForeignKey(settings.AUTH_USER_MODEL,
|
||||
default=get_system_user_id,
|
||||
on_delete=models.SET(get_ghost_user),
|
||||
related_name='+')
|
||||
|
||||
class Meta:
|
||||
ordering = ['event', 'timestamp', 'status']
|
||||
|
||||
def __unicode__(self):
|
||||
s = u'{status} - {timestamp}'
|
||||
if self.user:
|
||||
s += u' by user {user}'
|
||||
return s.format(status=self.status, timestamp=self.timestamp.strftime('%d.%m.%Y %H:%M:%S'),
|
||||
user=self.user)
|
||||
@@ -8,6 +8,8 @@ from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from . import emails
|
||||
from . import signals
|
||||
from .models.eventflag import EventFlag
|
||||
from .models.eventstatus import get_or_create_event_status
|
||||
from .utils import get_users_by_role, has_role
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -35,39 +37,20 @@ class BasicWorkflow(object):
|
||||
#
|
||||
# Status changes
|
||||
#
|
||||
def get_number(self):
|
||||
|
||||
# We use EventFlags to store the status information
|
||||
def _add_flag(self, code, **kwargs):
|
||||
event = self._event
|
||||
if event.number and event.flags.filter(status__code='accepted').exists():
|
||||
return event.number
|
||||
else:
|
||||
return '%s**/%d' % (event.sport, event.first_day.year % 100)
|
||||
status = get_or_create_event_status(code)
|
||||
kwargs['event'] = event
|
||||
kwargs['status'] = status
|
||||
flag = EventFlag(**kwargs)
|
||||
flag.save()
|
||||
logger.info('Flagging status \'%s\' for %s', status.code, event)
|
||||
return flag
|
||||
|
||||
def set_number(self):
|
||||
event = self._event
|
||||
counter = 0
|
||||
|
||||
year = event.first_day.year
|
||||
year_begin = datetime.date(year, 1, 1)
|
||||
year_end = datetime.date(year, 12, 31)
|
||||
qs = event.__class__.objects.filter(number__isnull=False,
|
||||
sport=event.sport,
|
||||
first_day__gte=year_begin,
|
||||
first_day__lte=year_end).order_by('number')
|
||||
last = qs.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)
|
||||
if match:
|
||||
gd = match.groupdict()
|
||||
counter = int(gd['count'])
|
||||
|
||||
counter += 1
|
||||
event.number = '%s%02d/%d' % (event.sport, counter, year % 100)
|
||||
event.save(implicit_update=True)
|
||||
return event.number
|
||||
|
||||
# TODO: the name/intention of this method is unclear.
|
||||
# Could we make it obsolete? At least it should be private
|
||||
def check_status(self, code=None):
|
||||
# TODO: the name/intention of this method is unclear. Could we make it obsolete?
|
||||
def _check_status(self, code=None):
|
||||
event = self._event
|
||||
if not event.id:
|
||||
return
|
||||
@@ -78,7 +61,7 @@ class BasicWorkflow(object):
|
||||
# Check if event has a draft flag.
|
||||
if not event.flags.filter(status__code='draft').exists():
|
||||
logger.info('Detected draft state of Event %s', event)
|
||||
event.set_flag(status='draft', timestamp=event.created_at)
|
||||
self._add_flag('draft', timestamp=event.created_at)
|
||||
|
||||
if code in (None, 'accepted'):
|
||||
# Check if event with accepted flag has a number.
|
||||
@@ -130,7 +113,7 @@ class BasicWorkflow(object):
|
||||
if not timestamp:
|
||||
timestamp = event.flags.filter(status__code='publishing').last().timestamp
|
||||
logger.info('Detected published state of Event %s', event)
|
||||
event.set_flag(status='published', timestamp=timestamp)
|
||||
self._add_flag('published', timestamp=timestamp)
|
||||
elif ((publishing_web.exists() or published_web.exists()) and
|
||||
(publishing_facebook.exists() or published_facebook.exists())):
|
||||
# All publishers have confirmed the publication date or have published already
|
||||
@@ -138,7 +121,7 @@ class BasicWorkflow(object):
|
||||
if not timestamp:
|
||||
timestamp = pub_flags.last().timestamp
|
||||
logger.info('Detected general published state of Event %s', event)
|
||||
event.set_flag(status='published', timestamp=timestamp)
|
||||
self._add_flag('published', timestamp=timestamp)
|
||||
else:
|
||||
if publishing_web.exists() and not published_web.exists():
|
||||
# One publisher has confirmed the publication date,
|
||||
@@ -146,20 +129,20 @@ class BasicWorkflow(object):
|
||||
if not timestamp:
|
||||
timestamp = event.flags.filter(status__code='publishing_web').last().timestamp
|
||||
logger.info('Detected published_web state of Event %s', event)
|
||||
event.set_flag(status='published_web', timestamp=timestamp)
|
||||
self._add_flag('published_web', timestamp=timestamp)
|
||||
if publishing_facebook.exists() and not published_facebook.exists():
|
||||
# One publisher has confirmed the publication date,
|
||||
# so we can flag, that he/she has published.
|
||||
if not timestamp:
|
||||
timestamp = event.flags.filter(status__code='publishing_facebook').last().timestamp
|
||||
logger.info('Detected published_facebook state of Event %s', event)
|
||||
event.set_flag(status='published_facebook', timestamp=timestamp)
|
||||
self._add_flag('published_facebook', timestamp=timestamp)
|
||||
if published_web.exists() and published_facebook.exists():
|
||||
# All publishers have published,
|
||||
# so we can flag the complete published state.
|
||||
timestamp = pub_flags.last().timestamp
|
||||
logger.info('Detected general published state of Event %s', event)
|
||||
event.set_flag(status='published', timestamp=timestamp)
|
||||
self._add_flag('published', timestamp=timestamp)
|
||||
elif not publishing.exists() and publishing_web.exists() and publishing_facebook.exists():
|
||||
# Event is not due to be published yet,
|
||||
# does not have a general publishing flag,
|
||||
@@ -168,7 +151,7 @@ class BasicWorkflow(object):
|
||||
logger.info('Detected publishing state of Event %s', event)
|
||||
flags = event.flags.filter(status__code__in=('publishing_web', 'publishing_facebook'))
|
||||
timestamp = flags.order_by('timestamp').last().timestamp
|
||||
event.set_flag(status='publishing', timestamp=timestamp)
|
||||
self._add_flag('publishing', timestamp=timestamp)
|
||||
|
||||
if code in (None, 'expired'):
|
||||
# Check if event is expired now and need a expired flag.
|
||||
@@ -190,10 +173,10 @@ class BasicWorkflow(object):
|
||||
if expired_at:
|
||||
logger.info('Detected expired state of Event %s', event)
|
||||
timestamp = timezone.make_aware(datetime.datetime.combine(expired_at, midnight))
|
||||
event.set_flag(status='expired', timestamp=timestamp)
|
||||
self._add_flag('expired', timestamp=timestamp)
|
||||
|
||||
def has_reached_status(self, code):
|
||||
self.check_status(code)
|
||||
self._check_status(code)
|
||||
if code == 'publishing*':
|
||||
codes = ['publishing', 'publishing_web', 'publishing_facebook']
|
||||
elif code == 'published*':
|
||||
@@ -243,8 +226,8 @@ class BasicWorkflow(object):
|
||||
if not valid:
|
||||
logger.warning(u'Invalid status update to \'%s\': %s Event: %s', code, message, event)
|
||||
|
||||
flag = event.set_flag(status=code, user=user)
|
||||
self.check_status(code)
|
||||
flag = self._add_flag(code, user=user)
|
||||
self._check_status(code)
|
||||
signals.event_status_updated.send(sender=self.__class__, event=event, flag=flag)
|
||||
|
||||
return flag
|
||||
@@ -253,7 +236,7 @@ class BasicWorkflow(object):
|
||||
event = self._event
|
||||
|
||||
status_list = []
|
||||
event.workflow.check_status()
|
||||
self._check_status()
|
||||
|
||||
heaviest_flag = event.flags.order_by('status').last()
|
||||
if heaviest_flag:
|
||||
@@ -283,6 +266,39 @@ class BasicWorkflow(object):
|
||||
|
||||
return status_list
|
||||
|
||||
#
|
||||
# Status related event properties
|
||||
#
|
||||
def get_number(self):
|
||||
event = self._event
|
||||
if event.number and event.flags.filter(status__code='accepted').exists():
|
||||
return event.number
|
||||
else:
|
||||
return '%s**/%d' % (event.sport, event.first_day.year % 100)
|
||||
|
||||
def set_number(self):
|
||||
event = self._event
|
||||
counter = 0
|
||||
|
||||
year = event.first_day.year
|
||||
year_begin = datetime.date(year, 1, 1)
|
||||
year_end = datetime.date(year, 12, 31)
|
||||
qs = event.__class__.objects.filter(number__isnull=False,
|
||||
sport=event.sport,
|
||||
first_day__gte=year_begin,
|
||||
first_day__lte=year_end).order_by('number')
|
||||
last = qs.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)
|
||||
if match:
|
||||
gd = match.groupdict()
|
||||
counter = int(gd['count'])
|
||||
|
||||
counter += 1
|
||||
event.number = '%s%02d/%d' % (event.sport, counter, year % 100)
|
||||
event.save(implicit_update=True)
|
||||
return event.number
|
||||
|
||||
#
|
||||
# Notifications (loose coupled via signals)
|
||||
#
|
||||
@@ -381,7 +397,7 @@ class BasicWorkflow(object):
|
||||
email.send()
|
||||
|
||||
#
|
||||
# Permission
|
||||
# Permissions
|
||||
#
|
||||
def has_permission(self, user, permission):
|
||||
if user.is_superuser:
|
||||
|
||||
Reference in New Issue
Block a user