Commit 6c17201c authored by Thom Wiggers's avatar Thom Wiggers 📐
Browse files

Revert "Merge branch 'import_events' into 'master'"

This reverts merge request !124
parent a775ce9a
from django import forms
from django.utils.translation import get_language, ugettext_lazy as _
from django.utils.translation import ugettext_lazy as _
from .models import RegistrationInformationField
class RegistrationInformationFieldForm(forms.ModelForm):
order = forms.IntegerField(label=_('order'), initial=0)
class Meta:
......@@ -35,10 +36,8 @@ class FieldsForm(forms.Form):
elif field.type == RegistrationInformationField.TEXT_FIELD:
self.fields[key] = forms.CharField()
self.fields[key].label = getattr(field, '{}_{}'.format(
'name', get_language()))
self.fields[key].help_text = getattr(field, '{}_{}'.format(
'description', get_language()))
self.fields[key].label = field.name
self.fields[key].help_text = field.description
self.fields[key].initial = information_field['value']
if not field.type == RegistrationInformationField.BOOLEAN_FIELD:
self.fields[key].required = field.required
......
import re
import json
import requests
from django.contrib.auth.models import User
from datetime import datetime
from django.core.management.base import BaseCommand
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils import timezone
import events.models as events_models
import members.models as members_models
FIELD_DATA_TYPES = {
'0': events_models.RegistrationInformationField.TEXT_FIELD,
'1': events_models.RegistrationInformationField.INTEGER_FIELD,
'2': events_models.RegistrationInformationField.BOOLEAN_FIELD,
}
def naive_to_aware(date_string):
"""Convert string of form '%Y-%m-%d %H:%M:%S'
to timezone aware datetime object"""
naive_datetime = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S')
return timezone.get_current_timezone().localize(naive_datetime)
class Command(BaseCommand):
help = 'Migrate the events from the old website.'
def handle(self, *args, **options):
if not settings.EVENTS_MIGRATION_KEY:
raise ImproperlyConfigured('EVENTS_MIGRATION_KEY not specified')
events_api_url = 'https://thalia.nu/events/api/?apikey={}'.format(
settings.EVENTS_MIGRATION_KEY)
print('[*]Getting events json data')
try:
response = requests.get(events_api_url,
headers={'User-Agent': 'The Donald'})
except requests.RequestException:
print('[!]Could not get {}'.format(events_api_url))
return
try:
data = response.json()
except json.decoder.JSONDecodeError:
print('[!]No json data found')
return
event_fields_translations = {
# name in data : name in model
'title': 'title',
'description': 'description',
'location': 'location',
'start_date': 'start',
'end_date': 'end',
'member_price': 'price',
'thalia_costs': 'cost',
'begin_registration': 'registration_start',
'end_registration': 'registration_end',
'end_cancel': 'cancel_deadline',
'registration_not_needed_message': 'no_registration_message',
}
activity_map = {}
registration_map = {}
information_field_map = {}
print('[*]Parsing event data.')
# Event
for event_data in data['events']:
new_event = events_models.Event(
published=bool(int(event_data['public'])),
max_participants=int(event_data['registration_limit']),
)
for concrete_field in event_fields_translations:
django_field = event_fields_translations[concrete_field]
concrete_data = event_data[concrete_field]
# MultilingualField
if django_field in (
'title', 'description', 'location',
'no_registration_message'):
for language_code in ('en', 'nl'):
django_multilingualfield = '{}_{}'.format(
django_field, language_code)
if not hasattr(new_event, django_multilingualfield):
print('[!]Could neither find {} nor {}'.format(
django_field, django_multilingualfield))
return
setattr(new_event, django_multilingualfield,
concrete_data)
# DateTimeField
elif concrete_data and django_field in (
'start', 'end', 'registration_start',
'registration_end',
'cancel_deadline'):
setattr(new_event, django_field,
naive_to_aware(concrete_data))
# DecimalField
elif django_field in ('price', 'cost'):
if re.match(r'[-+]?\d*\.?\d+$', concrete_data):
setattr(new_event, django_field, float(concrete_data))
else:
# TODO: is 0 the right value?
setattr(new_event, django_field, 0)
new_event.save()
activity_map[event_data['id']] = new_event.pk
print('[*]Parsing registration field data.')
# RegistrationInformationField
for field_data in data['extra_fields']:
new_registration_information_field = \
events_models.RegistrationInformationField(
# TODO: UGLY AF
name_en=field_data['field_name'],
name_nl=field_data['field_name'],
description_en=field_data['field_explanation'],
description_nl=field_data['field_explanation'],
type=FIELD_DATA_TYPES[field_data['data_type']],
required=True,
event=events_models.Event.objects.get(
pk=activity_map[field_data['activity_id']]
),
)
new_registration_information_field.save()
information_field_map[field_data['field_id']] = \
new_registration_information_field.pk
print('[*]Parsing registration data.')
# Registration
for registration_data in data['registrations']:
new_registration = events_models.Registration(
name=registration_data['name'],
date=naive_to_aware(registration_data['date']),
paid=bool(registration_data['paid']),
event=events_models.Event.objects.get(
pk=activity_map[registration_data['activity_id']]
),
)
username = registration_data['username']
if registration_data['username'] and User.objects.filter(
username=username).exists():
registration_user = User.objects.get(username=username)
new_registration.member = members_models.Member.objects.get(
user=registration_user)
cancelled_date = registration_data['canceled']
if cancelled_date:
new_registration.cancelled_date = naive_to_aware(
cancelled_date)
new_registration.save()
registration_map[registration_data['id']] = new_registration.pk
print('[*]Parsing registration field info data.')
# fields info
for field_info_data in data['extra_info']:
registration_field = events_models.RegistrationInformationField.\
objects.get(
pk=information_field_map[field_info_data['field_id']]
)
parameters = {
'registration': events_models.Registration.objects.get(
pk=registration_map[field_info_data['registration_id']]),
'field': registration_field,
}
if registration_field.type == events_models.\
RegistrationInformationField.TEXT_FIELD:
new_registration_information = events_models. \
TextRegistrationInformation(
value=field_info_data['value'],
**parameters
)
elif registration_field.type == events_models.\
RegistrationInformationField.BOOLEAN_FIELD:
value = False
if value and bool(int(field_info_data['value'])):
value = True
new_registration_information = \
events_models.BooleanRegistrationInformation(
value=value,
**parameters)
# registration_field.type == INTEGER_FIELD:
else:
new_registration_information = \
events_models.IntegerRegistrationInformation(
value=field_info_data['value'] or 0,
**parameters)
new_registration_information.save()
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-10-21 17:28
# Generated by Django 1.10 on 2016-08-13 13:33
from __future__ import unicode_literals
import django.core.validators
......@@ -12,8 +12,8 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('members', '0010_merge_20160907_2042'),
('activemembers', '0011_auto_20161005_2141'),
('members', '0004_auto_20160805_1435'),
('activemembers', '0004_auto_20160727_2253'),
]
operations = [
......@@ -32,25 +32,21 @@ class Migration(migrations.Migration):
name='Event',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100, verbose_name='title')),
('description', models.TextField(verbose_name='description')),
('start', models.DateTimeField(verbose_name='start time')),
('end', models.DateTimeField(verbose_name='end time')),
('registration_start', models.DateTimeField(blank=True, null=True, verbose_name='registration start')),
('registration_end', models.DateTimeField(blank=True, null=True, verbose_name='registration end')),
('cancel_deadline', models.DateTimeField(blank=True, null=True, verbose_name='cancel deadline')),
('location', models.CharField(max_length=255, verbose_name='location')),
('map_location', models.CharField(help_text='Location of Huygens: Heyendaalseweg 135, Nijmegen. Not shown as text!!', max_length=255, verbose_name='location for minimap')),
('price', models.DecimalField(decimal_places=2, default=0, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='price')),
('cost', models.DecimalField(decimal_places=2, default=0, help_text='Actual cost of event.', max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='cost')),
('max_participants', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='maximum number of participants')),
('registration_required', models.BooleanField(default=False, verbose_name='registration required')),
('no_registration_message', models.CharField(blank=True, help_text='Default: No registration required', max_length=200, null=True, verbose_name='message when there is no registration')),
('published', models.BooleanField(default=False, verbose_name='published')),
('no_registration_message_en', models.CharField(blank=True, help_text='Default: No registration required', max_length=200, null=True, verbose_name='message when there is no registration (EN)')),
('no_registration_message_nl', models.CharField(blank=True, help_text='Default: No registration required', max_length=200, null=True, verbose_name='message when there is no registration (NL)')),
('title_en', models.CharField(max_length=100, verbose_name='title (EN)')),
('title_nl', models.CharField(max_length=100, verbose_name='title (NL)')),
('location_en', models.CharField(max_length=255, verbose_name='location (EN)')),
('location_nl', models.CharField(max_length=255, verbose_name='location (NL)')),
('description_en', models.TextField(verbose_name='description (EN)')),
('description_nl', models.TextField(verbose_name='description (NL)')),
('organiser', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='activemembers.Committee', verbose_name='organiser')),
('organiser', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='activemembers.Committee')),
],
options={
'ordering': ('-start',),
......@@ -74,8 +70,8 @@ class Migration(migrations.Migration):
('name', models.CharField(blank=True, help_text='Use this for non-members', max_length=50, null=True, verbose_name='name')),
('date', models.DateTimeField(auto_now_add=True, verbose_name='registration date')),
('date_cancelled', models.DateTimeField(blank=True, null=True, verbose_name='cancellation date')),
('present', models.BooleanField(default=False, verbose_name='present')),
('paid', models.BooleanField(default=False, verbose_name='paid')),
('present', models.BooleanField(default=False, verbose_name='Present')),
('paid', models.BooleanField(default=False, verbose_name='Paid')),
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.Event')),
('member', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='members.Member')),
],
......@@ -87,12 +83,9 @@ class Migration(migrations.Migration):
name='RegistrationInformationField',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('type', models.CharField(choices=[('boolean', 'Checkbox'), ('text', 'Text'), ('integer', 'Integer')], max_length=10, verbose_name='field type')),
('required', models.BooleanField(verbose_name='required')),
('name_en', models.CharField(max_length=100, verbose_name='field name (EN)')),
('name_nl', models.CharField(max_length=100, verbose_name='field name (NL)')),
('description_en', models.TextField(blank=True, null=True, verbose_name='description (EN)')),
('description_nl', models.TextField(blank=True, null=True, verbose_name='description (NL)')),
('type', models.CharField(choices=[('checkbox', 'checkbox'), ('charfield', 'text field'), ('intfield', 'integer field')], max_length=10, verbose_name='field type')),
('name', models.CharField(max_length=100, verbose_name='field name')),
('description', models.TextField(blank=True, null=True, verbose_name='description')),
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.Event')),
],
),
......
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-08-13 14:20
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('events', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='event',
name='organiser',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='activemembers.Committee'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-08-13 14:21
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('events', '0002_auto_20160813_1620'),
]
operations = [
migrations.RemoveField(
model_name='event',
name='registration_required',
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-08-31 19:39
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0003_remove_event_registration_required'),
]
operations = [
migrations.AddField(
model_name='event',
name='cancel_deadline',
field=models.DateTimeField(blank=True, null=True, verbose_name='cancel deadline'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-09-14 19:54
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('events', '0004_event_cancel_deadline'),
]
operations = [
migrations.RemoveField(
model_name='event',
name='location',
),
migrations.RemoveField(
model_name='event',
name='no_registration_message',
),
migrations.RemoveField(
model_name='event',
name='title',
),
migrations.AddField(
model_name='event',
name='location_en',
field=models.CharField(default='', max_length=255, verbose_name='location (EN)'),
preserve_default=False,
),
migrations.AddField(
model_name='event',
name='location_nl',
field=models.CharField(default='', max_length=255, verbose_name='location (NL)'),
preserve_default=False,
),
migrations.AddField(
model_name='event',
name='no_registration_message_en',
field=models.CharField(blank=True, help_text='Default: No registration required', max_length=200, null=True, verbose_name='message when there is no registration (EN)'),
),
migrations.AddField(
model_name='event',
name='no_registration_message_nl',
field=models.CharField(blank=True, help_text='Default: No registration required', max_length=200, null=True, verbose_name='message when there is no registration (NL)'),
),
migrations.AddField(
model_name='event',
name='title_en',
field=models.CharField(default='', max_length=100, verbose_name='title (EN)'),
preserve_default=False,
),
migrations.AddField(
model_name='event',
name='title_nl',
field=models.CharField(default='', max_length=100, verbose_name='title (NL)'),
preserve_default=False,
),
migrations.AlterField(
model_name='event',
name='organiser',
field=models.ForeignKey(null=True,
on_delete=django.db.models.deletion.SET_NULL, to='activemembers.Committee', verbose_name='organiser'),
),
migrations.AlterField(
model_name='registration',
name='paid',
field=models.BooleanField(default=False, verbose_name='paid'),
),
migrations.AlterField(
model_name='registration',
name='present',
field=models.BooleanField(default=False, verbose_name='present'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-09-21 20:01
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0005_auto_20160914_2154'),
]
operations = [
migrations.RemoveField(
model_name='event',
name='description',
),
migrations.AddField(
model_name='event',
name='description_en',
field=models.TextField(default='', verbose_name='description (EN)'),
preserve_default=False,
),
migrations.AddField(
model_name='event',
name='description_nl',
field=models.TextField(default='', verbose_name='description (NL)'),
preserve_default=False,
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-10-09 21:52
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0006_auto_20160921_2201'),
]
operations = [
migrations.AddField(
model_name='registrationinformationfield',
name='required',
field=models.BooleanField(default=True, verbose_name='required'),
preserve_default=False,
),
migrations.AlterField(
model_name='registrationinformationfield',
name='type',
field=models.CharField(choices=[('boolean', 'Checkbox'), ('text', 'Text'), ('integer', 'Integer')], max_length=10, verbose_name='field type'),
),
]
......@@ -118,8 +118,7 @@ class Event(models.Model, metaclass=ModelTranslateMeta):
return self.registrationinformationfield_set.count() > 0
def reached_participants_limit(self):
return (self.max_participants is not None and
self.max_participants <= self.registration_set.count())
return self.max_participants <= self.registration_set.count()
@property
def status(self):
......@@ -188,7 +187,7 @@ class Event(models.Model, metaclass=ModelTranslateMeta):
ordering = ('-start',)
class RegistrationInformationField(models.Model, metaclass=ModelTranslateMeta):
class RegistrationInformationField(models.Model):
"""Field description to ask for when registering"""
BOOLEAN_FIELD = 'boolean'
INTEGER_FIELD = 'integer'
......@@ -206,14 +205,12 @@ class RegistrationInformationField(models.Model, metaclass=ModelTranslateMeta):
max_length=10,
)
name = MultilingualField(
models.CharField,
name = models.CharField(
_('field name'),
max_length=100,
)
description = MultilingualField(
models.TextField,
description = models.TextField(
_('description'),
null=True,
blank=True,
......@@ -368,16 +365,18 @@ class AbstractRegistrationInformation(models.Model):
class BooleanRegistrationInformation(AbstractRegistrationInformation):
"""Checkbox information filled in by members when registering"""
"""Checkbox information filled in by members when registring"""
value = models.BooleanField()
class TextRegistrationInformation(AbstractRegistrationInformation):
"""Checkbox information filled in by members when registering"""
"""Checkbox information filled in by members when registring"""
value = models.TextField()
class IntegerRegistrationInformation(AbstractRegistrationInformation):
"""Checkbox information filled in by members when registering"""
"""Checkbox information filled in by members when registring"""