diff options
| -rw-r--r-- | docs/emitters.rst | 2 | ||||
| -rw-r--r-- | docs/index.rst | 24 | ||||
| -rw-r--r-- | examples/pygments_api/forms.py | 52 | ||||
| -rw-r--r-- | examples/pygments_api/views.py | 2 | ||||
| -rw-r--r-- | examples/urls.py | 1 | ||||
| -rw-r--r-- | flywheel/emitters.py | 7 | ||||
| -rw-r--r-- | flywheel/resource.py | 13 | ||||
| -rw-r--r-- | flywheel/templates/emitter.html | 8 | 
8 files changed, 47 insertions, 62 deletions
| diff --git a/docs/emitters.rst b/docs/emitters.rst index fcea6151..590ace0f 100644 --- a/docs/emitters.rst +++ b/docs/emitters.rst @@ -1,8 +1,6 @@  :mod:`emitters`  =============== -.. module:: emitters -  The emitters module provides a set of emitters that can be plugged in to a :class:`.Resource`.  An emitter is responsible for taking the output of a and serializing it to a given media type.  A :class:`.Resource` can have a number of emitters, allow the same content to be serialized in a number of different formats depending on the requesting client's preferences, as specified in the HTTP Request's Accept header.  .. automodule:: emitters diff --git a/docs/index.rst b/docs/index.rst index a6bdaab8..10e41f7a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,8 +13,30 @@ Some of FlyWheel's features:  * Optional support for forms as input validation.  * Modular architecture - Easy to extend and modify. +Installation & Setup +-------------------- + +blah di blah + +Getting Started +--------------- + +Blah di blah + + +Examples +-------- + +Blah blah blah, examples here. + +Add a toctree for examples + + +Library Reference +----------------- +  .. toctree:: -  :maxdepth: 1 +  :maxdepth: 2    resource    modelresource diff --git a/examples/pygments_api/forms.py b/examples/pygments_api/forms.py index 66446c5b..dc9927e2 100644 --- a/examples/pygments_api/forms.py +++ b/examples/pygments_api/forms.py @@ -15,57 +15,11 @@ class PygmentsForm(forms.Form):      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)') +    code = forms.CharField(widget=forms.Textarea, label='Code Text', max_length=1000000,  +                           help_text='(Copy and paste the code text here.)') +    title = forms.CharField(required=False, help_text='(Optional)', max_length=100)      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 diff --git a/examples/pygments_api/views.py b/examples/pygments_api/views.py index 02f541f3..4493a822 100644 --- a/examples/pygments_api/views.py +++ b/examples/pygments_api/views.py @@ -24,7 +24,7 @@ class HTMLEmitter(BaseEmitter):  class PygmentsRoot(Resource):      """This example demonstrates a simple RESTful Web API aound the awesome pygments library. -    This top level resource is used to create  """ +    This top level resource is used to create highlighted code snippets."""      form = PygmentsForm      allowed_methods = anon_allowed_methods = ('POST',) diff --git a/examples/urls.py b/examples/urls.py index b1dec13d..48af39de 100644 --- a/examples/urls.py +++ b/examples/urls.py @@ -7,6 +7,7 @@ urlpatterns = patterns('',      (r'^pygments-example/', include('pygments_api.urls')),      (r'^blog-post-example/', include('blogpost.urls')),      (r'^object-store-example/', include('objectstore.urls')), +    (r'^testarchive-example/', include('testarchive.urls')),      (r'^accounts/login/$', 'django.contrib.auth.views.login'),      (r'^accounts/logout/$', 'django.contrib.auth.views.logout'),      (r'^admin/doc/', include('django.contrib.admindocs.urls')), diff --git a/flywheel/emitters.py b/flywheel/emitters.py index d052d965..57e95ec2 100644 --- a/flywheel/emitters.py +++ b/flywheel/emitters.py @@ -32,6 +32,8 @@ class BaseEmitter(object):          self.resource = resource      def emit(self, output=NoContent, verbose=False): +        """By default emit simply returns the ouput as-is. +        Override this method to provide for other behaviour."""          if output is NoContent:              return '' @@ -81,7 +83,8 @@ class DocumentingTemplateEmitter(BaseEmitter):          provide a form that can be used to submit arbitrary content."""          # Get the form instance if we have one bound to the input          form_instance = resource.form_instance -         +        print form_instance +          # Otherwise if this isn't an error response          # then attempt to get a form bound to the response object          if not form_instance and resource.response.has_content_body: @@ -89,6 +92,8 @@ class DocumentingTemplateEmitter(BaseEmitter):                  form_instance = resource.get_form(resource.response.raw_content)              except:                  pass +            if form_instance and not form_instance.is_valid(): +                form_instance = None          # If we still don't have a form instance then try to get an unbound form          if not form_instance: diff --git a/flywheel/resource.py b/flywheel/resource.py index 677bdfce..2a8554f3 100644 --- a/flywheel/resource.py +++ b/flywheel/resource.py @@ -58,14 +58,19 @@ class Resource(object):      CSRF_PARAM = 'csrfmiddlewaretoken'    # Django's CSRF token used in form params -    def __new__(cls, request, *args, **kwargs): +    def __new__(cls, *args, **kwargs):          """Make the class callable so it can be used as a Django view."""          self = object.__new__(cls) -        self.__init__(request) -        return self._handle_request(request, *args, **kwargs) +        if args: +            request = args[0] +            self.__init__(request) +            return self._handle_request(request, *args[1:], **kwargs) +        else: +            self.__init__() +            return self -    def __init__(self, request): +    def __init__(self, request=None):          """"""          # Setup the resource context          self.request = request diff --git a/flywheel/templates/emitter.html b/flywheel/templates/emitter.html index 7959af17..4b0a7ce9 100644 --- a/flywheel/templates/emitter.html +++ b/flywheel/templates/emitter.html @@ -30,9 +30,9 @@  	    <h1>{{ resource.name }}</h1>  	    <p>{{ resource.description|linebreaksbr }}</p>  	    <pre><b>{{ response.status }} {{ response.status_text }}</b>{% autoescape off %} -	{% for key, val in response.headers.items %}<b>{{ key }}:</b> {{ val|urlize_quoted_links }} -	{% endfor %} -	{{ content|urlize_quoted_links }}</pre>{% endautoescape %} +{% for key, val in response.headers.items %}<b>{{ key }}:</b> {{ val|urlize_quoted_links }} +{% endfor %} +{{ content|urlize_quoted_links }}</pre>{% endautoescape %}  	{% if 'GET' in resource.allowed_methods %}  		<div class='action'> @@ -40,7 +40,7 @@  			<ul class="accepttypes">  			{% for media_type in resource.emitted_media_types %}  			  {% with resource.ACCEPT_QUERY_PARAM|add:"="|add:media_type as param %} -			    <li>[<a href='{{ request.path|add_query_param:param }} rel="nofollow"'>{{ media_type }}</a>]</li> +			    <li>[<a href='{{ request.path|add_query_param:param }}' rel="nofollow">{{ media_type }}</a>]</li>  			  {% endwith %}  			{% endfor %}  			</ul> | 
