BROKEN! MIGRATE! BIG UPD: not yet complete support for publish[ed|ing]_[web|facebook]
This commit is contained in:
7
dav_auth/admin.py
Normal file
7
dav_auth/admin.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.models import Permission
|
||||
|
||||
|
||||
@admin.register(Permission)
|
||||
class PermissionAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
@@ -7,14 +7,15 @@ from . import signals
|
||||
DEFAULT_SETTINGS = (
|
||||
DefaultSetting('enable_email_on_status_update', False),
|
||||
DefaultSetting('enable_email_on_update', False),
|
||||
DefaultSetting('group_manage_all', None),
|
||||
DefaultSetting('group_manage_w', None),
|
||||
DefaultSetting('group_manage_s', None),
|
||||
DefaultSetting('group_manage_m', None),
|
||||
DefaultSetting('group_manage_k', None),
|
||||
DefaultSetting('group_manage_b', None),
|
||||
DefaultSetting('group_publish', None),
|
||||
DefaultSetting('group_publish_incremental', None),
|
||||
DefaultSetting('groups_manager_super', []),
|
||||
DefaultSetting('groups_manager_w', []),
|
||||
DefaultSetting('groups_manager_s', []),
|
||||
DefaultSetting('groups_manager_m', []),
|
||||
DefaultSetting('groups_manager_k', []),
|
||||
DefaultSetting('groups_manager_b', []),
|
||||
DefaultSetting('groups_publisher_print', []),
|
||||
DefaultSetting('groups_publisher_web', []),
|
||||
DefaultSetting('groups_publisher_facebook', []),
|
||||
DefaultSetting('forms_development_init', False),
|
||||
DefaultSetting('form_initials', dict()),
|
||||
DefaultSetting('matrix_config', ImproperlyConfigured),
|
||||
|
||||
@@ -7,14 +7,15 @@ ENABLE_EMAIL_ON_STATUS_UPDATE = False
|
||||
ENABLE_EMAIL_ON_UPDATE = False
|
||||
|
||||
# Authorization Roles / Groups
|
||||
GROUP_MANAGE_ALL = 'Tourenreferenten'
|
||||
GROUP_MANAGE_W = 'Wanderreferenten'
|
||||
GROUP_MANAGE_S = 'Skireferenten'
|
||||
GROUP_MANAGE_M = 'MTBReferenten'
|
||||
GROUP_MANAGE_K = 'Kletterreferenten'
|
||||
GROUP_MANAGE_B = 'Bergsteigerreferenten'
|
||||
GROUP_PUBLISH = 'Redaktion'
|
||||
GROUP_PUBLISH_INCREMENTAL = 'OnlineRedaktion'
|
||||
GROUPS_MANAGER_SUPER = ['Tourenreferenten']
|
||||
GROUPS_MANAGER_W = ['Bereichsleiter_Wandern']
|
||||
GROUPS_MANAGER_S = ['Bereichsleiter_Ski']
|
||||
GROUPS_MANAGER_M = ['Bereichsleiter_MTB']
|
||||
GROUPS_MANAGER_K = ['Bereichsleiter_Klettern']
|
||||
GROUPS_MANAGER_B = ['Bereichsleiter_Bergsteigen']
|
||||
GROUPS_PUBLISHER_PRINT = ['Redaktion_KA-Alpin']
|
||||
GROUPS_PUBLISHER_WEB = ['Redaktion_Joomla']
|
||||
GROUPS_PUBLISHER_FACEBOOK = ['Redaktion_Facebook']
|
||||
|
||||
# ChainedForm and sub classes
|
||||
FORM_INITIALS = {
|
||||
|
||||
@@ -93,3 +93,11 @@ class EventToPublishMail(AbstractEventMail):
|
||||
context['editor'] = self._editor
|
||||
context['confirm_publication_url'] = self._confirm_publication_action.get_absolute_url()
|
||||
return context
|
||||
|
||||
|
||||
class EventToPublishWebMail(EventToPublishMail):
|
||||
_template_name = 'dav_events/emails/event_to_publish_web.txt'
|
||||
|
||||
|
||||
class EventToPublishFacebookMail(EventToPublishMail):
|
||||
_template_name = 'dav_events/emails/event_to_publish_facebook.txt'
|
||||
|
||||
20
dav_events/migrations/0024_auto_20190117_1515.py
Normal file
20
dav_events/migrations/0024_auto_20190117_1515.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.17 on 2019-01-17 15:15
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dav_events', '0023_auto_20181121_1422'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='oneclickaction',
|
||||
name='command',
|
||||
field=models.CharField(choices=[(b'EA', b'accept event'), (b'EP', b'confirm publication of an event'), (b'EL', b'login and go to event list'), (b'EVENT_STATUS_UPDATE', b'update event status')], max_length=254),
|
||||
),
|
||||
]
|
||||
19
dav_events/migrations/0025_auto_20190117_1518.py
Normal file
19
dav_events/migrations/0025_auto_20190117_1518.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.17 on 2019-01-17 15:18
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dav_events', '0024_auto_20190117_1515'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='event',
|
||||
options={'ordering': ['first_day'], 'verbose_name': 'Veranstaltung', 'verbose_name_plural': 'Veranstaltungen'},
|
||||
),
|
||||
]
|
||||
26
dav_events/migrations/0026_auto_20190123_1528.py
Normal file
26
dav_events/migrations/0026_auto_20190123_1528.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.17 on 2019-01-23 15:28
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dav_events', '0025_auto_20190117_1518'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='eventstatus',
|
||||
name='code',
|
||||
field=models.CharField(max_length=254, primary_key=True, serialize=False, validators=[django.core.validators.RegexValidator(b'^[0-9a-z_.-]*$', b'Only lower case latin characters (a-z), digits (0-9), dots (.), underscores (_) and hyphens (-) are allowed.')]),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='oneclickaction',
|
||||
name='command',
|
||||
field=models.CharField(choices=[(b'EVENT_LIST', b'login and go to event list (user id)'), (b'EVENT_STATUS_UPDATE', b'update event status (event id,status code,user id)')], max_length=254),
|
||||
),
|
||||
]
|
||||
@@ -246,7 +246,7 @@ class Event(models.Model):
|
||||
verbose_name = _(u'Veranstaltung')
|
||||
verbose_name_plural = _(u'Veranstaltungen')
|
||||
ordering = ['first_day']
|
||||
default_permissions = ('view', 'accept', 'edit', 'delete')
|
||||
# default_permissions = ('view', 'edit', 'delete')
|
||||
|
||||
def __unicode__(self):
|
||||
return u'{number} - {title} ({date})'.format(number=self.get_number(),
|
||||
@@ -331,8 +331,12 @@ class Event(models.Model):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_status_flags(self):
|
||||
return workflow.get_status_flags(self)
|
||||
|
||||
def get_status(self):
|
||||
workflow.status_code_update(self)
|
||||
|
||||
last_flag = self.flags.last()
|
||||
if last_flag:
|
||||
return last_flag.status
|
||||
@@ -472,7 +476,6 @@ class Event(models.Model):
|
||||
|
||||
r = {
|
||||
'event': self,
|
||||
'status': self.get_status(),
|
||||
'number': self.get_number(),
|
||||
'title': self.title,
|
||||
'description': self.description,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from ..validators import LowerAlphanumericValidator
|
||||
from ..validators import IdStringValidator
|
||||
|
||||
BOOTSTRAP_CONTEXT_CHOICES = (
|
||||
('default', 'default'),
|
||||
@@ -17,7 +17,11 @@ DEFAULT_EVENT_STATI = {
|
||||
'draft': (10, _(u'Entwurf'), 'info'),
|
||||
'submitted': (30, _(u'Eingereicht'), 'danger'),
|
||||
'accepted': (50, _(u'Freigegeben'), 'warning'),
|
||||
'publishing_facebook': (68, _(u'Veröffentlichung Facebook'), 'warning'),
|
||||
'publishing_web': (69, _(u'Veröffentlichung Web'), 'warning'),
|
||||
'publishing': (70, _(u'Veröffentlichung'), 'warning'),
|
||||
'published_facebook': (78, _(u'Veröffentlicht Facebook'), 'success'),
|
||||
'published_web': (79, _(u'Veröffentlicht Web'), 'success'),
|
||||
'published': (80, _(u'Veröffentlicht'), 'success'),
|
||||
'expired': (100, _(u'Ausgelaufen'), None),
|
||||
}
|
||||
@@ -39,7 +43,7 @@ def get_event_status(code):
|
||||
|
||||
|
||||
class EventStatus(models.Model):
|
||||
code = models.CharField(primary_key=True, max_length=254, validators=[LowerAlphanumericValidator])
|
||||
code = models.CharField(primary_key=True, max_length=254, validators=[IdStringValidator])
|
||||
severity = models.IntegerField(unique=True)
|
||||
label = models.CharField(unique=True, max_length=254)
|
||||
bootstrap_context = models.CharField(max_length=20, blank=True, choices=BOOTSTRAP_CONTEXT_CHOICES)
|
||||
@@ -50,9 +54,9 @@ class EventStatus(models.Model):
|
||||
ordering = ['severity']
|
||||
|
||||
def __unicode__(self):
|
||||
return u'{label} ({severity} {code})'.format(code=self.code,
|
||||
severity=self.severity,
|
||||
label=self.label)
|
||||
return u'{label} ({severity} - {code})'.format(code=self.code,
|
||||
severity=self.severity,
|
||||
label=self.label)
|
||||
|
||||
def get_bootstrap_label(self):
|
||||
context = self.bootstrap_context or 'default'
|
||||
|
||||
@@ -14,9 +14,8 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class OneClickAction(models.Model):
|
||||
COMMANDS = (
|
||||
('EA', 'accept event'),
|
||||
('EP', 'confirm publication of an event'),
|
||||
('EL', 'login and go to event list')
|
||||
('EVENT_LIST', 'login and go to event list (user id)'),
|
||||
('EVENT_STATUS_UPDATE', 'update event status (event id,status code,user id)'),
|
||||
)
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
@@ -28,7 +27,7 @@ class OneClickAction(models.Model):
|
||||
done_at = models.DateTimeField(blank=True,
|
||||
null=True)
|
||||
|
||||
command = models.CharField(max_length=2, choices=COMMANDS)
|
||||
command = models.CharField(max_length=254, choices=COMMANDS)
|
||||
|
||||
parameters = models.TextField(blank=True)
|
||||
|
||||
@@ -56,79 +55,7 @@ class OneClickAction(models.Model):
|
||||
return result
|
||||
|
||||
logger.info('OneClickAction.run(): %s(%s)', self.command, self.parameters)
|
||||
if self.command == 'EA':
|
||||
text = u''
|
||||
try:
|
||||
event_id, user_id = self.parameters.split(',')
|
||||
event = Event.objects.get(id=event_id)
|
||||
user = get_user_model().objects.get(id=user_id)
|
||||
flag = event.flags.filter(status__code='accepted').first()
|
||||
if flag:
|
||||
status = 'info'
|
||||
message = (ugettext(u'Veranstaltung wurde bereits von %(fullname)s freigegeben.') %
|
||||
{'fullname': flag.user.get_full_name()})
|
||||
text = unicode(event)
|
||||
text += u'\n'
|
||||
text += (ugettext(u'Freigegeben am: %(date)s') %
|
||||
{'date': flag.timestamp.strftime('%d.%m.%Y %H:%M:%S')})
|
||||
else:
|
||||
event.confirm_status('accepted', user)
|
||||
status = 'success'
|
||||
message = ugettext(u'Veranstaltung freigegeben.')
|
||||
text = unicode(event)
|
||||
|
||||
self.done = True
|
||||
self.done_at = timezone.now()
|
||||
self.save()
|
||||
except Exception as e:
|
||||
status = 'danger'
|
||||
message = str(e)
|
||||
logger.error('OneClickAction.run(): %s(%s): %s', self.command, self.parameters, message)
|
||||
|
||||
result['context'] = {
|
||||
'status': status,
|
||||
'message': message,
|
||||
'text': text,
|
||||
}
|
||||
elif self.command == 'EP':
|
||||
text = u''
|
||||
try:
|
||||
event_id, user_id = self.parameters.split(',')
|
||||
event = Event.objects.get(id=event_id)
|
||||
user = get_user_model().objects.get(id=user_id)
|
||||
flag = event.flags.filter(status__code__in=('publishing', 'published')).first()
|
||||
if flag:
|
||||
status = 'info'
|
||||
message = (ugettext(u'Veröffentlichung wurde bereits von %(fullname)s bestätigt.') %
|
||||
{'fullname': flag.user.get_full_name()})
|
||||
text = unicode(event)
|
||||
text += u'\n'
|
||||
text += (ugettext(u'Bestätigt am: %(date)s') %
|
||||
{'date': flag.timestamp.strftime('%d.%m.%Y %H:%M:%S')})
|
||||
else:
|
||||
if event.planned_publication_date:
|
||||
new_state = 'publishing'
|
||||
else:
|
||||
new_state = 'published'
|
||||
event.confirm_status(new_state, user)
|
||||
status = 'success'
|
||||
message = ugettext(u'Veröffentlichung registriert.')
|
||||
text = unicode(event)
|
||||
|
||||
self.done = True
|
||||
self.done_at = timezone.now()
|
||||
self.save()
|
||||
except Exception as e:
|
||||
status = 'danger'
|
||||
message = str(e)
|
||||
logger.error('OneClickAction.run(): %s(%s): %s', self.command, self.parameters, message)
|
||||
|
||||
result['context'] = {
|
||||
'status': status,
|
||||
'message': message,
|
||||
'text': text,
|
||||
}
|
||||
elif self.command == 'EL':
|
||||
if self.command == 'EVENT_LIST':
|
||||
try:
|
||||
user_id = self.parameters
|
||||
user = get_user_model().objects.get(id=user_id)
|
||||
@@ -142,6 +69,42 @@ class OneClickAction(models.Model):
|
||||
'status': 'danger',
|
||||
'message': message,
|
||||
}
|
||||
elif self.command == 'EVENT_STATUS_UPDATE':
|
||||
try:
|
||||
event_id, status_code, user_id = self.parameters.split(',')
|
||||
event = Event.objects.get(id=event_id)
|
||||
user = get_user_model().objects.get(id=user_id)
|
||||
|
||||
flag = event.flags.filter(status__code=status_code).first()
|
||||
if flag:
|
||||
message = (ugettext(u'Der Status wurde bereits'
|
||||
u' am %(date)s'
|
||||
u' von %(user)s'
|
||||
u' auf \'%(status)s\' gesetzt.') % {
|
||||
'status': flag.status.label,
|
||||
'date': flag.timestamp.strftime('%d.%m.%Y %H:%M:%S'),
|
||||
'user': flag.user.get_full_name(),
|
||||
})
|
||||
else:
|
||||
flag = event.confirm_status(status_code, user)
|
||||
message = (ugettext(u'Der Status wurde auf \'%(status)s\' gesetzt.') %
|
||||
{'status': flag.status.label})
|
||||
|
||||
result['context'] = {
|
||||
'status': 'success',
|
||||
'message': message,
|
||||
}
|
||||
|
||||
self.done = True
|
||||
self.done_at = timezone.now()
|
||||
self.save()
|
||||
except Exception as e:
|
||||
message = str(e)
|
||||
logger.error('OneClickAction.run(): %s(%s): %s', self.command, self.parameters, message)
|
||||
result['context'] = {
|
||||
'status': 'danger',
|
||||
'message': message,
|
||||
}
|
||||
else:
|
||||
result['context'] = {
|
||||
'status': 'danger',
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
{% load i18n %}Hallo {{ recipient.first_name }},
|
||||
|
||||
{{ trainer_firstname }} {{ trainer_familyname }} hat eine neue Veranstaltung eingereicht.
|
||||
Die Veranstaltung wurde {% if editor %}von {{ editor.get_full_name }} {% endif %}zur Veröffentlichung
|
||||
auf Facebook frei gegeben.
|
||||
|
||||
Der folgende Link führt zur Veranstaltung:
|
||||
{{ base_url }}{{ event.get_absolute_url }}
|
||||
Über den folgenden Link kannst du die Veröffentlichung auf Facebook unmittelbar bestätigen:
|
||||
{{ base_url }}{{ confirm_publication_url }}
|
||||
|
||||
Veröffentlichung: ({% if planned_publication_date %}{{ planned_publication_date|date:'l, d. F Y' }}{% else %}sofort{% endif %})
|
||||
=================
|
||||
{% if planned_publication_date %}Veröffentlichung starten: {{ planned_publication_date|date:'d.m.Y' }} 00:00:00
|
||||
{% endif %}Veröffentlichung beenden: {{ day_after|date:'d.m.Y' }} 00:00:00
|
||||
Erstellungsdatum: {{ first_day|date:'d.m.Y' }} 00:00:00
|
||||
Titel: {{ number }} - {{ title }}
|
||||
{% if internal_note %}
|
||||
Bearbeitungshinweis:
|
||||
====================
|
||||
{{ internal_note }}
|
||||
{% endif %}
|
||||
Ausschreibung:
|
||||
==============
|
||||
{{ event.render_as_text }}
|
||||
@@ -0,0 +1,73 @@
|
||||
{% load i18n %}Hallo {{ recipient.first_name }},
|
||||
|
||||
{{ trainer_firstname }} {{ trainer_familyname }} hat eine neue Veranstaltung eingereicht.
|
||||
Die Veranstaltung wurde {% if editor %}von {{ editor.get_full_name }} {% endif %}zur Veröffentlichung
|
||||
auf der Webseite frei gegeben.
|
||||
|
||||
Der folgende Link führt zur Veranstaltung:
|
||||
{{ base_url }}{{ event.get_absolute_url }}
|
||||
Über den folgenden Link kannst du die Veröffentlichung auf der Webseite unmittelbar bestätigen:
|
||||
{{ base_url }}{{ confirm_publication_url }}
|
||||
|
||||
Veröffentlichung: ({% if planned_publication_date %}{{ planned_publication_date|date:'l, d. F Y' }}{% else %}sofort{% endif %})
|
||||
=================
|
||||
{% if planned_publication_date %}Veröffentlichung starten: {{ planned_publication_date|date:'d.m.Y' }} 00:00:00
|
||||
{% endif %}Veröffentlichung beenden: {{ day_after|date:'d.m.Y' }} 00:00:00
|
||||
Erstellungsdatum: {{ first_day|date:'d.m.Y' }} 00:00:00
|
||||
Titel: {{ number }} - {{ title }}
|
||||
{% if internal_note %}
|
||||
Bearbeitungshinweis:
|
||||
====================
|
||||
{{ internal_note }}
|
||||
{% endif %}
|
||||
Joomla HTML
|
||||
===========
|
||||
<h6>{{ normalized_long_date }}{% if alt_normalized_long_date %}<br />
|
||||
({% trans 'Ersatztermin' %}: {{ alt_normalized_long_date }})
|
||||
{% endif %}</h6>
|
||||
<p>{{ description|urlize|linebreaksbr }}</p>
|
||||
{% if mode == 'training' %}
|
||||
<p><strong>{% trans 'Kursinhalte' %}:</strong></p>
|
||||
{% if course_topic_2 %}<ul>
|
||||
<li>{{ course_topic_1|urlize }}</li>
|
||||
<li>{{ course_topic_2|urlize }}</li>
|
||||
{% if course_topic_3 %} <li>{{ course_topic_3|urlize }}</li>
|
||||
{% endif %}{% if course_topic_4 %} <li>{{ course_topic_4|urlize }}</li>
|
||||
{% endif %}{% if course_topic_5 %} <li>{{ course_topic_5|urlize }}</li>
|
||||
{% endif %}{% if course_topic_6 %} <li>{{ course_topic_6|urlize }}</li>
|
||||
{% endif %}</ul>
|
||||
{% else %}<p>{{ course_topic_1|urlize|linebreaksbr }}</p>{% endif %}
|
||||
<p><strong>{% trans 'Kursziele' %}:</strong></p>
|
||||
{% if course_goal_2 %}<ul>
|
||||
<li>{{ course_goal_1|urlize }}</li>
|
||||
<li>{{ course_goal_2|urlize }}</li>
|
||||
{% if course_goal_3 %} <li>{{ course_goal_3|urlize }}</li>
|
||||
{% endif %}{% if course_goal_4 %} <li>{{ course_goal_4|urlize }}</li>
|
||||
{% endif %}{% if course_goal_5 %} <li>{{ course_goal_5|urlize }}</li>
|
||||
{% endif %}{% if course_goal_6 %} <li>{{ course_goal_6|urlize }}</li>
|
||||
{% endif %}</ul>
|
||||
{% else %}<p>{{ course_goal_1|urlize|linebreaksbr }}</p>{% endif %}
|
||||
{% endif %}<hr id="system-readmore" />
|
||||
|
||||
<p>
|
||||
{% if requirements %}<strong>{% trans 'Anforderungen' %}:</strong> {{ requirements }}<br />
|
||||
{% endif %}{% if equipment %}<strong>{% trans 'Ausrüstung' %}:</strong> {{ equipment }}<br />
|
||||
{% endif %}{% if location %}<strong>{% trans 'Ort' %}:</strong> {{ location }} {% if country and country != 'DE' and country != 'XX' %}({{ country }}){% endif %}<br />
|
||||
{% endif %}{% if basecamp %}<strong>{% trans 'Stützpunkt' %}:</strong> {{ basecamp }}<br />
|
||||
{% endif %}{% if accommodation and accommodation != 'NONE' %}<strong>{% trans 'Unterkunft' %}:</strong> {% if accommodation == 'OTHER' %}{{ accommodation_other }}{% else %}{{ event.get_accommodation_display }}{% endif %}<br />
|
||||
{% endif %}{% if meals and meals != 'NONE' %}<strong>{% trans 'Verpflegung' %}:</strong> {% if meals == 'OTHER' %}{{ meals_other }}{% else %}{{ event.get_meals_display }}{% endif %}<br />
|
||||
{% endif %}{% if transport and transport != 'NONE' and transport != 'public' %}<strong>{% trans 'Hin- / Rückfahrt' %}:</strong> {% if transport == 'OTHER' %}{{ transport_other }}{% else %}{{ event.get_transport_display }}{% endif %}<br />
|
||||
{% endif %}{% if meeting_point and meeting_point != 'NONE' %}<strong>{% trans 'Treffpunkt' %}:</strong> {% if meeting_time %}{{ meeting_time|time:'G:i'|cut:':00' }} Uhr, {% endif %}{% if meeting_point == 'OTHER' %}{{ meeting_point_other }}{% else %}{{ event.get_meeting_point_display }}{% endif %}<br />
|
||||
{% endif %}{% if transport == 'public' %}{% if departure_time or departure_ride %}<strong>{% trans 'Abfahrt' %}:</strong> {% if departure_time %}{{ departure_time|time:'G:i'|cut:':00' }} Uhr{% endif %}{% if departure_time and departure_ride %}, {% endif %}{% if departure_ride %}{{ departure_ride }}{% endif %}<br />
|
||||
{% endif %}{% endif %}{% if return_departure_time or return_arrival_time %}<strong>{% trans 'Rückfahrt' %}:</strong> {% if return_arrival_time %}{{ return_arrival_time|time:'G:i'|cut:':00' }} Uhr ({% trans 'Ankunft in' %} Karlsruhe){% elif return_departure_time %}{{ return_departure_time|time:'G:i'|cut:':00' }} Uhr ({% trans 'Abfahrt am Tourenort' %}){% endif %}<br />
|
||||
{% endif %}{% if pre_meeting_1 %}{% if pre_meeting_2 %}<strong>{% trans 'Vortreffen' %} 1:</strong> {{ pre_meeting_1|date:'l, d. F Y, G:i'|cut:':00' }} {% trans 'Uhr' %}, DAV {% trans 'Sektionszentrum' %}<br />
|
||||
<strong>{% trans 'Vortreffen' %} 2:</strong> {{ pre_meeting_2|date:'l, d. F Y, G:i'|cut:':00' }} {% trans 'Uhr' %}, DAV {% trans 'Sektionszentrum' %}<br />
|
||||
{% else %}<strong>{% trans 'Vortreffen' %}:</strong> {{ pre_meeting_1|date:'l, d. F Y, G:i'|cut:':00' }} {% trans 'Uhr' %}, DAV {% trans 'Sektionszentrum' %}<br />{% endif %}
|
||||
{% endif %}{% if min_participants > 0 or max_participants > 0 %}<strong>{% trans 'Teilnehmerzahl' %}:</strong> {% if min_participants == max_participants %}{{ max_participants }} {% trans 'Teilnehmer' %}{% elif min_participants > 0 and max_participants > 0 %}{{ min_participants }} - {{ max_participants }} {% trans 'Teilnehmer' %}{% elif min_participants > 0 %}min. {{ min_participants }} {% trans 'Teilnehmer' %}{% else %}max. {{ max_participants }} {% trans 'Teilnehmer' %}{% endif %}<br />
|
||||
{% endif %}{% if charge > 0 or additional_costs %}<strong>{% trans 'Kosten' %}:</strong> {% if charge > 0 %}{{ charge|floatformat:'-2' }} € {% trans 'Teilnahmegebühr' %}{% endif %}{% if additional_costs %}{% if charge > 0 %} {% trans 'zzgl.' %} {% endif %}{{ additional_costs }}{% endif %}<br />
|
||||
{% endif %}{% if registration_required and deadline %}<strong>{% trans 'Anmeldeschluss' %}:</strong> {{ deadline|date:'l, d. F Y' }}<br />
|
||||
{% endif %}{% if trainer_2_fullname %}{% if mode == 'training' %}<strong>{% trans 'Ausbildungsteam' %}:</strong>{% else %}<strong>{% trans 'Team' %}:</strong>{% endif %} {{ trainer_firstname }} {{ trainer_familyname }}, {{ trainer_2_fullname }}{% if trainer_3_fullname %}, {{ trainer_3_fullname }}{% endif %}<br />
|
||||
{% endif %}{% if trainer_familyname %}<strong>{% trans 'Leitung' %}:</strong> {{ trainer_firstname }} {{ trainer_familyname }}{% if trainer_email or trainer_phone %} ({% if trainer_email %}<a href="mailto:{{ trainer_email }}">{{ trainer_email }}</a>{% endif %}{% if trainer_email and trainer_phone %}, {% endif %}{% if trainer_phone %}{{ trainer_phone }}{% endif %}){% endif %}
|
||||
{% endif %}</p>
|
||||
{% if registration_required and registration_howto %}<p>{{ registration_howto|urlize }}</p>
|
||||
{% endif %}
|
||||
@@ -3,12 +3,12 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="pull-right">
|
||||
{% if status.code != 'void' %}
|
||||
{{ status.get_bootstrap_label|safe }}
|
||||
{% if status.code == 'publishing' %}
|
||||
<span class="label label-{{ status.bootstrap_context|default:'default' }}">{{ planned_publication_date|date:'d.m.Y' }}</span>
|
||||
{% endif %}
|
||||
{% for flag in event.get_status_flags %}
|
||||
{{ flag.status.get_bootstrap_label|safe }}
|
||||
{% if planned_publication_date and flag.status.code|slice:":10" == 'publishing' %}
|
||||
<span class="label label-{{ flag.status.bootstrap_context|default:'default' }}">{{ planned_publication_date|date:'d.m.Y' }}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<span class="panel-title">{{ number }} - {{ title }}</span>
|
||||
</div>
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
<div class="action-tabs">
|
||||
<div class="pull-right">
|
||||
{% if has_permission_submit %}
|
||||
<a class="btn {% if event.get_status.code == 'draft' %}btn-success{% else %}btn-default disabled{% endif %}"
|
||||
<a class="btn {% if 'submitted' in event.get_status_codes %}btn-default disabled{% else %}btn-success{% endif %}"
|
||||
data-toggle="modal" data-target="#modal-submit-dialog">
|
||||
{% if 'submitted' in event.get_status_codes %}
|
||||
{% bootstrap_icon 'check' %} 
|
||||
@@ -113,7 +113,7 @@
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if has_permission_accept %}
|
||||
<a class="btn {% if event.get_status.code == 'submitted' %}btn-success{% else %}btn-default disabled{% endif %}"
|
||||
<a class="btn {% if 'accepted' in event.get_status_codes %}btn-default disabled{% else %}btn-success{% endif %}"
|
||||
data-toggle="modal" data-target="#modal-accept-dialog">
|
||||
{% if 'accepted' in event.get_status_codes %}
|
||||
{% bootstrap_icon 'check' %} 
|
||||
|
||||
@@ -65,10 +65,14 @@
|
||||
{{ event.get_numeric_date }}
|
||||
</td>
|
||||
<td>
|
||||
{{ event.get_status.get_bootstrap_label|safe }}
|
||||
{% if event.get_status.code == 'publishing' %}
|
||||
<span class="label label-{{ event.get_status.bootstrap_context|default:'default' }}">{{ event.planned_publication_date|date:'d.m.Y' }}</span>
|
||||
{% for flag in event.get_status_flags %}
|
||||
{{ flag.status.get_bootstrap_label|safe }}
|
||||
{% if event.planned_publication_date and flag.status.code|slice:':10' == 'publishing' %}
|
||||
<span class="label label-{{ flag.status.bootstrap_context|default:'default' }}">{{ event.planned_publication_date|date:'d.m.Y' }}</span>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
{{ event.get_status.get_bootstrap_label|safe }}
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
@@ -2,6 +2,7 @@ import logging
|
||||
from django.apps import apps
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Group
|
||||
from django.db.models import Q
|
||||
|
||||
app_config = apps.get_containing_app_config(__package__)
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -26,21 +27,50 @@ def get_group_members(group_name, ignore_missing=False):
|
||||
return users
|
||||
|
||||
|
||||
def get_group_name_by_role(role):
|
||||
group_name_var = 'group_{}'.format(role)
|
||||
return getattr(app_config.settings, group_name_var, None)
|
||||
def get_group_names_by_role(role):
|
||||
if role == 'publisher':
|
||||
sub_roles = ('publisher_print', 'publisher_web', 'publisher_facebook')
|
||||
elif role.startswith('publisher_'):
|
||||
sub_roles = (role, )
|
||||
elif role == 'manager':
|
||||
sub_roles = ('manager_super', 'manager_w', 'manager_s', 'manager_m', 'manager_k', 'manager_b')
|
||||
elif role == 'manager_super':
|
||||
sub_roles = (role, )
|
||||
elif role.startswith('manager_'):
|
||||
sub_roles = ('manager_super', role)
|
||||
else:
|
||||
sub_roles = (role, )
|
||||
|
||||
group_names = []
|
||||
for sub_role in sub_roles:
|
||||
var_name = 'groups_{}'.format(sub_role)
|
||||
if hasattr(app_config.settings, var_name):
|
||||
group_names += getattr(app_config.settings, var_name)
|
||||
|
||||
return list(set(group_names))
|
||||
|
||||
|
||||
def get_users_by_role(role):
|
||||
users = []
|
||||
group_name = get_group_name_by_role(role)
|
||||
if group_name:
|
||||
users = get_group_members(group_name, ignore_missing=True)
|
||||
return users
|
||||
group_names = get_group_names_by_role(role)
|
||||
for group_name in group_names:
|
||||
users += get_group_members(group_name, ignore_missing=True)
|
||||
return list(set(users))
|
||||
|
||||
|
||||
def has_role(user, role):
|
||||
group_name = get_group_name_by_role(role)
|
||||
if group_name and user.groups.filter(name=group_name).count():
|
||||
group_names = get_group_names_by_role(role)
|
||||
if group_names and user.groups.filter(name__in=group_names).count():
|
||||
return True
|
||||
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()
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
from django.core.validators import RegexValidator
|
||||
|
||||
|
||||
AlphanumericValidator = RegexValidator(r'^[0-9a-zA-Z]*$', 'Only characters A-Z, a-z and digits 0-9 are allowed.')
|
||||
LowerAlphanumericValidator = RegexValidator(r'^[0-9a-z]*$', 'Only characters a-z and digits 0-9 are allowed.')
|
||||
AlphanumericValidator = RegexValidator(r'^[0-9a-zA-Z]*$', 'Only latin characters (A-Z, a-z)'
|
||||
' and digits (0-9) are allowed.')
|
||||
LowerAlphanumericValidator = RegexValidator(r'^[0-9a-z]*$', 'Only lower case latin characters (a-z)'
|
||||
' and digits (0-9) are allowed.')
|
||||
IdStringValidator = RegexValidator(r'^[0-9a-z_.-]*$', 'Only lower case latin characters (a-z),'
|
||||
' digits (0-9),'
|
||||
' dots (.), underscores (_) and hyphens (-) are allowed.')
|
||||
|
||||
@@ -31,20 +31,20 @@ class EventListView(generic.ListView):
|
||||
user = self.request.user
|
||||
if user.is_superuser:
|
||||
qs = self.model.objects.all()
|
||||
elif has_role(user, 'manage_all'):
|
||||
elif has_role(user, 'manager_super'):
|
||||
qs = self.model.objects.all()
|
||||
else:
|
||||
filter = Q(owner=user)
|
||||
|
||||
user_sports_list = list()
|
||||
for k in ('W', 'S', 'M', 'K', 'B'):
|
||||
role = 'manage_{}'.format(k.lower())
|
||||
role = 'manager_{}'.format(k.lower())
|
||||
if has_role(user, role):
|
||||
user_sports_list.append(k)
|
||||
|
||||
filter |= Q(sport__in=user_sports_list)
|
||||
|
||||
if has_role(user, 'publish') or has_role(user, 'publish_incremental'):
|
||||
if has_role(user, 'publisher'):
|
||||
filter |= Q(flags__status__code='accepted')
|
||||
|
||||
qs = self.model.objects.filter(filter)
|
||||
@@ -54,7 +54,7 @@ class EventListView(generic.ListView):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(EventListView, self).get_context_data(**kwargs)
|
||||
user = self.request.user
|
||||
context['has_permission_export'] = user.is_superuser or has_role(user, 'publish')
|
||||
context['has_permission_export'] = workflow.has_global_permission(user, 'export')
|
||||
return context
|
||||
|
||||
@method_decorator(login_required)
|
||||
@@ -112,8 +112,8 @@ class EventListExportView(generic.FormView):
|
||||
@method_decorator(login_required)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
user = request.user
|
||||
if not user.is_superuser and not has_role(user, 'publish'):
|
||||
raise PermissionDenied('publish')
|
||||
if not workflow.has_global_permission(user, 'export'):
|
||||
raise PermissionDenied('export')
|
||||
return super(EventListExportView, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
@@ -122,45 +122,7 @@ class EventPermissionMixin(object):
|
||||
|
||||
def has_permission(self, permission, obj):
|
||||
user = self.request.user
|
||||
|
||||
if user.is_superuser:
|
||||
return True
|
||||
|
||||
if permission == 'view':
|
||||
if user == obj.owner:
|
||||
return True
|
||||
if has_role(user, 'manage_all'):
|
||||
return True
|
||||
if has_role(user, 'manage_{}'.format(obj.sport.lower())):
|
||||
return True
|
||||
if has_role(user, 'publish_incremental') and obj.is_flagged('accepted'):
|
||||
return True
|
||||
if has_role(user, 'publish') and obj.is_flagged('accepted'):
|
||||
return True
|
||||
elif permission == 'submit':
|
||||
if user == obj.owner:
|
||||
return True
|
||||
elif permission == 'accept':
|
||||
if has_role(user, 'manage_all'):
|
||||
return True
|
||||
if has_role(user, 'manage_{}'.format(obj.sport.lower())):
|
||||
return True
|
||||
elif permission == 'publish':
|
||||
if has_role(user, 'publish') or has_role(user, 'publish_incremental'):
|
||||
return True
|
||||
elif permission == 'update':
|
||||
if not obj.is_flagged('submitted'):
|
||||
if user == obj.owner:
|
||||
return True
|
||||
elif not obj.is_flagged('accepted'):
|
||||
if has_role(user, 'manage_all'):
|
||||
return True
|
||||
if has_role(user, 'manage_{}'.format(obj.sport.lower())):
|
||||
return True
|
||||
elif has_role(user, 'publish') or has_role(user, 'publish_incremental'):
|
||||
return True
|
||||
|
||||
return False
|
||||
return workflow.has_object_permission(user, permission, obj)
|
||||
|
||||
def enforce_permission(self, obj):
|
||||
permission = self.permission
|
||||
@@ -197,13 +159,13 @@ class EventConfirmStatusView(EventPermissionMixin, generic.DetailView):
|
||||
status = kwargs.get('status')
|
||||
event = self.get_object()
|
||||
|
||||
if status == 'submitted':
|
||||
if status.startswith('submit'):
|
||||
if not self.has_permission('submit', event):
|
||||
raise PermissionDenied(status)
|
||||
elif status == 'accepted':
|
||||
elif status.startswith('accept'):
|
||||
if not self.has_permission('accept', event):
|
||||
raise PermissionDenied(status)
|
||||
elif status == 'publishing' or status == 'published':
|
||||
elif status.startswith('publish'):
|
||||
if not self.has_permission('publish', event):
|
||||
raise PermissionDenied(status)
|
||||
else:
|
||||
@@ -221,11 +183,11 @@ class EventConfirmStatusView(EventPermissionMixin, generic.DetailView):
|
||||
|
||||
event.confirm_status(status, request.user)
|
||||
|
||||
if status == 'submitted':
|
||||
if status.startswith('submit'):
|
||||
messages.success(request, _(u'Veranstaltung eingereicht.'))
|
||||
elif status == 'accepted':
|
||||
elif status.startswith('accept'):
|
||||
messages.success(request, _(u'Veranstaltung freigegeben.'))
|
||||
elif status == 'publishing' or status == 'published':
|
||||
elif status.startswith('publish'):
|
||||
messages.success(request, _(u'Veröffentlichung registriert.'))
|
||||
else:
|
||||
messages.success(request, _(u'Veranstaltungsstatus registriert.'))
|
||||
|
||||
@@ -4,9 +4,10 @@ from django.apps import apps
|
||||
from django.utils import timezone
|
||||
|
||||
from . import emails
|
||||
from .utils import get_users_by_role
|
||||
from .utils import get_users_by_role, has_role
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
today = datetime.date.today()
|
||||
|
||||
|
||||
class BasicWorkflow(object):
|
||||
@@ -18,16 +19,26 @@ class BasicWorkflow(object):
|
||||
valid = True
|
||||
return_code = 'OK'
|
||||
message = u'OK'
|
||||
if code == 'accepted':
|
||||
if code.startswith('accept'):
|
||||
if not event.is_flagged('submitted'):
|
||||
valid = False
|
||||
return_code = 'not-submitted'
|
||||
message = u'Event is not submitted.'
|
||||
elif code == 'publishing' or code == 'published':
|
||||
elif code.startswith('publishing'):
|
||||
if not event.is_flagged('accepted'):
|
||||
valid = False
|
||||
return_code = 'not-accepted'
|
||||
message = u'Event is not accepted.'
|
||||
elif code.startswith('published'):
|
||||
if event.planned_publication_date and event.planned_publication_date > today:
|
||||
valid = False
|
||||
return_code = 'not-due'
|
||||
message = u'Event is not due to publication.'
|
||||
elif not event.is_flagged('accepted'):
|
||||
valid = False
|
||||
return_code = 'not-accepted'
|
||||
message = u'Event is not accepted.'
|
||||
|
||||
if callback is not None:
|
||||
callback(valid, return_code, message, *args, **kwargs)
|
||||
return valid, return_code, message
|
||||
@@ -37,7 +48,6 @@ class BasicWorkflow(object):
|
||||
if not event.id:
|
||||
return
|
||||
|
||||
today = datetime.date.today()
|
||||
midnight = datetime.time(00, 00, 00)
|
||||
|
||||
if code in (None, 'draft'):
|
||||
@@ -53,18 +63,86 @@ class BasicWorkflow(object):
|
||||
event.set_next_number()
|
||||
logger.info('Setting number on Event %s', event)
|
||||
|
||||
if code in (None, 'published', 'publishing'):
|
||||
# Check if event with publishing flag should now have a published flag also.
|
||||
if (event.flags.filter(status__code='publishing').exists() and
|
||||
not event.flags.filter(status__code='published').exists()):
|
||||
if not event.planned_publication_date:
|
||||
logger.info('Detected published state of Event %s', event)
|
||||
flag = event.flags.filter(status__code='publishing').last()
|
||||
event.set_flag(status='published', timestamp=flag.timestamp)
|
||||
elif event.planned_publication_date <= today:
|
||||
logger.info('Detected published state of Event %s', event)
|
||||
timestamp = timezone.make_aware(datetime.datetime.combine(event.planned_publication_date, midnight))
|
||||
event.set_flag(status='published', timestamp=timestamp)
|
||||
if code in (None,
|
||||
'publishing_facebook',
|
||||
'publishing_web',
|
||||
'publishing',
|
||||
'published_facebook',
|
||||
'published_web',
|
||||
'published'):
|
||||
|
||||
if not event.flags.filter(status__code='published').exists():
|
||||
# Event is not fully published yet.
|
||||
|
||||
# We use some querysets, just to make code more readable.
|
||||
pub_flags = event.flags.filter(status__code__in=('publishing_facebook',
|
||||
'publishing_web',
|
||||
'publishing',
|
||||
'published_facebook',
|
||||
'published_web',
|
||||
'published')).order_by('timestamp')
|
||||
|
||||
publishing_web = pub_flags.filter(status__code='publishing_web')
|
||||
publishing_facebook = pub_flags.filter(status__code='publishing_facebook')
|
||||
published_web = pub_flags.filter(status__code='published_web')
|
||||
published_facebook = pub_flags.filter(status__code='published_facebook')
|
||||
|
||||
if not event.planned_publication_date or event.planned_publication_date <= today:
|
||||
# Event is due to be published.
|
||||
|
||||
# Timestamp of the detected action flag. No very good.
|
||||
if event.planned_publication_date:
|
||||
timestamp = timezone.make_aware(datetime.datetime.combine(
|
||||
event.planned_publication_date,
|
||||
midnight)
|
||||
)
|
||||
else:
|
||||
timestamp = None
|
||||
|
||||
if event.flags.filter(status__code='publishing').exists():
|
||||
# The publishers have confirmed the publications date,
|
||||
# so we can flag the complete publication.
|
||||
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)
|
||||
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
|
||||
# so we can flag the complete published state.
|
||||
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)
|
||||
else:
|
||||
if publishing_web.exists() and not published_web.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_web').last().timestamp
|
||||
logger.info('Detected published_web state of Event %s', event)
|
||||
event.set_flag(status='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)
|
||||
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)
|
||||
elif publishing_web.exists() and publishing_facebook.exists():
|
||||
# Event is not due to be published yet,
|
||||
# but all publishers have confirmed the publication date,
|
||||
# so we set a general publishing flag.
|
||||
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)
|
||||
|
||||
if code in (None, 'expired'):
|
||||
# Check if event is expired now and need a expired flag.
|
||||
@@ -88,6 +166,26 @@ class BasicWorkflow(object):
|
||||
timestamp = timezone.make_aware(datetime.datetime.combine(expired_at, midnight))
|
||||
event.set_flag(status='expired', timestamp=timestamp)
|
||||
|
||||
@classmethod
|
||||
def get_status_flags(cls, event):
|
||||
cls.status_code_update(event)
|
||||
last_flag = event.flags.last()
|
||||
if not last_flag:
|
||||
#last_flag = event.set_flag('void')
|
||||
return []
|
||||
flags = [last_flag]
|
||||
|
||||
last_status = last_flag.status
|
||||
if last_status.code.startswith('publishing_'):
|
||||
flags += event.flags.filter(status__code='accepted')
|
||||
elif last_status.code.startswith('published_'):
|
||||
if event.is_flagged('publishing'):
|
||||
flags += event.flags.filter(status__code='publishing')
|
||||
else:
|
||||
flags += event.flags.filter(status__code='accepted')
|
||||
|
||||
return flags
|
||||
|
||||
@classmethod
|
||||
def get_number(cls, event):
|
||||
if event.number and event.flags.filter(status__code='accepted').exists():
|
||||
@@ -99,25 +197,50 @@ class BasicWorkflow(object):
|
||||
# Permissions
|
||||
#
|
||||
@classmethod
|
||||
def has_permission(cls, event, user, permission):
|
||||
raise NotImplementedError('not ready yet')
|
||||
def has_global_permission(cls, user, permission):
|
||||
if user.is_superuser:
|
||||
return True
|
||||
|
||||
if permission == 'export':
|
||||
return has_role(user, 'publisher')
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def has_object_permission(cls, user, permission, obj):
|
||||
if user.is_superuser:
|
||||
return True
|
||||
|
||||
if permission == 'view':
|
||||
if user == event.owner:
|
||||
if user == obj.owner:
|
||||
return True
|
||||
if has_role(user, 'manager_super'):
|
||||
return True
|
||||
if has_role(user, 'manager_{}'.format(obj.sport.lower())):
|
||||
return True
|
||||
if has_role(user, 'publisher') and obj.is_flagged('accepted'):
|
||||
return True
|
||||
raise Exception('must check roles')
|
||||
elif permission == 'submit':
|
||||
if user == event.owner:
|
||||
if user == obj.owner:
|
||||
return True
|
||||
elif permission == 'accept':
|
||||
raise Exception('must check roles')
|
||||
if has_role(user, 'manager_super'):
|
||||
return True
|
||||
if has_role(user, 'manager_{}'.format(obj.sport.lower())):
|
||||
return True
|
||||
elif permission == 'publish':
|
||||
raise Exception('must check roles')
|
||||
if has_role(user, 'publisher'):
|
||||
return True
|
||||
elif permission == 'update':
|
||||
raise Exception('must check roles')
|
||||
if not obj.is_flagged('submitted'):
|
||||
if user == obj.owner:
|
||||
return True
|
||||
elif not obj.is_flagged('accepted'):
|
||||
if has_role(user, 'manager_super'):
|
||||
return True
|
||||
if has_role(user, 'manager_{}'.format(obj.sport.lower())):
|
||||
return True
|
||||
elif has_role(user, 'publisher'):
|
||||
return True
|
||||
return False
|
||||
|
||||
#
|
||||
@@ -142,11 +265,12 @@ class BasicWorkflow(object):
|
||||
recipients = [event.owner]
|
||||
if event.is_flagged('submitted'):
|
||||
# If the event is already submitted, add managers to the recipients.
|
||||
recipients += get_users_by_role('manage_all')
|
||||
recipients += get_users_by_role('manage_{}'.format(event.sport.lower()))
|
||||
recipients += get_users_by_role('manager_super')
|
||||
recipients += get_users_by_role('manager_{}'.format(event.sport.lower()))
|
||||
if event.is_flagged('accepted'):
|
||||
# If the event is already published, add publishers to the recipients.
|
||||
recipients += get_users_by_role('publish_incremental')
|
||||
recipients += get_users_by_role('publisher_web')
|
||||
recipients += get_users_by_role('publisher_facebook')
|
||||
|
||||
for recipient in recipients:
|
||||
if recipient.email and recipient.email != updater.email:
|
||||
@@ -172,13 +296,13 @@ class BasicWorkflow(object):
|
||||
# Inform managers that they have to accept the event.
|
||||
# Also create OneClickActions for all of them and add the link to the mail,
|
||||
# so they can accept the event with a click into the mail.
|
||||
recipients = get_users_by_role('manage_all')
|
||||
recipients += get_users_by_role('manage_{}'.format(event.sport.lower()))
|
||||
recipients = get_users_by_role('manager_super')
|
||||
recipients += get_users_by_role('manager_{}'.format(event.sport.lower()))
|
||||
OneClickAction = app_config.get_model('OneClickAction')
|
||||
for recipient in recipients:
|
||||
if recipient.email:
|
||||
action = OneClickAction(command='EA')
|
||||
action.parameters = '{event},{user}'.format(event=event.id, user=recipient.id)
|
||||
action = OneClickAction(command='EVENT_STATUS_UPDATE')
|
||||
action.parameters = '{event},accepted,{user}'.format(event=event.id, user=recipient.id)
|
||||
action.save()
|
||||
email = emails.EventToAcceptMail(recipient=recipient, event=event, accept_action=action)
|
||||
email.send()
|
||||
@@ -192,15 +316,35 @@ class BasicWorkflow(object):
|
||||
# Inform publishers that they have to publish the event.
|
||||
# Also create OneClickActions for all of them and add the link to the mail,
|
||||
# so they can confirm the publication with a click into the mail.
|
||||
recipients = get_users_by_role('publish_incremental')
|
||||
|
||||
# Website
|
||||
recipients = get_users_by_role('publisher_web')
|
||||
status_code = 'publishing_web'
|
||||
OneClickAction = app_config.get_model('OneClickAction')
|
||||
for recipient in recipients:
|
||||
if recipient.email:
|
||||
action = OneClickAction(command='EP')
|
||||
action.parameters = '{event},{user}'.format(event=event.id, user=recipient.id)
|
||||
action = OneClickAction(command='EVENT_STATUS_UPDATE')
|
||||
action.parameters = '{event},{status_code},{user}'.format(event=event.id,
|
||||
status_code=status_code,
|
||||
user=recipient.id)
|
||||
action.save()
|
||||
email = emails.EventToPublishMail(recipient=recipient, event=event, editor=updater,
|
||||
confirm_publication_action=action)
|
||||
email = emails.EventToPublishWebMail(recipient=recipient, event=event, editor=updater,
|
||||
confirm_publication_action=action)
|
||||
email.send()
|
||||
|
||||
# Facebook
|
||||
recipients = get_users_by_role('publisher_facebook')
|
||||
status_code = 'publishing_facebook'
|
||||
OneClickAction = app_config.get_model('OneClickAction')
|
||||
for recipient in recipients:
|
||||
if recipient.email:
|
||||
action = OneClickAction(command='EVENT_STATUS_UPDATE')
|
||||
action.parameters = '{event},{status_code},{user}'.format(event=event.id,
|
||||
status_code=status_code,
|
||||
user=recipient.id)
|
||||
action.save()
|
||||
email = emails.EventToPublishFacebookMail(recipient=recipient, event=event, editor=updater,
|
||||
confirm_publication_action=action)
|
||||
email.send()
|
||||
|
||||
#
|
||||
@@ -215,8 +359,6 @@ class BasicWorkflow(object):
|
||||
else:
|
||||
publication_deadline = first_day - datetime.timedelta(app_config.settings.publish_before_begin_days)
|
||||
|
||||
today = datetime.date.today()
|
||||
|
||||
for year in (today.year, today.year + 1):
|
||||
for issue in app_config.settings.publish_issues:
|
||||
if not ('issue' in issue and 'release' in issue and 'deadline' in issue):
|
||||
|
||||
Reference in New Issue
Block a user