django-rest-framework/examples/pygments_api/forms.py
tom christie tom@tomchristie.com 6807cf014c Added pygments_api example
2011-01-26 08:58:09 +00:00

72 lines
2.8 KiB
Python

from django import forms
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles
import httplib2 as httplib
LEXER_CHOICES = sorted([(item[1][0], item[0]) for item in get_all_lexers()])
STYLE_CHOICES = sorted((item, item) for item in list(get_all_styles()))
class PygmentsForm(forms.Form):
"""A simple form with some of the most important pygments settings.
The code to be highlighted can be specified either in a text field, or by URL.
We do some additional form validation to ensure clients see helpful error responses."""
code_url = forms.URLField(required=False, label='Code URL',
help_text='eg. https://bitbucket.org/tomchristie/flywheel/raw/cc266285d879/flywheel/resource.py')
code_text = forms.CharField(widget=forms.Textarea, required=False, label='Code Text',
help_text='Either supply a URL for the code to be highlighted or copy and paste the code text here.')
title = forms.CharField(required=False, help_text='(Optional)')
linenos = forms.BooleanField(label='Show Line Numbers', required=False)
lexer = forms.ChoiceField(choices=LEXER_CHOICES, initial='python')
style = forms.ChoiceField(choices=STYLE_CHOICES, initial='friendly')
def clean_code_url(self):
"""Custom field validation.
Ensure that code URLs really are valid, and return the content they point to in the cleaned_data,
rather than returning the URL itself."""
cleaned_data = self.cleaned_data
url = cleaned_data.get('code_url')
if not url:
return ''
try:
http = httplib.Http('.cache')
resp, content = http.request(url)
except:
raise forms.ValidationError('The URL supplied cannot be reached')
if int(resp.status/100) != 2:
raise forms.ValidationError('The URL supplied does not return successfully')
if not content:
raise forms.ValidationError('The URL supplied returns no content')
return content
def clean(self):
"""Custom form validation.
Ensure that only one of code_url and code_text is set, and return the content of whichever is set in 'code'."""
cleaned_data = self.cleaned_data
code_url = cleaned_data.get('code_url')
code_text = cleaned_data.get('code_text')
if not code_url and not code_text:
raise forms.ValidationError('Either the URL or the code text must be supplied')
if code_url and code_text:
raise forms.ValidationError('You may not specify both the URL and the code text')
if code_url:
cleaned_data['code'] = code_url
del cleaned_data['code_url']
else:
cleaned_data['code'] = code_text
del cleaned_data['code_text']
return cleaned_data