Support for One-Click-Actions.
This commit is contained in:
@@ -1,9 +1,15 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Event
|
||||
from .models import Event, OneClickAction
|
||||
|
||||
|
||||
class EventAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
class OneClickActionAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
admin.site.register(Event, EventAdmin)
|
||||
admin.site.register(OneClickAction, OneClickActionAdmin)
|
||||
|
||||
@@ -87,9 +87,7 @@ class AbstractEventMail(AbstractMail):
|
||||
|
||||
def _get_context_data(self, extra_context=None):
|
||||
context = super(AbstractEventMail, self)._get_context_data(extra_context=extra_context)
|
||||
context.update({
|
||||
'recipient': self._recipient,
|
||||
})
|
||||
context['recipient'] = self._recipient
|
||||
context.update(self._event.get_template_context())
|
||||
return context
|
||||
|
||||
@@ -106,6 +104,15 @@ class NewEventMail(AbstractEventMail):
|
||||
class EventToAcceptMail(AbstractEventMail):
|
||||
_template_name = 'dav_events/emails/event_to_accept.txt'
|
||||
|
||||
def __init__(self, accept_action=None, *args, **kwargs):
|
||||
self._accept_action = accept_action
|
||||
super(EventToAcceptMail, self).__init__(*args, **kwargs)
|
||||
|
||||
def _get_context_data(self, extra_context=None):
|
||||
context = super(EventToAcceptMail, self)._get_context_data(extra_context=extra_context)
|
||||
context['accept_url'] = self._accept_action.get_absolute_url()
|
||||
return context
|
||||
|
||||
def _get_subject(self, **kwargs):
|
||||
s = super(EventToAcceptMail, self)._get_subject(**kwargs)
|
||||
s += u' Neue Veranstaltung freigeben'
|
||||
|
||||
25
dav_events/migrations/0006_oneclickaction.py
Normal file
25
dav_events/migrations/0006_oneclickaction.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.9 on 2018-01-29 08:47
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dav_events', '0005_auto_20180124_1725'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='OneClickAction',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('done', models.BooleanField(default=False)),
|
||||
('done_at', models.DateTimeField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
]
|
||||
31
dav_events/migrations/0007_auto_20180129_1117.py
Normal file
31
dav_events/migrations/0007_auto_20180129_1117.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.9 on 2018-01-29 11:17
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dav_events', '0006_oneclickaction'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='oneclickaction',
|
||||
name='allow_repeat',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='oneclickaction',
|
||||
name='command',
|
||||
field=models.CharField(choices=[(b'EA', b'accept event'), (b'EP', b'mark event as published')], default='EA', max_length=2),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='oneclickaction',
|
||||
name='parameters',
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
]
|
||||
24
dav_events/migrations/0008_auto_20180129_1355.py
Normal file
24
dav_events/migrations/0008_auto_20180129_1355.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.9 on 2018-01-29 13:55
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dav_events', '0007_auto_20180129_1117'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='oneclickaction',
|
||||
options={'verbose_name': 'One-Click-Action'},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='oneclickaction',
|
||||
name='command',
|
||||
field=models.CharField(choices=[(b'EA', b'accept event'), (b'EP', b'mark event as published'), (b'EL', b'login and go to event list')], max_length=2),
|
||||
),
|
||||
]
|
||||
@@ -11,7 +11,7 @@ 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.utils.translation import get_language, ugettext, ugettext_lazy as _
|
||||
from django_countries.fields import CountryField
|
||||
|
||||
from . import choices
|
||||
@@ -167,7 +167,7 @@ class Event(models.Model):
|
||||
return reverse('dav_events:event_detail', kwargs={'pk': self.pk})
|
||||
|
||||
def save(self, **kwargs):
|
||||
emails_to_send = []
|
||||
creating = False
|
||||
|
||||
if not self.id:
|
||||
user_model = get_user_model()
|
||||
@@ -180,18 +180,26 @@ class Event(models.Model):
|
||||
email=self.trainer_email,
|
||||
)
|
||||
owner.save()
|
||||
logger.info('Owner created: %s', owner.username)
|
||||
|
||||
self.owner = owner
|
||||
creating = True
|
||||
|
||||
super(Event, self).save(**kwargs)
|
||||
|
||||
if creating:
|
||||
logger.info('Event created: %s', self)
|
||||
|
||||
managers = get_users_by_role('manage_all')
|
||||
managers += get_users_by_role('manage_{}'.format(self.sport.lower()))
|
||||
for user in managers:
|
||||
emails_to_send.append(emails.EventToAcceptMail(recipient=user, event=self))
|
||||
action = OneClickAction(command='EA')
|
||||
action.parameters = '{event},{user}'.format(event=self.id, user=user.id)
|
||||
action.save()
|
||||
email = emails.EventToAcceptMail(recipient=user, event=self, accept_action=action)
|
||||
email.send()
|
||||
|
||||
emails_to_send.append(emails.NewEventMail(recipient=owner, event=self))
|
||||
|
||||
super(Event, self).save(**kwargs)
|
||||
for email in emails_to_send:
|
||||
email = emails.NewEventMail(recipient=self.owner, event=self)
|
||||
email.send()
|
||||
|
||||
def accept(self, user=None):
|
||||
@@ -203,6 +211,7 @@ class Event(models.Model):
|
||||
if user:
|
||||
self.accepted_by = user
|
||||
self.save()
|
||||
logger.info('Event is accepted: %s', self)
|
||||
|
||||
publishers = get_users_by_role('publish_incremental')
|
||||
for user in publishers:
|
||||
@@ -343,8 +352,106 @@ class Event(models.Model):
|
||||
return template.render(self.get_template_context())
|
||||
|
||||
|
||||
# class OneClickAction(models.Model):
|
||||
# id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
# caller = models.ForeignKey(settings.AUTH_USER_MODEL,
|
||||
# null=True,
|
||||
# related_name='+')
|
||||
class OneClickAction(models.Model):
|
||||
COMMANDS = (
|
||||
('EA', 'accept event'),
|
||||
('EP', 'mark event as published'),
|
||||
('EL', 'login and go to event list')
|
||||
)
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
allow_repeat = models.BooleanField(default=False)
|
||||
|
||||
done = models.BooleanField(default=False)
|
||||
done_at = models.DateTimeField(blank=True,
|
||||
null=True)
|
||||
|
||||
command = models.CharField(max_length=2, choices=COMMANDS)
|
||||
|
||||
parameters = models.TextField(blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'One-Click-Action')
|
||||
|
||||
def __unicode__(self):
|
||||
s = u'{command}({parameters}) - {description}'.format(description=self.get_command_display(),
|
||||
command=self.command,
|
||||
parameters=self.parameters)
|
||||
if self.done and not self.allow_repeat:
|
||||
s += u' - done'
|
||||
return s
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('dav_events:action_run', kwargs={'pk': self.pk})
|
||||
|
||||
def run(self):
|
||||
result = {}
|
||||
if self.done and not self.allow_repeat:
|
||||
result['context'] = {
|
||||
'status': 'warning',
|
||||
'message': ugettext(u'Diese Aktion hast du bereits ausgeführt.'),
|
||||
}
|
||||
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)
|
||||
number = event.accept(user)
|
||||
if number:
|
||||
status = 'success'
|
||||
message = ugettext(u'Veranstaltung freigegeben.')
|
||||
text = unicode(event)
|
||||
else:
|
||||
status = 'info'
|
||||
message = (ugettext(u'Veranstaltung wurde bereits von %(fullname)s freigegeben.') %
|
||||
{'fullname': event.accepted_by.get_full_name()})
|
||||
text = unicode(event)
|
||||
text += u'\n'
|
||||
text += (ugettext(u'Freigegeben am: %(date)s') %
|
||||
{'date': event.accepted_at.strftime('%d.%m.%Y %H:%M:%S')})
|
||||
|
||||
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':
|
||||
result['context'] = {
|
||||
'status': 'warning',
|
||||
'message': ugettext(u'Funktion noch nicht verfügbar.'),
|
||||
}
|
||||
elif self.command == 'EL':
|
||||
try:
|
||||
user_id = self.parameters
|
||||
user = get_user_model().objects.get(id=user_id)
|
||||
url = reverse('dav_events:event_list')
|
||||
result['location'] = url
|
||||
result['login'] = user
|
||||
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',
|
||||
'message': ugettext(u'Invalid Command. Code on fire!'),
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -5,5 +5,7 @@ ein Tourenreferent hat deine Veranstaltung freigegeben:
|
||||
-----
|
||||
{{ event.render_as_text }}-----
|
||||
|
||||
URL: {{ base_url }}{{ event.get_absolute_url }}
|
||||
Link zur Veranstaltung:
|
||||
{{ base_url }}{{ event.get_absolute_url }}
|
||||
|
||||
Die Redaktion wurden informiert, um deine Veranstaltung zu veröffentlichen.
|
||||
|
||||
@@ -5,5 +5,8 @@ Hallo Tourenreferenten,
|
||||
-----
|
||||
{{ event.render_as_text }}-----
|
||||
|
||||
Ihr könnt die Veranstaltung unter folgender URL freigeben:
|
||||
Über den folgenden Link könnt ihr die Veranstaltung unmittelbar freigeben:
|
||||
{{ base_url }}{{ accept_url }}
|
||||
|
||||
Der folgende Link führt euch zur Veranstaltung:
|
||||
{{ base_url }}{{ event.get_absolute_url }}
|
||||
@@ -5,5 +5,7 @@ du hast die folgende Veranstaltung angelegt:
|
||||
-----
|
||||
{{ event.render_as_text }}-----
|
||||
|
||||
URL: {{ base_url }}{{ event.get_absolute_url }}
|
||||
Link zur Veranstaltung:
|
||||
{{ base_url }}{{ event.get_absolute_url }}
|
||||
|
||||
Die entsprechenden Referenten wurden informiert, um deine Veranstaltung frei zu geben.
|
||||
19
dav_events/templates/dav_events/oneclickaction.html
Normal file
19
dav_events/templates/dav_events/oneclickaction.html
Normal file
@@ -0,0 +1,19 @@
|
||||
{% extends 'dav_events/base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page-container %}
|
||||
{% if text %}
|
||||
<div class="panel panel-{{ status }}">
|
||||
<div class="panel-heading">
|
||||
{{ message }}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{ text|linebreaksbr }}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-{{ status }}" role="alert">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock page-container %}
|
||||
@@ -13,4 +13,6 @@ urlpatterns = [
|
||||
url(r'^events/(?P<pk>\d+)/accept', views.events.EventAcceptView.as_view(), name='event_accept'),
|
||||
url(r'^events/(?P<pk>\d+)/edit', views.events.EventUpdateView.as_view(), name='event_update'),
|
||||
url(r'^events/(?P<pk>\d+)/', views.events.EventDetailView.as_view(), name='event_detail'),
|
||||
url(r'^action/(?P<pk>[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12})/',
|
||||
views.actions.OneClickActionRunView.as_view(), name='action_run'),
|
||||
]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from . import base
|
||||
from . import auth
|
||||
from . import events
|
||||
from . import actions
|
||||
|
||||
34
dav_events/views/actions.py
Normal file
34
dav_events/views/actions.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import logging
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import login
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.views import generic
|
||||
|
||||
from .. import models
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OneClickActionRunView(generic.DetailView):
|
||||
model = models.OneClickAction
|
||||
template_name = 'dav_events/oneclickaction.html'
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
result = self.object.run()
|
||||
|
||||
if 'login' in result:
|
||||
user = result['login']
|
||||
login(self.request, user)
|
||||
logger.info('Logged in via OneClickAction: %s', user.username)
|
||||
messages.success(self.request,
|
||||
_(u'Benutzer angemeldet: %(username)s') % {'username': user.username})
|
||||
|
||||
if 'location' in result:
|
||||
return HttpResponseRedirect(result['location'])
|
||||
|
||||
context = self.get_context_data(object=self.object)
|
||||
if 'context' in result:
|
||||
context.update(result['context'])
|
||||
return self.render_to_response(context)
|
||||
Reference in New Issue
Block a user