Skip to content

Commit

Permalink
Merge pull request #457 from ox-it/clean-xml-data
Browse files Browse the repository at this point in the history
Clean xml data - 3306
  • Loading branch information
ahaith committed May 6, 2016
2 parents 59f51f0 + a73e3cf commit 380e550
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 21 deletions.
2 changes: 0 additions & 2 deletions talks/api/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging
from datetime import date

from django.contrib.auth.models import User

from django.core.exceptions import ObjectDoesNotExist
Expand Down Expand Up @@ -180,7 +179,6 @@ def api_event_get(request, slug):
serializer = HALEventSerializer(event, read_only=True, context={'request': request})
return Response(serializer.data, status=status.HTTP_200_OK)


@api_view(["GET"])
@renderer_classes((ICalRenderer,))
def api_event_get_ics(request, slug):
Expand Down
73 changes: 56 additions & 17 deletions talks/contributors/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from talks.events import models, typeahead, datasources
from talks.events.models import EventGroup, AUDIENCE_CHOICES, AUDIENCE_PUBLIC, AUDIENCE_OXFORD, AUDIENCE_OTHER
from talks.users.authentication import GROUP_EDIT_EVENTS

from talks.core.utils import clean_xml

class OxPointField(forms.CharField):
def __init__(self, source, *args, **kwargs):
Expand All @@ -20,6 +20,11 @@ class TopicsField(forms.MultipleChoiceField):
def valid_value(self, value):
return True

class XMLFriendlyTextField(forms.CharField):
def clean(self, data):
super(XMLFriendlyTextField, self).clean(data)
return clean_xml(data)


class BootstrappedDateTimeWidget(forms.DateTimeInput):
def render(self, name, value, attrs=None):
Expand Down Expand Up @@ -134,34 +139,57 @@ def __init__(self, *args, **kwargs):
required=False
)

audience_other = forms.CharField(
label="",
required=False,
help_text="If other, please specify"
)

audience_choices = forms.ChoiceField(
label="Who can attend",
required=False,
choices=AUDIENCE_CHOICES,
widget=RadioSelect()
)

title = XMLFriendlyTextField(
max_length=250,
required=False,
)

location_details = XMLFriendlyTextField(
required=False,
label='Venue details',
help_text='e.g.: room number or accessibility information'
)

description = XMLFriendlyTextField(
label="Abstract",
widget=forms.Textarea(attrs={'rows': 4}),
required=False,
)

special_message = XMLFriendlyTextField(
required=False,
label="Special message",
widget=forms.Textarea(attrs={'rows': 2}),
help_text="Use this for important notices - e.g.: cancellation or a last minute change of venue"
)

audience_other = XMLFriendlyTextField(
label="",
required=False,
help_text="If other, please specify"
)

cost = XMLFriendlyTextField(
required=False,
)

class Meta:
exclude = ('slug', 'embargo')
model = models.Event
labels = {
'description': 'Abstract',
}
widgets = {
'start': BootstrappedDateTimeWidget(attrs={'readonly': True}),
'end': BootstrappedDateTimeWidget(attrs={'readonly': True}),
'booking_type': forms.RadioSelect,
'cost': forms.TextInput,
'audience': forms.RadioSelect,
'location_details': forms.TextInput,
'status': forms.RadioSelect,
'special_message': forms.Textarea(attrs={'rows': 2})
}
help_texts = {
'organiser_email': 'Email address for more details',
Expand Down Expand Up @@ -287,7 +315,23 @@ class EventGroupForm(forms.ModelForm):
required=False,
widget=typeahead.MultipleTypeahead(datasources.USERS_DATA_SOURCE),
)

title = XMLFriendlyTextField(
max_length=250,
required=True
)

description = XMLFriendlyTextField(
widget=forms.Textarea(attrs={'rows': 8}),
required=False,
)

occurence = XMLFriendlyTextField(
required=False,
label='Timing',
help_text='e.g.: Mondays at 10 or September 19th to 20th.'
)

def save(self):
group = super(EventGroupForm, self).save(commit=False)
group.save()
Expand All @@ -307,11 +351,6 @@ def save(self):
class Meta:
exclude = ('slug',)
model = models.EventGroup
widgets = {
'title': forms.TextInput(),
'description': forms.Textarea(),
'occurence': forms.TextInput(),
}
labels = {
'group_type': 'Series type'
}
Expand Down
25 changes: 25 additions & 0 deletions talks/core/utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
from datetime import datetime, timedelta
from re import sub, compile
from sys import maxunicode

from rest_framework.exceptions import ParseError
import yaml

def clean_xml(dirty):
if dirty is None:
return ""

_illegal_unichrs = [(0x00, 0x08), (0x0B, 0x0C), (0x0E, 0x1F),
(0x7F, 0x84), (0x86, 0x9F),
(0xFDD0, 0xFDDF), (0xFFFE, 0xFFFF)]
if maxunicode >= 0x10000: # not narrow build
_illegal_unichrs.extend([(0x1FFFE, 0x1FFFF), (0x2FFFE, 0x2FFFF),
(0x3FFFE, 0x3FFFF), (0x4FFFE, 0x4FFFF),
(0x5FFFE, 0x5FFFF), (0x6FFFE, 0x6FFFF),
(0x7FFFE, 0x7FFFF), (0x8FFFE, 0x8FFFF),
(0x9FFFE, 0x9FFFF), (0xAFFFE, 0xAFFFF),
(0xBFFFE, 0xBFFFF), (0xCFFFE, 0xCFFFF),
(0xDFFFE, 0xDFFFF), (0xEFFFE, 0xEFFFF),
(0xFFFFE, 0xFFFFF), (0x10FFFE, 0x10FFFF)])

_illegal_ranges = ["%s-%s" % (unichr(low), unichr(high))
for (low, high) in _illegal_unichrs]
_illegal_xml_chars_RE = compile(u'[%s]' % u''.join(_illegal_ranges))
clean = _illegal_xml_chars_RE.sub('', str(dirty))
return clean

def parse_date(date_param):
"""
Parse the date string parameter
Expand Down
14 changes: 12 additions & 2 deletions talks/users/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@

from talks.events import typeahead, datasources
from talks.users.models import Collection, TalksUser, TalksUserCollection, DEFAULT_COLLECTION_NAME, COLLECTION_ROLES_EDITOR, COLLECTION_ROLES_READER, COLLECTION_ROLES_OWNER
from talks.contributors.forms import XMLFriendlyTextField

class CollectionForm(forms.ModelForm):

title = XMLFriendlyTextField(
max_length=250,
required=True
)

description = XMLFriendlyTextField(
widget=forms.Textarea(attrs={'rows': 8}),
required=False,
)

editor_set = forms.ModelMultipleChoiceField(
queryset=TalksUser.objects.filter().distinct(),
label="Other Editors",
Expand Down Expand Up @@ -58,4 +68,4 @@ def clean(self):
raise ValidationError({'title': 'Please change the title of your list to something less generic before making your list public'})

if not public and (number_of_readers > 0):
raise ValidationError({'public': 'Unable to revoke public status - there are already ' + str(number_of_readers) + ' readers following this list.'})
raise ValidationError({'public': 'Unable to revoke public status - there are already ' + str(number_of_readers) + ' readers following this list.'})

0 comments on commit 380e550

Please sign in to comment.