Commits

Jesper Nøhr committed d394b4e Merge

importing ephelon's fork, resolving a few conflicts and refactoring oauth datastore caching

Comments (0)

Files changed (7)

piston/authentication.py

+import oauth
 from django.http import HttpResponse, HttpResponseRedirect
 from django.contrib.auth.models import User, AnonymousUser
 from django.contrib.auth.decorators import login_required
 from django.template import RequestContext
 from django.utils.importlib import import_module
 
-import oauth
 from piston import forms
 
 class NoAuthentication(object):
         resp.status_code = 401
         return resp
 
-DataStore = None
-
 def load_data_store():
     '''Load data store for OAuth Consumers, Tokens, Nonces and Resources
     '''
     # stolen from django.contrib.auth.load_backend
     i = path.rfind('.')
     module, attr = path[:i], path[i+1:]
+
     try:
         mod = import_module(module)
     except ImportError, e:
 
     return cls
 
+# Set the datastore here.
+oauth_datastore = load_data_store()
+
 def initialize_server_request(request):
     """
     Shortcut for initialization.
         query_string=request.environ.get('QUERY_STRING', ''))
         
     if oauth_request:
-        global DataStore
-        if DataStore is None:
-            DataStore = load_data_store()
-
-        oauth_server = oauth.OAuthServer(DataStore(oauth_request))
+        oauth_server = oauth.OAuthServer(oauth_datastore(oauth_request))
         oauth_server.add_signature_method(oauth.OAuthSignatureMethod_PLAINTEXT())
         oauth_server.add_signature_method(oauth.OAuthSignatureMethod_HMAC_SHA1())
     else:
         'oauth_token': token.key,
         'oauth_callback': callback,
         })
+
     return render_to_response('piston/authorize_token.html',
             { 'form': form }, RequestContext(request))
 

piston/emitters.py

 from __future__ import generators
 
-import types, decimal, types, re, inspect
+import decimal, re, inspect
 
 try:
     # yaml isn't standard with python.  It shouldn't be required if it
                 ret = _model(thing, fields=fields)
             elif isinstance(thing, HttpResponse):
                 raise HttpStatusCode(thing)
-            elif isinstance(thing, types.FunctionType):
+            elif inspect.isfunction(thing):
                 if not inspect.getargspec(thing)[0]:
                     ret = _any(thing())
+            elif hasattr(thing, '__emittable__'):
+                f = thing.__emittable__
+                if inspect.ismethod(f) and len(inspect.getargspec(f)[0]) == 1:
+                    ret = _any(f())
             else:
                 ret = smart_unicode(thing, strings_only=True)
 

piston/resource.py

 import sys, inspect
 
-from django.http import HttpResponse, Http404, HttpResponseNotAllowed, HttpResponseForbidden
+from django.http import (HttpResponse, Http404, HttpResponseNotAllowed,
+    HttpResponseForbidden, HttpResponseServerError)
 from django.views.debug import ExceptionReporter
 from django.views.decorators.vary import vary_on_headers
 from django.conf import settings
             If `PISTON_DISPLAY_ERRORS` is not enabled, the caller will
             receive a basic "500 Internal Server Error" message.
             """
+            exc_type, exc_value, tb = sys.exc_info()
+            rep = ExceptionReporter(request, exc_type, exc_value, tb.tb_next)
             if self.email_errors:
-                exc_type, exc_value, tb = sys.exc_info()
-                rep = ExceptionReporter(request, exc_type, exc_value, tb.tb_next)
-
                 self.email_exception(rep)
-
             if self.display_errors:
-                result = format_error('\n'.join(rep.format_exception()))
+                return HttpResponseServerError(
+                    format_error('\n'.join(rep.format_exception())))
             else:
                 raise
 
         emitter, ct = Emitter.get(em_format)
         srl = emitter(result, typemapper, handler, handler.fields, anonymous)
-        
+
         try:
             """
             Decide whether or not we want a generator here,

tests/test_project/apps/testapp/handlers.py

 from piston.handler import BaseHandler
 from piston.utils import rc, validate
 
-from models import TestModel, ExpressiveTestModel, Comment, InheritedModel
+from models import TestModel, ExpressiveTestModel, Comment, InheritedModel, PlainOldObject
 from forms import EchoForm
 from test_project.apps.testapp import signals
 
         else:
             return super(AbstractHandler, self).read(request)
 
+class PlainOldObjectHandler(BaseHandler):
+    allowed_methods = ('GET',)
+    fields = ('type', 'field')
+    model = PlainOldObject
+    
+    def read(self, request):
+        return self.model()
 
 class EchoHandler(BaseHandler):
     allowed_methods = ('GET', )

tests/test_project/apps/testapp/models.py

     some_other = models.CharField(max_length=32, default='something else')
     
     class Meta:
-        db_table = 'testing_abstracts'
+        db_table = 'testing_abstracts'
+
+class PlainOldObject(object):
+    def __emittable__(self):
+        return {'type': 'plain',
+                'field': 'a field'}

tests/test_project/apps/testapp/tests.py

         resp = self.client.get('/api/echo', data)
         self.assertEquals(resp.status_code, 200)
         self.assertEquals(data, simplejson.loads(resp.content))
+
+class PlainOldObject(MainTests):
+    def test_plain_object_serialization(self):
+        resp = self.client.get('/api/popo')
+        self.assertEquals(resp.status_code, 200)
+        self.assertEquals({'type': 'plain', 'field': 'a field'}, simplejson.loads(resp.content))
+        

tests/test_project/apps/testapp/urls.py

 from piston.resource import Resource
 from piston.authentication import HttpBasicAuthentication
 
-from test_project.apps.testapp.handlers import EntryHandler, ExpressiveHandler, AbstractHandler, EchoHandler
+from test_project.apps.testapp.handlers import EntryHandler, ExpressiveHandler, AbstractHandler, EchoHandler, PlainOldObjectHandler
 
 auth = HttpBasicAuthentication(realm='TestApplication')
 
 expressive = Resource(handler=ExpressiveHandler, authentication=auth)
 abstract = Resource(handler=AbstractHandler, authentication=auth)
 echo = Resource(handler=EchoHandler)
+popo = Resource(handler=PlainOldObjectHandler)
 
 
 urlpatterns = patterns('',
 
     url(r'^echo$', echo),
 
+    # oauth entrypoints
     url(r'^oauth/request_token$', 'piston.authentication.oauth_request_token'),
     url(r'^oauth/authorize$', 'piston.authentication.oauth_user_auth'),
     url(r'^oauth/access_token$', 'piston.authentication.oauth_access_token'),
+    
+    url(r'^popo$', popo),
 )