2to3 python converstion with major version bump to 1.0.0-yr.alpha
This commit is contained in:
Родитель
b7e8a365de
Коммит
be83a240fb
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
from django.core.management import execute_manager
|
from django.core.management import execute_manager
|
||||||
try:
|
try:
|
||||||
import settings # Assumed to be in the same directory.
|
from . import settings # Assumed to be in the same directory.
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import sys
|
import sys
|
||||||
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
|
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
|
||||||
|
|
26
ez_setup.py
26
ez_setup.py
|
@ -62,10 +62,10 @@ def _validate_md5(egg_name, data):
|
||||||
if egg_name in md5_data:
|
if egg_name in md5_data:
|
||||||
digest = md5(data).hexdigest()
|
digest = md5(data).hexdigest()
|
||||||
if digest != md5_data[egg_name]:
|
if digest != md5_data[egg_name]:
|
||||||
print >>sys.stderr, (
|
print((
|
||||||
"md5 validation of %s failed! (Possible download problem?)"
|
"md5 validation of %s failed! (Possible download problem?)"
|
||||||
% egg_name
|
% egg_name
|
||||||
)
|
), file=sys.stderr)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@ -95,14 +95,14 @@ def use_setuptools(
|
||||||
return do_download()
|
return do_download()
|
||||||
try:
|
try:
|
||||||
pkg_resources.require("setuptools>="+version); return
|
pkg_resources.require("setuptools>="+version); return
|
||||||
except pkg_resources.VersionConflict, e:
|
except pkg_resources.VersionConflict as e:
|
||||||
if was_imported:
|
if was_imported:
|
||||||
print >>sys.stderr, (
|
print((
|
||||||
"The required version of setuptools (>=%s) is not available, and\n"
|
"The required version of setuptools (>=%s) is not available, and\n"
|
||||||
"can't be installed while this script is running. Please install\n"
|
"can't be installed while this script is running. Please install\n"
|
||||||
" a more recent version first, using 'easy_install -U setuptools'."
|
" a more recent version first, using 'easy_install -U setuptools'."
|
||||||
"\n\n(Currently using %r)"
|
"\n\n(Currently using %r)"
|
||||||
) % (version, e.args[0])
|
) % (version, e.args[0]), file=sys.stderr)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
else:
|
else:
|
||||||
del pkg_resources, sys.modules['pkg_resources'] # reload ok
|
del pkg_resources, sys.modules['pkg_resources'] # reload ok
|
||||||
|
@ -121,7 +121,7 @@ def download_setuptools(
|
||||||
with a '/'). `to_dir` is the directory where the egg will be downloaded.
|
with a '/'). `to_dir` is the directory where the egg will be downloaded.
|
||||||
`delay` is the number of seconds to pause before an actual download attempt.
|
`delay` is the number of seconds to pause before an actual download attempt.
|
||||||
"""
|
"""
|
||||||
import urllib2, shutil
|
import urllib.request, urllib.error, urllib.parse, shutil
|
||||||
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
|
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
|
||||||
url = download_base + egg_name
|
url = download_base + egg_name
|
||||||
saveto = os.path.join(to_dir, egg_name)
|
saveto = os.path.join(to_dir, egg_name)
|
||||||
|
@ -147,7 +147,7 @@ and place it in this directory before rerunning this script.)
|
||||||
version, download_base, delay, url
|
version, download_base, delay, url
|
||||||
); from time import sleep; sleep(delay)
|
); from time import sleep; sleep(delay)
|
||||||
log.warn("Downloading %s", url)
|
log.warn("Downloading %s", url)
|
||||||
src = urllib2.urlopen(url)
|
src = urllib.request.urlopen(url)
|
||||||
# Read/write all in one block, so we don't create a corrupt file
|
# Read/write all in one block, so we don't create a corrupt file
|
||||||
# if the download is interrupted.
|
# if the download is interrupted.
|
||||||
data = _validate_md5(egg_name, src.read())
|
data = _validate_md5(egg_name, src.read())
|
||||||
|
@ -208,10 +208,10 @@ def main(argv, version=DEFAULT_VERSION):
|
||||||
os.unlink(egg)
|
os.unlink(egg)
|
||||||
else:
|
else:
|
||||||
if setuptools.__version__ == '0.0.1':
|
if setuptools.__version__ == '0.0.1':
|
||||||
print >>sys.stderr, (
|
print((
|
||||||
"You have an obsolete version of setuptools installed. Please\n"
|
"You have an obsolete version of setuptools installed. Please\n"
|
||||||
"remove it from your system entirely before rerunning this script."
|
"remove it from your system entirely before rerunning this script."
|
||||||
)
|
), file=sys.stderr)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
req = "setuptools>="+version
|
req = "setuptools>="+version
|
||||||
|
@ -230,8 +230,8 @@ def main(argv, version=DEFAULT_VERSION):
|
||||||
from setuptools.command.easy_install import main
|
from setuptools.command.easy_install import main
|
||||||
main(argv)
|
main(argv)
|
||||||
else:
|
else:
|
||||||
print "Setuptools version",version,"or greater has been installed."
|
print("Setuptools version",version,"or greater has been installed.")
|
||||||
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
|
print('(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)')
|
||||||
|
|
||||||
def update_md5(filenames):
|
def update_md5(filenames):
|
||||||
"""Update our built-in md5 registry"""
|
"""Update our built-in md5 registry"""
|
||||||
|
@ -244,7 +244,7 @@ def update_md5(filenames):
|
||||||
md5_data[base] = md5(f.read()).hexdigest()
|
md5_data[base] = md5(f.read()).hexdigest()
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
data = [" %r: %r,\n" % it for it in md5_data.items()]
|
data = [" %r: %r,\n" % it for it in list(md5_data.items())]
|
||||||
data.sort()
|
data.sort()
|
||||||
repl = "".join(data)
|
repl = "".join(data)
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ def update_md5(filenames):
|
||||||
|
|
||||||
match = re.search("\nmd5_data = {\n([^}]+)}", src)
|
match = re.search("\nmd5_data = {\n([^}]+)}", src)
|
||||||
if not match:
|
if not match:
|
||||||
print >>sys.stderr, "Internal error!"
|
print("Internal error!", file=sys.stderr)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
src = src[:match.start(1)] + repl + src[match.end(1):]
|
src = src[:match.start(1)] + repl + src[match.end(1):]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import binascii
|
import binascii
|
||||||
|
|
||||||
import oauth
|
from . import oauth
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
from django.contrib.auth.models import User, AnonymousUser
|
from django.contrib.auth.models import User, AnonymousUser
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
@ -70,7 +70,7 @@ class HttpBasicAuthentication(object):
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u'<HTTPBasic: realm=%s>' % self.realm
|
return '<HTTPBasic: realm=%s>' % self.realm
|
||||||
|
|
||||||
class HttpBasicSimple(HttpBasicAuthentication):
|
class HttpBasicSimple(HttpBasicAuthentication):
|
||||||
def __init__(self, realm, username, password):
|
def __init__(self, realm, username, password):
|
||||||
|
@ -94,13 +94,13 @@ def load_data_store():
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mod = __import__(module, {}, {}, attr)
|
mod = __import__(module, {}, {}, attr)
|
||||||
except ImportError, e:
|
except ImportError as e:
|
||||||
raise ImproperlyConfigured, 'Error importing OAuth data store %s: "%s"' % (module, e)
|
raise ImproperlyConfigured('Error importing OAuth data store %s: "%s"' % (module, e))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cls = getattr(mod, attr)
|
cls = getattr(mod, attr)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise ImproperlyConfigured, 'Module %s does not define a "%s" OAuth data store' % (module, attr)
|
raise ImproperlyConfigured('Module %s does not define a "%s" OAuth data store' % (module, attr))
|
||||||
|
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ def initialize_server_request(request):
|
||||||
"""
|
"""
|
||||||
# c.f. http://www.mail-archive.com/oauth@googlegroups.com/msg01556.html
|
# c.f. http://www.mail-archive.com/oauth@googlegroups.com/msg01556.html
|
||||||
if (request.method == 'POST' and request.FILES == {}):
|
if (request.method == 'POST' and request.FILES == {}):
|
||||||
params = dict(request.REQUEST.items())
|
params = dict(list(request.REQUEST.items()))
|
||||||
else:
|
else:
|
||||||
params = {}
|
params = {}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ def send_oauth_error(err=None):
|
||||||
realm = 'OAuth'
|
realm = 'OAuth'
|
||||||
header = oauth.build_authenticate_header(realm=realm)
|
header = oauth.build_authenticate_header(realm=realm)
|
||||||
|
|
||||||
for k, v in header.iteritems():
|
for k, v in header.items():
|
||||||
response[k] = v
|
response[k] = v
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
@ -159,7 +159,7 @@ def oauth_request_token(request):
|
||||||
token = oauth_server.fetch_request_token(oauth_request)
|
token = oauth_server.fetch_request_token(oauth_request)
|
||||||
|
|
||||||
response = HttpResponse(token.to_string())
|
response = HttpResponse(token.to_string())
|
||||||
except oauth.OAuthError, err:
|
except oauth.OAuthError as err:
|
||||||
response = send_oauth_error(err)
|
response = send_oauth_error(err)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
@ -183,7 +183,7 @@ def oauth_user_auth(request):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
token = oauth_server.fetch_request_token(oauth_request)
|
token = oauth_server.fetch_request_token(oauth_request)
|
||||||
except oauth.OAuthError, err:
|
except oauth.OAuthError as err:
|
||||||
return send_oauth_error(err)
|
return send_oauth_error(err)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -214,7 +214,7 @@ def oauth_user_auth(request):
|
||||||
|
|
||||||
response = HttpResponseRedirect(callback+args)
|
response = HttpResponseRedirect(callback+args)
|
||||||
|
|
||||||
except oauth.OAuthError, err:
|
except oauth.OAuthError as err:
|
||||||
response = send_oauth_error(err)
|
response = send_oauth_error(err)
|
||||||
else:
|
else:
|
||||||
response = HttpResponse('Action not allowed.')
|
response = HttpResponse('Action not allowed.')
|
||||||
|
@ -230,7 +230,7 @@ def oauth_access_token(request):
|
||||||
try:
|
try:
|
||||||
token = oauth_server.fetch_access_token(oauth_request, required=True)
|
token = oauth_server.fetch_access_token(oauth_request, required=True)
|
||||||
return HttpResponse(token.to_string())
|
return HttpResponse(token.to_string())
|
||||||
except oauth.OAuthError, err:
|
except oauth.OAuthError as err:
|
||||||
return send_oauth_error(err)
|
return send_oauth_error(err)
|
||||||
|
|
||||||
INVALID_PARAMS_RESPONSE = send_oauth_error(oauth.OAuthError('Invalid request parameters.'))
|
INVALID_PARAMS_RESPONSE = send_oauth_error(oauth.OAuthError('Invalid request parameters.'))
|
||||||
|
@ -254,8 +254,8 @@ class OAuthAuthentication(object):
|
||||||
if self.is_valid_request(request):
|
if self.is_valid_request(request):
|
||||||
try:
|
try:
|
||||||
consumer, token, parameters = self.validate_token(request)
|
consumer, token, parameters = self.validate_token(request)
|
||||||
except oauth.OAuthError, err:
|
except oauth.OAuthError as err:
|
||||||
print send_oauth_error(err)
|
print(send_oauth_error(err))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if consumer and token:
|
if consumer and token:
|
||||||
|
@ -281,7 +281,7 @@ class OAuthAuthentication(object):
|
||||||
response.status_code = 401
|
response.status_code = 401
|
||||||
realm = 'API'
|
realm = 'API'
|
||||||
|
|
||||||
for k, v in self.builder(realm=realm).iteritems():
|
for k, v in self.builder(realm=realm).items():
|
||||||
response[k] = v
|
response[k] = v
|
||||||
tmpl = loader.render_to_string('oauth/challenge.html',
|
tmpl = loader.render_to_string('oauth/challenge.html',
|
||||||
{ 'MEDIA_URL': settings.MEDIA_URL })
|
{ 'MEDIA_URL': settings.MEDIA_URL })
|
||||||
|
|
|
@ -54,9 +54,9 @@ def getinfo(func):
|
||||||
signature = inspect.formatargspec(regargs, varargs, varkwargs, defaults,
|
signature = inspect.formatargspec(regargs, varargs, varkwargs, defaults,
|
||||||
formatvalue=lambda value: "")[1:-1]
|
formatvalue=lambda value: "")[1:-1]
|
||||||
return dict(name=func.__name__, argnames=argnames, signature=signature,
|
return dict(name=func.__name__, argnames=argnames, signature=signature,
|
||||||
defaults = func.func_defaults, doc=func.__doc__,
|
defaults = func.__defaults__, doc=func.__doc__,
|
||||||
module=func.__module__, dict=func.__dict__,
|
module=func.__module__, dict=func.__dict__,
|
||||||
globals=func.func_globals, closure=func.func_closure)
|
globals=func.__globals__, closure=func.__closure__)
|
||||||
|
|
||||||
# akin to functools.update_wrapper
|
# akin to functools.update_wrapper
|
||||||
def update_wrapper(wrapper, model, infodict=None):
|
def update_wrapper(wrapper, model, infodict=None):
|
||||||
|
@ -68,7 +68,7 @@ def update_wrapper(wrapper, model, infodict=None):
|
||||||
wrapper.__doc__ = infodict['doc']
|
wrapper.__doc__ = infodict['doc']
|
||||||
wrapper.__module__ = infodict['module']
|
wrapper.__module__ = infodict['module']
|
||||||
wrapper.__dict__.update(infodict['dict'])
|
wrapper.__dict__.update(infodict['dict'])
|
||||||
wrapper.func_defaults = infodict['defaults']
|
wrapper.__defaults__ = infodict['defaults']
|
||||||
wrapper.undecorated = model
|
wrapper.undecorated = model
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ class HandlerDocumentation(object):
|
||||||
if not met:
|
if not met:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
stale = inspect.getmodule(met.im_func) is not inspect.getmodule(self.handler)
|
stale = inspect.getmodule(met.__func__) is not inspect.getmodule(self.handler)
|
||||||
|
|
||||||
if not self.handler.is_anonymous:
|
if not self.handler.is_anonymous:
|
||||||
if met and (not stale or include_default):
|
if met and (not stale or include_default):
|
||||||
|
@ -140,7 +140,7 @@ class HandlerDocumentation(object):
|
||||||
def _convert(template, params=[]):
|
def _convert(template, params=[]):
|
||||||
"""URI template converter"""
|
"""URI template converter"""
|
||||||
paths = template % dict([p, "{%s}" % p] for p in params)
|
paths = template % dict([p, "{%s}" % p] for p in params)
|
||||||
return u'%s%s' % (get_script_prefix(), paths)
|
return '%s%s' % (get_script_prefix(), paths)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
resource_uri = self.handler.resource_uri()
|
resource_uri = self.handler.resource_uri()
|
||||||
|
@ -171,7 +171,7 @@ class HandlerDocumentation(object):
|
||||||
resource_uri_template = property(get_resource_uri_template)
|
resource_uri_template = property(get_resource_uri_template)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u'<Documentation for "%s">' % self.name
|
return '<Documentation for "%s">' % self.name
|
||||||
|
|
||||||
def documentation_view(request):
|
def documentation_view(request):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
from __future__ import generators
|
|
||||||
|
|
||||||
import decimal, re, inspect
|
import decimal, re, inspect
|
||||||
import copy
|
import copy
|
||||||
|
import collections
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# yaml isn't standard with python. It shouldn't be required if it
|
# yaml isn't standard with python. It shouldn't be required if it
|
||||||
|
@ -34,16 +35,16 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import json as simplejson
|
import json as simplejson
|
||||||
|
|
||||||
from utils import HttpStatusCode, Mimer
|
from .utils import HttpStatusCode, Mimer
|
||||||
from validate_jsonp import is_valid_jsonp_callback_value
|
from .validate_jsonp import is_valid_jsonp_callback_value
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import cStringIO as StringIO
|
import io as StringIO
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import StringIO
|
import io
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import cPickle as pickle
|
import pickle as pickle
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ class Emitter(object):
|
||||||
for field in fields - Emitter.RESERVED_FIELDS:
|
for field in fields - Emitter.RESERVED_FIELDS:
|
||||||
t = getattr(handler, str(field), None)
|
t = getattr(handler, str(field), None)
|
||||||
|
|
||||||
if t and callable(t):
|
if t and isinstance(t, collections.Callable):
|
||||||
ret[field] = t
|
ret[field] = t
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
@ -182,7 +183,7 @@ class Emitter(object):
|
||||||
|
|
||||||
# sets can be negated.
|
# sets can be negated.
|
||||||
for exclude in exclude_fields:
|
for exclude in exclude_fields:
|
||||||
if isinstance(exclude, basestring):
|
if isinstance(exclude, str):
|
||||||
get_fields.discard(exclude)
|
get_fields.discard(exclude)
|
||||||
|
|
||||||
elif isinstance(exclude, re._pattern_type):
|
elif isinstance(exclude, re._pattern_type):
|
||||||
|
@ -221,7 +222,7 @@ class Emitter(object):
|
||||||
if inst:
|
if inst:
|
||||||
if hasattr(inst, 'all'):
|
if hasattr(inst, 'all'):
|
||||||
ret[model] = _related(inst, fields)
|
ret[model] = _related(inst, fields)
|
||||||
elif callable(inst):
|
elif isinstance(inst, collections.Callable):
|
||||||
if len(inspect.getargspec(inst)[0]) == 1:
|
if len(inspect.getargspec(inst)[0]) == 1:
|
||||||
ret[model] = _any(inst(), fields)
|
ret[model] = _any(inst(), fields)
|
||||||
else:
|
else:
|
||||||
|
@ -236,7 +237,7 @@ class Emitter(object):
|
||||||
else:
|
else:
|
||||||
maybe = getattr(data, maybe_field, None)
|
maybe = getattr(data, maybe_field, None)
|
||||||
if maybe is not None:
|
if maybe is not None:
|
||||||
if callable(maybe):
|
if isinstance(maybe, collections.Callable):
|
||||||
if len(inspect.getargspec(maybe)[0]) <= 1:
|
if len(inspect.getargspec(maybe)[0]) <= 1:
|
||||||
ret[maybe_field] = _any(maybe())
|
ret[maybe_field] = _any(maybe())
|
||||||
else:
|
else:
|
||||||
|
@ -253,10 +254,10 @@ class Emitter(object):
|
||||||
ret[f.attname] = _any(getattr(data, f.attname))
|
ret[f.attname] = _any(getattr(data, f.attname))
|
||||||
|
|
||||||
if hasattr(data, "_piston"):
|
if hasattr(data, "_piston"):
|
||||||
for f,v in data._piston['fields'].items():
|
for f,v in list(data._piston['fields'].items()):
|
||||||
ret[f] = _any(v)
|
ret[f] = _any(v)
|
||||||
|
|
||||||
fields = dir(data.__class__) + ret.keys()
|
fields = dir(data.__class__) + list(ret.keys())
|
||||||
add_ons = [k for k in dir(data) if k not in fields]
|
add_ons = [k for k in dir(data) if k not in fields]
|
||||||
|
|
||||||
for k in add_ons:
|
for k in add_ons:
|
||||||
|
@ -271,7 +272,7 @@ class Emitter(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ret['resource_uri'] = reverser( lambda: (url_id, fields) )()
|
ret['resource_uri'] = reverser( lambda: (url_id, fields) )()
|
||||||
except NoReverseMatch, e:
|
except NoReverseMatch as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if hasattr(data, 'get_api_url') and 'resource_uri' not in ret:
|
if hasattr(data, 'get_api_url') and 'resource_uri' not in ret:
|
||||||
|
@ -301,13 +302,13 @@ class Emitter(object):
|
||||||
"""
|
"""
|
||||||
Dictionaries.
|
Dictionaries.
|
||||||
"""
|
"""
|
||||||
return dict([ (k, _any(v, fields)) for k, v in data.iteritems() ])
|
return dict([ (k, _any(v, fields)) for k, v in data.items() ])
|
||||||
|
|
||||||
# Kickstart the seralizin'.
|
# Kickstart the seralizin'.
|
||||||
return _any(self.data, self.fields)
|
return _any(self.data, self.fields)
|
||||||
|
|
||||||
def in_typemapper(self, model, anonymous):
|
def in_typemapper(self, model, anonymous):
|
||||||
for klass, (km, is_anon) in self.typemapper.iteritems():
|
for klass, (km, is_anon) in self.typemapper.items():
|
||||||
if model is km and is_anon is anonymous:
|
if model is km and is_anon is anonymous:
|
||||||
return klass
|
return klass
|
||||||
|
|
||||||
|
@ -332,7 +333,7 @@ class Emitter(object):
|
||||||
"""
|
"""
|
||||||
Gets an emitter, returns the class and a content-type.
|
Gets an emitter, returns the class and a content-type.
|
||||||
"""
|
"""
|
||||||
if cls.EMITTERS.has_key(format):
|
if format in cls.EMITTERS:
|
||||||
return cls.EMITTERS.get(format)
|
return cls.EMITTERS.get(format)
|
||||||
|
|
||||||
raise ValueError("No emitters found for type %s" % format)
|
raise ValueError("No emitters found for type %s" % format)
|
||||||
|
@ -365,7 +366,7 @@ class XMLEmitter(Emitter):
|
||||||
self._to_xml(xml, item)
|
self._to_xml(xml, item)
|
||||||
xml.endElement("resource")
|
xml.endElement("resource")
|
||||||
elif isinstance(data, dict):
|
elif isinstance(data, dict):
|
||||||
for key, value in data.iteritems():
|
for key, value in data.items():
|
||||||
xml.startElement(key, {})
|
xml.startElement(key, {})
|
||||||
self._to_xml(xml, value)
|
self._to_xml(xml, value)
|
||||||
xml.endElement(key)
|
xml.endElement(key)
|
||||||
|
@ -373,7 +374,7 @@ class XMLEmitter(Emitter):
|
||||||
xml.characters(smart_unicode(data))
|
xml.characters(smart_unicode(data))
|
||||||
|
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
stream = StringIO.StringIO()
|
stream = io.StringIO()
|
||||||
|
|
||||||
xml = SimplerXMLGenerator(stream, "utf-8")
|
xml = SimplerXMLGenerator(stream, "utf-8")
|
||||||
xml.startDocument()
|
xml.startDocument()
|
||||||
|
|
|
@ -16,7 +16,7 @@ class ModelForm(forms.ModelForm):
|
||||||
"""
|
"""
|
||||||
def merge_from_initial(self):
|
def merge_from_initial(self):
|
||||||
self.data._mutable = True
|
self.data._mutable = True
|
||||||
filt = lambda v: v not in self.data.keys()
|
filt = lambda v: v not in list(self.data.keys())
|
||||||
for field in filter(filt, getattr(self.Meta, 'fields', ())):
|
for field in filter(filt, getattr(self.Meta, 'fields', ())):
|
||||||
self.data[field] = self.initial.get(field, None)
|
self.data[field] = self.initial.get(field, None)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from utils import rc
|
from .utils import rc
|
||||||
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
|
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class HandlerMetaClass(type):
|
||||||
new_cls = type.__new__(cls, name, bases, attrs)
|
new_cls = type.__new__(cls, name, bases, attrs)
|
||||||
|
|
||||||
def already_registered(model, anon):
|
def already_registered(model, anon):
|
||||||
for k, (m, a) in typemapper.iteritems():
|
for k, (m, a) in typemapper.items():
|
||||||
if model == m and anon == a:
|
if model == m and anon == a:
|
||||||
return k
|
return k
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class HandlerMetaClass(type):
|
||||||
|
|
||||||
return new_cls
|
return new_cls
|
||||||
|
|
||||||
class BaseHandler(object):
|
class BaseHandler(object, metaclass=HandlerMetaClass):
|
||||||
"""
|
"""
|
||||||
Basehandler that gives you CRUD for free.
|
Basehandler that gives you CRUD for free.
|
||||||
You are supposed to subclass this for specific
|
You are supposed to subclass this for specific
|
||||||
|
@ -45,7 +45,6 @@ class BaseHandler(object):
|
||||||
receive a request as the first argument from the
|
receive a request as the first argument from the
|
||||||
resource. Use this for checking `request.user`, etc.
|
resource. Use this for checking `request.user`, etc.
|
||||||
"""
|
"""
|
||||||
__metaclass__ = HandlerMetaClass
|
|
||||||
|
|
||||||
allowed_methods = ('GET', 'POST', 'PUT', 'DELETE')
|
allowed_methods = ('GET', 'POST', 'PUT', 'DELETE')
|
||||||
anonymous = is_anonymous = False
|
anonymous = is_anonymous = False
|
||||||
|
@ -53,7 +52,7 @@ class BaseHandler(object):
|
||||||
fields = ( )
|
fields = ( )
|
||||||
|
|
||||||
def flatten_dict(self, dct):
|
def flatten_dict(self, dct):
|
||||||
return dict([ (str(k), dct.get(k)) for k in dct.keys() ])
|
return dict([ (str(k), dct.get(k)) for k in list(dct.keys()) ])
|
||||||
|
|
||||||
def has_model(self):
|
def has_model(self):
|
||||||
return hasattr(self, 'model') or hasattr(self, 'queryset')
|
return hasattr(self, 'model') or hasattr(self, 'queryset')
|
||||||
|
@ -127,7 +126,7 @@ class BaseHandler(object):
|
||||||
return rc.BAD_REQUEST
|
return rc.BAD_REQUEST
|
||||||
|
|
||||||
attrs = self.flatten_dict(request.data)
|
attrs = self.flatten_dict(request.data)
|
||||||
for k,v in attrs.iteritems():
|
for k,v in attrs.items():
|
||||||
setattr( inst, k, v )
|
setattr( inst, k, v )
|
||||||
|
|
||||||
inst.save()
|
inst.save()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import urllib, time, urlparse
|
import urllib.request, urllib.parse, urllib.error, time, urllib.parse
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.db.models.signals import post_save, post_delete
|
from django.db.models.signals import post_save, post_delete
|
||||||
|
@ -7,8 +7,8 @@ from django.contrib.auth.models import User
|
||||||
from django.core.mail import send_mail, mail_admins
|
from django.core.mail import send_mail, mail_admins
|
||||||
|
|
||||||
# Piston imports
|
# Piston imports
|
||||||
from managers import TokenManager, ConsumerManager, ResourceManager
|
from .managers import TokenManager, ConsumerManager, ResourceManager
|
||||||
from signals import consumer_post_save, consumer_post_delete
|
from .signals import consumer_post_save, consumer_post_delete
|
||||||
|
|
||||||
KEY_SIZE = 18
|
KEY_SIZE = 18
|
||||||
SECRET_SIZE = 32
|
SECRET_SIZE = 32
|
||||||
|
@ -33,7 +33,7 @@ class Nonce(models.Model):
|
||||||
app_label = 'piston'
|
app_label = 'piston'
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"Nonce %s for %s" % (self.key, self.consumer_key)
|
return "Nonce %s for %s" % (self.key, self.consumer_key)
|
||||||
|
|
||||||
|
|
||||||
class Consumer(models.Model):
|
class Consumer(models.Model):
|
||||||
|
@ -52,7 +52,7 @@ class Consumer(models.Model):
|
||||||
app_label = 'piston'
|
app_label = 'piston'
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"Consumer %s with key %s" % (self.name, self.key)
|
return "Consumer %s with key %s" % (self.name, self.key)
|
||||||
|
|
||||||
def generate_random_codes(self):
|
def generate_random_codes(self):
|
||||||
"""
|
"""
|
||||||
|
@ -79,13 +79,13 @@ class Consumer(models.Model):
|
||||||
class Token(models.Model):
|
class Token(models.Model):
|
||||||
REQUEST = 1
|
REQUEST = 1
|
||||||
ACCESS = 2
|
ACCESS = 2
|
||||||
TOKEN_TYPES = ((REQUEST, u'Request'), (ACCESS, u'Access'))
|
TOKEN_TYPES = ((REQUEST, 'Request'), (ACCESS, 'Access'))
|
||||||
|
|
||||||
key = models.CharField(max_length=KEY_SIZE)
|
key = models.CharField(max_length=KEY_SIZE)
|
||||||
secret = models.CharField(max_length=SECRET_SIZE)
|
secret = models.CharField(max_length=SECRET_SIZE)
|
||||||
verifier = models.CharField(max_length=VERIFIER_SIZE)
|
verifier = models.CharField(max_length=VERIFIER_SIZE)
|
||||||
token_type = models.IntegerField(choices=TOKEN_TYPES)
|
token_type = models.IntegerField(choices=TOKEN_TYPES)
|
||||||
timestamp = models.IntegerField(default=long(time.time()))
|
timestamp = models.IntegerField(default=int(time.time()))
|
||||||
is_approved = models.BooleanField(default=False)
|
is_approved = models.BooleanField(default=False)
|
||||||
|
|
||||||
user = models.ForeignKey(User, null=True, blank=True, related_name='tokens')
|
user = models.ForeignKey(User, null=True, blank=True, related_name='tokens')
|
||||||
|
@ -100,7 +100,7 @@ class Token(models.Model):
|
||||||
app_label = 'piston'
|
app_label = 'piston'
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s Token %s for %s" % (self.get_token_type_display(), self.key, self.consumer)
|
return "%s Token %s for %s" % (self.get_token_type_display(), self.key, self.consumer)
|
||||||
|
|
||||||
def to_string(self, only_key=False):
|
def to_string(self, only_key=False):
|
||||||
token_dict = {
|
token_dict = {
|
||||||
|
@ -115,7 +115,7 @@ class Token(models.Model):
|
||||||
if only_key:
|
if only_key:
|
||||||
del token_dict['oauth_token_secret']
|
del token_dict['oauth_token_secret']
|
||||||
|
|
||||||
return urllib.urlencode(token_dict)
|
return urllib.parse.urlencode(token_dict)
|
||||||
|
|
||||||
def generate_random_codes(self):
|
def generate_random_codes(self):
|
||||||
key = User.objects.make_random_password(length=KEY_SIZE)
|
key = User.objects.make_random_password(length=KEY_SIZE)
|
||||||
|
@ -133,13 +133,13 @@ class Token(models.Model):
|
||||||
def get_callback_url(self):
|
def get_callback_url(self):
|
||||||
if self.callback and self.verifier:
|
if self.callback and self.verifier:
|
||||||
# Append the oauth_verifier.
|
# Append the oauth_verifier.
|
||||||
parts = urlparse.urlparse(self.callback)
|
parts = urllib.parse.urlparse(self.callback)
|
||||||
scheme, netloc, path, params, query, fragment = parts[:6]
|
scheme, netloc, path, params, query, fragment = parts[:6]
|
||||||
if query:
|
if query:
|
||||||
query = '%s&oauth_verifier=%s' % (query, self.verifier)
|
query = '%s&oauth_verifier=%s' % (query, self.verifier)
|
||||||
else:
|
else:
|
||||||
query = 'oauth_verifier=%s' % self.verifier
|
query = 'oauth_verifier=%s' % self.verifier
|
||||||
return urlparse.urlunparse((scheme, netloc, path, params,
|
return urllib.parse.urlunparse((scheme, netloc, path, params,
|
||||||
query, fragment))
|
query, fragment))
|
||||||
return self.callback
|
return self.callback
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,10 @@ THE SOFTWARE.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import cgi
|
import cgi
|
||||||
import urllib
|
import urllib.request, urllib.parse, urllib.error
|
||||||
import time
|
import time
|
||||||
import random
|
import random
|
||||||
import urlparse
|
import urllib.parse
|
||||||
import hmac
|
import hmac
|
||||||
import binascii
|
import binascii
|
||||||
|
|
||||||
|
@ -47,11 +47,11 @@ def build_authenticate_header(realm=''):
|
||||||
|
|
||||||
def escape(s):
|
def escape(s):
|
||||||
"""Escape a URL including any /."""
|
"""Escape a URL including any /."""
|
||||||
return urllib.quote(s, safe='~')
|
return urllib.parse.quote(s, safe='~')
|
||||||
|
|
||||||
def _utf8_str(s):
|
def _utf8_str(s):
|
||||||
"""Convert unicode to utf-8."""
|
"""Convert unicode to utf-8."""
|
||||||
if isinstance(s, unicode):
|
if isinstance(s, str):
|
||||||
return s.encode("utf-8")
|
return s.encode("utf-8")
|
||||||
else:
|
else:
|
||||||
return str(s)
|
return str(s)
|
||||||
|
@ -115,13 +115,13 @@ class OAuthToken(object):
|
||||||
def get_callback_url(self):
|
def get_callback_url(self):
|
||||||
if self.callback and self.verifier:
|
if self.callback and self.verifier:
|
||||||
# Append the oauth_verifier.
|
# Append the oauth_verifier.
|
||||||
parts = urlparse.urlparse(self.callback)
|
parts = urllib.parse.urlparse(self.callback)
|
||||||
scheme, netloc, path, params, query, fragment = parts[:6]
|
scheme, netloc, path, params, query, fragment = parts[:6]
|
||||||
if query:
|
if query:
|
||||||
query = '%s&oauth_verifier=%s' % (query, self.verifier)
|
query = '%s&oauth_verifier=%s' % (query, self.verifier)
|
||||||
else:
|
else:
|
||||||
query = 'oauth_verifier=%s' % self.verifier
|
query = 'oauth_verifier=%s' % self.verifier
|
||||||
return urlparse.urlunparse((scheme, netloc, path, params,
|
return urllib.parse.urlunparse((scheme, netloc, path, params,
|
||||||
query, fragment))
|
query, fragment))
|
||||||
return self.callback
|
return self.callback
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ class OAuthToken(object):
|
||||||
}
|
}
|
||||||
if self.callback_confirmed is not None:
|
if self.callback_confirmed is not None:
|
||||||
data['oauth_callback_confirmed'] = self.callback_confirmed
|
data['oauth_callback_confirmed'] = self.callback_confirmed
|
||||||
return urllib.urlencode(data)
|
return urllib.parse.urlencode(data)
|
||||||
|
|
||||||
def from_string(s):
|
def from_string(s):
|
||||||
""" Returns a token from something like:
|
""" Returns a token from something like:
|
||||||
|
@ -193,7 +193,7 @@ class OAuthRequest(object):
|
||||||
def get_nonoauth_parameters(self):
|
def get_nonoauth_parameters(self):
|
||||||
"""Get any non-OAuth parameters."""
|
"""Get any non-OAuth parameters."""
|
||||||
parameters = {}
|
parameters = {}
|
||||||
for k, v in self.parameters.iteritems():
|
for k, v in self.parameters.items():
|
||||||
# Ignore oauth parameters.
|
# Ignore oauth parameters.
|
||||||
if k.find('oauth_') < 0:
|
if k.find('oauth_') < 0:
|
||||||
parameters[k] = v
|
parameters[k] = v
|
||||||
|
@ -204,7 +204,7 @@ class OAuthRequest(object):
|
||||||
auth_header = 'OAuth realm="%s"' % realm
|
auth_header = 'OAuth realm="%s"' % realm
|
||||||
# Add the oauth parameters.
|
# Add the oauth parameters.
|
||||||
if self.parameters:
|
if self.parameters:
|
||||||
for k, v in self.parameters.iteritems():
|
for k, v in self.parameters.items():
|
||||||
if k[:6] == 'oauth_':
|
if k[:6] == 'oauth_':
|
||||||
auth_header += ', %s="%s"' % (k, escape(str(v)))
|
auth_header += ', %s="%s"' % (k, escape(str(v)))
|
||||||
return {'Authorization': auth_header}
|
return {'Authorization': auth_header}
|
||||||
|
@ -212,7 +212,7 @@ class OAuthRequest(object):
|
||||||
def to_postdata(self):
|
def to_postdata(self):
|
||||||
"""Serialize as post data for a POST request."""
|
"""Serialize as post data for a POST request."""
|
||||||
return '&'.join(['%s=%s' % (escape(str(k)), escape(str(v))) \
|
return '&'.join(['%s=%s' % (escape(str(k)), escape(str(v))) \
|
||||||
for k, v in self.parameters.iteritems()])
|
for k, v in self.parameters.items()])
|
||||||
|
|
||||||
def to_url(self):
|
def to_url(self):
|
||||||
"""Serialize as a URL for a GET request."""
|
"""Serialize as a URL for a GET request."""
|
||||||
|
@ -228,7 +228,7 @@ class OAuthRequest(object):
|
||||||
pass
|
pass
|
||||||
# Escape key values before sorting.
|
# Escape key values before sorting.
|
||||||
key_values = [(escape(_utf8_str(k)), escape(_utf8_str(v))) \
|
key_values = [(escape(_utf8_str(k)), escape(_utf8_str(v))) \
|
||||||
for k,v in params.items()]
|
for k,v in list(params.items())]
|
||||||
# Sort lexicographically, first after key, then after value.
|
# Sort lexicographically, first after key, then after value.
|
||||||
key_values.sort()
|
key_values.sort()
|
||||||
# Combine key value pairs into a string.
|
# Combine key value pairs into a string.
|
||||||
|
@ -240,7 +240,7 @@ class OAuthRequest(object):
|
||||||
|
|
||||||
def get_normalized_http_url(self):
|
def get_normalized_http_url(self):
|
||||||
"""Parses the URL and rebuilds it to be scheme://host/path."""
|
"""Parses the URL and rebuilds it to be scheme://host/path."""
|
||||||
parts = urlparse.urlparse(self.http_url)
|
parts = urllib.parse.urlparse(self.http_url)
|
||||||
scheme, netloc, path = parts[:3]
|
scheme, netloc, path = parts[:3]
|
||||||
# Exclude default port numbers.
|
# Exclude default port numbers.
|
||||||
if scheme == 'http' and netloc[-3:] == ':80':
|
if scheme == 'http' and netloc[-3:] == ':80':
|
||||||
|
@ -288,7 +288,7 @@ class OAuthRequest(object):
|
||||||
parameters.update(query_params)
|
parameters.update(query_params)
|
||||||
|
|
||||||
# URL parameters.
|
# URL parameters.
|
||||||
param_str = urlparse.urlparse(http_url)[4] # query
|
param_str = urllib.parse.urlparse(http_url)[4] # query
|
||||||
url_params = OAuthRequest._split_url_string(param_str)
|
url_params = OAuthRequest._split_url_string(param_str)
|
||||||
parameters.update(url_params)
|
parameters.update(url_params)
|
||||||
|
|
||||||
|
@ -352,15 +352,15 @@ class OAuthRequest(object):
|
||||||
# Split key-value.
|
# Split key-value.
|
||||||
param_parts = param.split('=', 1)
|
param_parts = param.split('=', 1)
|
||||||
# Remove quotes and unescape the value.
|
# Remove quotes and unescape the value.
|
||||||
params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"'))
|
params[param_parts[0]] = urllib.parse.unquote(param_parts[1].strip('\"'))
|
||||||
return params
|
return params
|
||||||
_split_header = staticmethod(_split_header)
|
_split_header = staticmethod(_split_header)
|
||||||
|
|
||||||
def _split_url_string(param_str):
|
def _split_url_string(param_str):
|
||||||
"""Turn URL string into parameters."""
|
"""Turn URL string into parameters."""
|
||||||
parameters = cgi.parse_qs(param_str, keep_blank_values=False)
|
parameters = cgi.parse_qs(param_str, keep_blank_values=False)
|
||||||
for k, v in parameters.iteritems():
|
for k, v in parameters.items():
|
||||||
parameters[k] = urllib.unquote(v[0])
|
parameters[k] = urllib.parse.unquote(v[0])
|
||||||
return parameters
|
return parameters
|
||||||
_split_url_string = staticmethod(_split_url_string)
|
_split_url_string = staticmethod(_split_url_string)
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ class OAuthServer(object):
|
||||||
# Get the signature method object.
|
# Get the signature method object.
|
||||||
signature_method = self.signature_methods[signature_method]
|
signature_method = self.signature_methods[signature_method]
|
||||||
except:
|
except:
|
||||||
signature_method_names = ', '.join(self.signature_methods.keys())
|
signature_method_names = ', '.join(list(self.signature_methods.keys()))
|
||||||
raise OAuthError('Signature method %s not supported try one of the '
|
raise OAuthError('Signature method %s not supported try one of the '
|
||||||
'following: %s' % (signature_method, signature_method_names))
|
'following: %s' % (signature_method, signature_method_names))
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,13 @@ from django.core.mail import send_mail, EmailMessage
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
|
|
||||||
from emitters import Emitter
|
from .emitters import Emitter
|
||||||
from handler import typemapper
|
from .handler import typemapper
|
||||||
from doc import HandlerMethod
|
from .doc import HandlerMethod
|
||||||
from authentication import NoAuthentication
|
from .authentication import NoAuthentication
|
||||||
from utils import coerce_put_post, FormValidationError, HttpStatusCode
|
from .utils import coerce_put_post, FormValidationError, HttpStatusCode
|
||||||
from utils import rc, format_error, translate_mime, MimerDataException
|
from .utils import rc, format_error, translate_mime, MimerDataException
|
||||||
|
import collections
|
||||||
|
|
||||||
CHALLENGE = object()
|
CHALLENGE = object()
|
||||||
|
|
||||||
|
@ -30,8 +31,8 @@ class Resource(object):
|
||||||
'PUT': 'update', 'DELETE': 'delete' }
|
'PUT': 'update', 'DELETE': 'delete' }
|
||||||
|
|
||||||
def __init__(self, handler, authentication=None):
|
def __init__(self, handler, authentication=None):
|
||||||
if not callable(handler):
|
if not isinstance(handler, collections.Callable):
|
||||||
raise AttributeError, "Handler not callable."
|
raise AttributeError("Handler not callable.")
|
||||||
|
|
||||||
self.handler = handler()
|
self.handler = handler()
|
||||||
self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True)
|
self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True)
|
||||||
|
@ -86,10 +87,10 @@ class Resource(object):
|
||||||
if hasattr(self.handler, 'anonymous'):
|
if hasattr(self.handler, 'anonymous'):
|
||||||
anon = self.handler.anonymous
|
anon = self.handler.anonymous
|
||||||
|
|
||||||
if callable(anon):
|
if isinstance(anon, collections.Callable):
|
||||||
return anon
|
return anon
|
||||||
|
|
||||||
for klass in typemapper.keys():
|
for klass in list(typemapper.keys()):
|
||||||
if anon == klass.__name__:
|
if anon == klass.__name__:
|
||||||
return klass
|
return klass
|
||||||
|
|
||||||
|
@ -162,7 +163,7 @@ class Resource(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = meth(request, *args, **kwargs)
|
result = meth(request, *args, **kwargs)
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
result = self.error_handler(e, request, meth, em_format)
|
result = self.error_handler(e, request, meth, em_format)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -208,7 +209,7 @@ class Resource(object):
|
||||||
resp.streaming = self.stream
|
resp.streaming = self.stream
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
except HttpStatusCode, e:
|
except HttpStatusCode as e:
|
||||||
return e.response
|
return e.response
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -220,10 +221,10 @@ class Resource(object):
|
||||||
for method_type in ('GET', 'PUT', 'POST', 'DELETE'):
|
for method_type in ('GET', 'PUT', 'POST', 'DELETE'):
|
||||||
block = getattr(request, method_type, { })
|
block = getattr(request, method_type, { })
|
||||||
|
|
||||||
if True in [ k.startswith("oauth_") for k in block.keys() ]:
|
if True in [ k.startswith("oauth_") for k in list(block.keys()) ]:
|
||||||
sanitized = block.copy()
|
sanitized = block.copy()
|
||||||
|
|
||||||
for k in sanitized.keys():
|
for k in list(sanitized.keys()):
|
||||||
if k.startswith("oauth_"):
|
if k.startswith("oauth_"):
|
||||||
sanitized.pop(k)
|
sanitized.pop(k)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import django.dispatch
|
import django.dispatch
|
||||||
|
|
||||||
# Piston imports
|
# Piston imports
|
||||||
from utils import send_consumer_mail
|
from .utils import send_consumer_mail
|
||||||
|
|
||||||
def consumer_post_save(sender, instance, created, **kwargs):
|
def consumer_post_save(sender, instance, created, **kwargs):
|
||||||
send_consumer_mail(instance)
|
send_consumer_mail(instance)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import oauth
|
from . import oauth
|
||||||
|
|
||||||
from models import Nonce, Token, Consumer
|
from .models import Nonce, Token, Consumer
|
||||||
from models import generate_random, VERIFIER_SIZE
|
from .models import generate_random, VERIFIER_SIZE
|
||||||
|
|
||||||
class DataStore(oauth.OAuthDataStore):
|
class DataStore(oauth.OAuthDataStore):
|
||||||
"""Layer between Python OAuth and Django database."""
|
"""Layer between Python OAuth and Django database."""
|
||||||
|
|
|
@ -8,7 +8,7 @@ from piston import oauth
|
||||||
from piston.models import Consumer, Token
|
from piston.models import Consumer, Token
|
||||||
|
|
||||||
# 3rd/Python party imports
|
# 3rd/Python party imports
|
||||||
import httplib2, urllib, cgi
|
import httplib2, urllib.request, urllib.parse, urllib.error, cgi
|
||||||
|
|
||||||
URLENCODED_FORM_CONTENT = 'application/x-www-form-urlencoded'
|
URLENCODED_FORM_CONTENT = 'application/x-www-form-urlencoded'
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,11 @@ except ImportError:
|
||||||
import json as simplejson
|
import json as simplejson
|
||||||
|
|
||||||
# Piston imports
|
# Piston imports
|
||||||
from test import TestCase
|
from .test import TestCase
|
||||||
from models import Consumer
|
from .models import Consumer
|
||||||
from handler import BaseHandler
|
from .handler import BaseHandler
|
||||||
from utils import rc
|
from .utils import rc
|
||||||
from resource import Resource
|
from .resource import Resource
|
||||||
|
|
||||||
class ConsumerTest(TestCase):
|
class ConsumerTest(TestCase):
|
||||||
fixtures = ['models.json']
|
fixtures = ['models.json']
|
||||||
|
@ -51,12 +51,12 @@ class ConsumerTest(TestCase):
|
||||||
# If it's pending we should have two messages in the outbox; one
|
# If it's pending we should have two messages in the outbox; one
|
||||||
# to the consumer and one to the site admins.
|
# to the consumer and one to the site admins.
|
||||||
if len(settings.ADMINS):
|
if len(settings.ADMINS):
|
||||||
self.assertEquals(len(mail.outbox), 2)
|
self.assertEqual(len(mail.outbox), 2)
|
||||||
else:
|
else:
|
||||||
self.assertEquals(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
|
|
||||||
expected = "Your API Consumer for example.com is awaiting approval."
|
expected = "Your API Consumer for example.com is awaiting approval."
|
||||||
self.assertEquals(mail.outbox[0].subject, expected)
|
self.assertEqual(mail.outbox[0].subject, expected)
|
||||||
|
|
||||||
def test_delete_consumer(self):
|
def test_delete_consumer(self):
|
||||||
""" Ensure deleting a Consumer sends a cancel email """
|
""" Ensure deleting a Consumer sends a cancel email """
|
||||||
|
@ -71,9 +71,9 @@ class ConsumerTest(TestCase):
|
||||||
if not self._pre_test_email():
|
if not self._pre_test_email():
|
||||||
return
|
return
|
||||||
|
|
||||||
self.assertEquals(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
expected = "Your API Consumer for example.com has been canceled."
|
expected = "Your API Consumer for example.com has been canceled."
|
||||||
self.assertEquals(mail.outbox[0].subject, expected)
|
self.assertEqual(mail.outbox[0].subject, expected)
|
||||||
|
|
||||||
|
|
||||||
class CustomResponseWithStatusCodeTest(TestCase):
|
class CustomResponseWithStatusCodeTest(TestCase):
|
||||||
|
@ -103,12 +103,12 @@ class CustomResponseWithStatusCodeTest(TestCase):
|
||||||
request.method = 'POST'
|
request.method = 'POST'
|
||||||
response = resource(request, emitter_format='json')
|
response = resource(request, emitter_format='json')
|
||||||
|
|
||||||
self.assertEquals(201, response.status_code)
|
self.assertEqual(201, response.status_code)
|
||||||
self.assertTrue(response._is_string, "Expected response content to be a string")
|
self.assertTrue(response._is_string, "Expected response content to be a string")
|
||||||
|
|
||||||
# compare the original data dict with the json response
|
# compare the original data dict with the json response
|
||||||
# converted to a dict
|
# converted to a dict
|
||||||
self.assertEquals(response_data, simplejson.loads(response.content))
|
self.assertEqual(response_data, simplejson.loads(response.content))
|
||||||
|
|
||||||
|
|
||||||
class ErrorHandlerTest(TestCase):
|
class ErrorHandlerTest(TestCase):
|
||||||
|
@ -154,7 +154,7 @@ class ErrorHandlerTest(TestCase):
|
||||||
request.method = 'GET'
|
request.method = 'GET'
|
||||||
response = resource(request, emitter_format='json')
|
response = resource(request, emitter_format='json')
|
||||||
|
|
||||||
self.assertEquals(401, response.status_code)
|
self.assertEqual(401, response.status_code)
|
||||||
|
|
||||||
# verify the content we got back can be converted back to json
|
# verify the content we got back can be converted back to json
|
||||||
# and examine the dictionary keys all exist as expected
|
# and examine the dictionary keys all exist as expected
|
||||||
|
|
|
@ -10,7 +10,7 @@ from django.core.mail import send_mail, mail_admins
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.template import loader, TemplateDoesNotExist
|
from django.template import loader, TemplateDoesNotExist
|
||||||
from decorator import decorator
|
from .decorator import decorator
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ def get_version():
|
||||||
return __version__
|
return __version__
|
||||||
|
|
||||||
def format_error(error):
|
def format_error(error):
|
||||||
return u"Piston/%s (Django %s) crash report:\n\n%s" % \
|
return "Piston/%s (Django %s) crash report:\n\n%s" % \
|
||||||
(get_version(), django_version(), error)
|
(get_version(), django_version(), error)
|
||||||
|
|
||||||
class rc_factory(object):
|
class rc_factory(object):
|
||||||
|
@ -73,7 +73,7 @@ class rc_factory(object):
|
||||||
self['Content-Type'] = 'application/json'
|
self['Content-Type'] = 'application/json'
|
||||||
|
|
||||||
is_string = False
|
is_string = False
|
||||||
if not isinstance(content, basestring) and hasattr(content, '__iter__'):
|
if not isinstance(content, str) and hasattr(content, '__iter__'):
|
||||||
self._container = content
|
self._container = content
|
||||||
else:
|
else:
|
||||||
self._container = [content]
|
self._container = [content]
|
||||||
|
@ -235,7 +235,7 @@ class Mimer(object):
|
||||||
Gets a function ref to deserialize content
|
Gets a function ref to deserialize content
|
||||||
for a certain mimetype.
|
for a certain mimetype.
|
||||||
"""
|
"""
|
||||||
for loadee, mimes in Mimer.TYPES.iteritems():
|
for loadee, mimes in Mimer.TYPES.items():
|
||||||
for mime in mimes:
|
for mime in mimes:
|
||||||
if ctype.startswith(mime):
|
if ctype.startswith(mime):
|
||||||
return loadee
|
return loadee
|
||||||
|
@ -359,7 +359,7 @@ def send_consumer_mail(consumer):
|
||||||
mail_admins(_(subject), body, fail_silently=True)
|
mail_admins(_(subject), body, fail_silently=True)
|
||||||
|
|
||||||
if settings.DEBUG and consumer.user:
|
if settings.DEBUG and consumer.user:
|
||||||
print "Mail being sent, to=%s" % consumer.user.email
|
print("Mail being sent, to=%s" % consumer.user.email)
|
||||||
print "Subject: %s" % _(subject)
|
print("Subject: %s" % _(subject))
|
||||||
print body
|
print(body)
|
||||||
|
|
||||||
|
|
|
@ -60,9 +60,9 @@ def is_valid_javascript_identifier(identifier, escape=r'\u', ucd_cat=category):
|
||||||
if not identifier:
|
if not identifier:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not isinstance(identifier, unicode):
|
if not isinstance(identifier, str):
|
||||||
try:
|
try:
|
||||||
identifier = unicode(identifier, 'utf-8')
|
identifier = str(identifier, 'utf-8')
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -76,12 +76,12 @@ def is_valid_javascript_identifier(identifier, escape=r'\u', ucd_cat=category):
|
||||||
if len(segment) < 4:
|
if len(segment) < 4:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
add_char(unichr(int('0x' + segment[:4], 16)))
|
add_char(chr(int('0x' + segment[:4], 16)))
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
add_char(segment[4:])
|
add_char(segment[4:])
|
||||||
|
|
||||||
identifier = u''.join(new)
|
identifier = ''.join(new)
|
||||||
|
|
||||||
if is_reserved_js_word(identifier):
|
if is_reserved_js_word(identifier):
|
||||||
return False
|
return False
|
||||||
|
@ -103,11 +103,11 @@ def is_valid_javascript_identifier(identifier, escape=r'\u', ucd_cat=category):
|
||||||
def is_valid_jsonp_callback_value(value):
|
def is_valid_jsonp_callback_value(value):
|
||||||
"""Return whether the given ``value`` can be used as a JSON-P callback."""
|
"""Return whether the given ``value`` can be used as a JSON-P callback."""
|
||||||
|
|
||||||
for identifier in value.split(u'.'):
|
for identifier in value.split('.'):
|
||||||
while '[' in identifier:
|
while '[' in identifier:
|
||||||
if not has_valid_array_index(identifier):
|
if not has_valid_array_index(identifier):
|
||||||
return False
|
return False
|
||||||
identifier = replace_array_index(u'', identifier)
|
identifier = replace_array_index('', identifier)
|
||||||
if not is_valid_javascript_identifier(identifier):
|
if not is_valid_javascript_identifier(identifier):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -140,16 +140,16 @@ def test():
|
||||||
>>> is_valid_javascript_identifier('$210')
|
>>> is_valid_javascript_identifier('$210')
|
||||||
True
|
True
|
||||||
|
|
||||||
>>> is_valid_javascript_identifier(u'Stra\u00dfe')
|
>>> is_valid_javascript_identifier(u'Stra\\u00dfe')
|
||||||
True
|
True
|
||||||
|
|
||||||
>>> is_valid_javascript_identifier(r'\u0062') # u'b'
|
>>> is_valid_javascript_identifier(r'\\u0062') # u'b'
|
||||||
True
|
True
|
||||||
|
|
||||||
>>> is_valid_javascript_identifier(r'\u62')
|
>>> is_valid_javascript_identifier(r'\\u62')
|
||||||
False
|
False
|
||||||
|
|
||||||
>>> is_valid_javascript_identifier(r'\u0020')
|
>>> is_valid_javascript_identifier(r'\\u0020')
|
||||||
False
|
False
|
||||||
|
|
||||||
>>> is_valid_javascript_identifier('_bar')
|
>>> is_valid_javascript_identifier('_bar')
|
||||||
|
|
4
setup.py
4
setup.py
|
@ -8,11 +8,9 @@ except ImportError:
|
||||||
ez_setup.use_setuptools()
|
ez_setup.use_setuptools()
|
||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name = "django-piston",
|
name = "django-piston",
|
||||||
version = "0.2.3.sm12",
|
version = "1.0.0-yr.alpha", # version 1.0.0 supports python3
|
||||||
url = 'http://bitbucket.org/jespern/django-piston/wiki/Home',
|
url = 'http://bitbucket.org/jespern/django-piston/wiki/Home',
|
||||||
download_url = 'http://bitbucket.org/jespern/django-piston/downloads/',
|
download_url = 'http://bitbucket.org/jespern/django-piston/downloads/',
|
||||||
license = 'BSD',
|
license = 'BSD',
|
||||||
|
|
|
@ -20,7 +20,7 @@ use the -c option to specify an alternate configuration file.
|
||||||
$Id$
|
$Id$
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os, shutil, sys, tempfile, urllib2
|
import os, shutil, sys, tempfile, urllib.request, urllib.error, urllib.parse
|
||||||
|
|
||||||
tmpeggs = tempfile.mkdtemp()
|
tmpeggs = tempfile.mkdtemp()
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ try:
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
except ImportError:
|
except ImportError:
|
||||||
ez = {}
|
ez = {}
|
||||||
exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
|
exec(urllib.request.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
|
||||||
).read() in ez
|
).read(), ez)
|
||||||
ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
|
ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
|
||||||
|
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
|
@ -3,8 +3,8 @@ from django.core.paginator import Paginator
|
||||||
from piston.handler import BaseHandler
|
from piston.handler import BaseHandler
|
||||||
from piston.utils import rc, validate
|
from piston.utils import rc, validate
|
||||||
|
|
||||||
from models import TestModel, ExpressiveTestModel, Comment, InheritedModel, PlainOldObject, Issue58Model, ListFieldsModel
|
from .models import TestModel, ExpressiveTestModel, Comment, InheritedModel, PlainOldObject, Issue58Model, ListFieldsModel
|
||||||
from forms import EchoForm
|
from .forms import EchoForm
|
||||||
from test_project.apps.testapp import signals
|
from test_project.apps.testapp import signals
|
||||||
|
|
||||||
class EntryHandler(BaseHandler):
|
class EntryHandler(BaseHandler):
|
||||||
|
|
|
@ -14,10 +14,10 @@ from piston.forms import OAuthAuthenticationForm
|
||||||
try:
|
try:
|
||||||
import yaml
|
import yaml
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print "Can't run YAML testsuite"
|
print("Can't run YAML testsuite")
|
||||||
yaml = None
|
yaml = None
|
||||||
|
|
||||||
import urllib, base64
|
import urllib.request, urllib.parse, urllib.error, base64
|
||||||
|
|
||||||
from test_project.apps.testapp.models import TestModel, ExpressiveTestModel, Comment, InheritedModel, Issue58Model, ListFieldsModel
|
from test_project.apps.testapp.models import TestModel, ExpressiveTestModel, Comment, InheritedModel, Issue58Model, ListFieldsModel
|
||||||
from test_project.apps.testapp import signals
|
from test_project.apps.testapp import signals
|
||||||
|
@ -70,7 +70,7 @@ class OAuthTests(MainTests):
|
||||||
self.assertEqual(token.secret, oatoken.secret)
|
self.assertEqual(token.secret, oatoken.secret)
|
||||||
|
|
||||||
# Simulate user authentication...
|
# Simulate user authentication...
|
||||||
self.failUnless(self.client.login(username='admin', password='admin'))
|
self.assertTrue(self.client.login(username='admin', password='admin'))
|
||||||
request = oauth.OAuthRequest.from_token_and_callback(token=oatoken,
|
request = oauth.OAuthRequest.from_token_and_callback(token=oatoken,
|
||||||
callback='http://printer.example.com/request_token_ready',
|
callback='http://printer.example.com/request_token_ready',
|
||||||
http_url='http://testserver/api/oauth/authorize')
|
http_url='http://testserver/api/oauth/authorize')
|
||||||
|
@ -92,8 +92,8 @@ class OAuthTests(MainTests):
|
||||||
|
|
||||||
# Response should be a redirect...
|
# Response should be a redirect...
|
||||||
self.assertEqual(302, response.status_code)
|
self.assertEqual(302, response.status_code)
|
||||||
self.failUnless(response['Location'].startswith("http://printer.example.com/request_token_ready?"))
|
self.assertTrue(response['Location'].startswith("http://printer.example.com/request_token_ready?"))
|
||||||
self.failUnless(('oauth_token='+oatoken.key in response['Location']))
|
self.assertTrue(('oauth_token='+oatoken.key in response['Location']))
|
||||||
|
|
||||||
# Actually we can't test this last part, since it's 1.0a.
|
# Actually we can't test this last part, since it's 1.0a.
|
||||||
# Obtain access token...
|
# Obtain access token...
|
||||||
|
@ -110,25 +110,25 @@ class BasicAuthTest(MainTests):
|
||||||
|
|
||||||
def test_invalid_auth_header(self):
|
def test_invalid_auth_header(self):
|
||||||
response = self.client.get('/api/entries/')
|
response = self.client.get('/api/entries/')
|
||||||
self.assertEquals(response.status_code, 401)
|
self.assertEqual(response.status_code, 401)
|
||||||
|
|
||||||
# no space
|
# no space
|
||||||
bad_auth_string = 'Basic%s' % base64.encodestring('admin:admin').rstrip()
|
bad_auth_string = 'Basic%s' % base64.encodestring('admin:admin').rstrip()
|
||||||
response = self.client.get('/api/entries/',
|
response = self.client.get('/api/entries/',
|
||||||
HTTP_AUTHORIZATION=bad_auth_string)
|
HTTP_AUTHORIZATION=bad_auth_string)
|
||||||
self.assertEquals(response.status_code, 401)
|
self.assertEqual(response.status_code, 401)
|
||||||
|
|
||||||
# no colon
|
# no colon
|
||||||
bad_auth_string = 'Basic %s' % base64.encodestring('adminadmin').rstrip()
|
bad_auth_string = 'Basic %s' % base64.encodestring('adminadmin').rstrip()
|
||||||
response = self.client.get('/api/entries/',
|
response = self.client.get('/api/entries/',
|
||||||
HTTP_AUTHORIZATION=bad_auth_string)
|
HTTP_AUTHORIZATION=bad_auth_string)
|
||||||
self.assertEquals(response.status_code, 401)
|
self.assertEqual(response.status_code, 401)
|
||||||
|
|
||||||
# non base64 data
|
# non base64 data
|
||||||
bad_auth_string = 'Basic FOOBARQ!'
|
bad_auth_string = 'Basic FOOBARQ!'
|
||||||
response = self.client.get('/api/entries/',
|
response = self.client.get('/api/entries/',
|
||||||
HTTP_AUTHORIZATION=bad_auth_string)
|
HTTP_AUTHORIZATION=bad_auth_string)
|
||||||
self.assertEquals(response.status_code, 401)
|
self.assertEqual(response.status_code, 401)
|
||||||
|
|
||||||
class TestMultipleAuthenticators(MainTests):
|
class TestMultipleAuthenticators(MainTests):
|
||||||
def test_both_authenticators(self):
|
def test_both_authenticators(self):
|
||||||
|
@ -142,7 +142,7 @@ class TestMultipleAuthenticators(MainTests):
|
||||||
response = self.client.get('/api/multiauth/',
|
response = self.client.get('/api/multiauth/',
|
||||||
HTTP_AUTHORIZATION=auth_string)
|
HTTP_AUTHORIZATION=auth_string)
|
||||||
|
|
||||||
self.assertEquals(response.status_code, 200, 'Failed with combo of %s:%s' % (username, password))
|
self.assertEqual(response.status_code, 200, 'Failed with combo of %s:%s' % (username, password))
|
||||||
|
|
||||||
class MultiXMLTests(MainTests):
|
class MultiXMLTests(MainTests):
|
||||||
def init_delegate(self):
|
def init_delegate(self):
|
||||||
|
@ -155,14 +155,14 @@ class MultiXMLTests(MainTests):
|
||||||
expected = '<?xml version="1.0" encoding="utf-8"?>\n<response><resource><test1>None</test1><test2>None</test2></resource><resource><test1>None</test1><test2>None</test2></resource></response>'
|
expected = '<?xml version="1.0" encoding="utf-8"?>\n<response><resource><test1>None</test1><test2>None</test2></resource><resource><test1>None</test1><test2>None</test2></resource></response>'
|
||||||
result = self.client.get('/api/entries.xml',
|
result = self.client.get('/api/entries.xml',
|
||||||
HTTP_AUTHORIZATION=self.auth_string).content
|
HTTP_AUTHORIZATION=self.auth_string).content
|
||||||
self.assertEquals(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
def test_singlexml(self):
|
def test_singlexml(self):
|
||||||
obj = TestModel.objects.all()[0]
|
obj = TestModel.objects.all()[0]
|
||||||
expected = '<?xml version="1.0" encoding="utf-8"?>\n<response><test1>None</test1><test2>None</test2></response>'
|
expected = '<?xml version="1.0" encoding="utf-8"?>\n<response><test1>None</test1><test2>None</test2></response>'
|
||||||
result = self.client.get('/api/entry-%d.xml' % (obj.pk,),
|
result = self.client.get('/api/entry-%d.xml' % (obj.pk,),
|
||||||
HTTP_AUTHORIZATION=self.auth_string).content
|
HTTP_AUTHORIZATION=self.auth_string).content
|
||||||
self.assertEquals(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
class AbstractBaseClassTests(MainTests):
|
class AbstractBaseClassTests(MainTests):
|
||||||
def init_delegate(self):
|
def init_delegate(self):
|
||||||
|
@ -188,7 +188,7 @@ class AbstractBaseClassTests(MainTests):
|
||||||
}
|
}
|
||||||
]"""
|
]"""
|
||||||
|
|
||||||
self.assertEquals(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
def test_specific_id(self):
|
def test_specific_id(self):
|
||||||
ids = (1, 2)
|
ids = (1, 2)
|
||||||
|
@ -204,7 +204,7 @@ class AbstractBaseClassTests(MainTests):
|
||||||
|
|
||||||
expected = be % id_
|
expected = be % id_
|
||||||
|
|
||||||
self.assertEquals(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
class IncomingExpressiveTests(MainTests):
|
class IncomingExpressiveTests(MainTests):
|
||||||
def init_delegate(self):
|
def init_delegate(self):
|
||||||
|
@ -234,12 +234,12 @@ class IncomingExpressiveTests(MainTests):
|
||||||
result = self.client.get('/api/expressive.json',
|
result = self.client.get('/api/expressive.json',
|
||||||
HTTP_AUTHORIZATION=self.auth_string).content
|
HTTP_AUTHORIZATION=self.auth_string).content
|
||||||
|
|
||||||
self.assertEquals(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
resp = self.client.post('/api/expressive.json', outgoing, content_type='application/json',
|
resp = self.client.post('/api/expressive.json', outgoing, content_type='application/json',
|
||||||
HTTP_AUTHORIZATION=self.auth_string)
|
HTTP_AUTHORIZATION=self.auth_string)
|
||||||
|
|
||||||
self.assertEquals(resp.status_code, 201)
|
self.assertEqual(resp.status_code, 201)
|
||||||
|
|
||||||
expected = """[
|
expected = """[
|
||||||
{
|
{
|
||||||
|
@ -269,14 +269,14 @@ class IncomingExpressiveTests(MainTests):
|
||||||
result = self.client.get('/api/expressive.json',
|
result = self.client.get('/api/expressive.json',
|
||||||
HTTP_AUTHORIZATION=self.auth_string).content
|
HTTP_AUTHORIZATION=self.auth_string).content
|
||||||
|
|
||||||
self.assertEquals(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
def test_incoming_invalid_json(self):
|
def test_incoming_invalid_json(self):
|
||||||
resp = self.client.post('/api/expressive.json',
|
resp = self.client.post('/api/expressive.json',
|
||||||
'foo',
|
'foo',
|
||||||
HTTP_AUTHORIZATION=self.auth_string,
|
HTTP_AUTHORIZATION=self.auth_string,
|
||||||
content_type='application/json')
|
content_type='application/json')
|
||||||
self.assertEquals(resp.status_code, 400)
|
self.assertEqual(resp.status_code, 400)
|
||||||
|
|
||||||
def test_incoming_yaml(self):
|
def test_incoming_yaml(self):
|
||||||
if not yaml:
|
if not yaml:
|
||||||
|
@ -290,7 +290,7 @@ class IncomingExpressiveTests(MainTests):
|
||||||
title: foo2
|
title: foo2
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.assertEquals(self.client.get('/api/expressive.yaml',
|
self.assertEqual(self.client.get('/api/expressive.yaml',
|
||||||
HTTP_AUTHORIZATION=self.auth_string).content, expected)
|
HTTP_AUTHORIZATION=self.auth_string).content, expected)
|
||||||
|
|
||||||
outgoing = yaml.dump({ 'title': 'test', 'content': 'test',
|
outgoing = yaml.dump({ 'title': 'test', 'content': 'test',
|
||||||
|
@ -300,7 +300,7 @@ class IncomingExpressiveTests(MainTests):
|
||||||
resp = self.client.post('/api/expressive.json', outgoing, content_type='application/x-yaml',
|
resp = self.client.post('/api/expressive.json', outgoing, content_type='application/x-yaml',
|
||||||
HTTP_AUTHORIZATION=self.auth_string)
|
HTTP_AUTHORIZATION=self.auth_string)
|
||||||
|
|
||||||
self.assertEquals(resp.status_code, 201)
|
self.assertEqual(resp.status_code, 201)
|
||||||
|
|
||||||
expected = """- comments: []
|
expected = """- comments: []
|
||||||
content: bar
|
content: bar
|
||||||
|
@ -314,7 +314,7 @@ class IncomingExpressiveTests(MainTests):
|
||||||
content: test
|
content: test
|
||||||
title: test
|
title: test
|
||||||
"""
|
"""
|
||||||
self.assertEquals(self.client.get('/api/expressive.yaml',
|
self.assertEqual(self.client.get('/api/expressive.yaml',
|
||||||
HTTP_AUTHORIZATION=self.auth_string).content, expected)
|
HTTP_AUTHORIZATION=self.auth_string).content, expected)
|
||||||
|
|
||||||
def test_incoming_invalid_yaml(self):
|
def test_incoming_invalid_yaml(self):
|
||||||
|
@ -322,7 +322,7 @@ class IncomingExpressiveTests(MainTests):
|
||||||
' 8**sad asj lja foo',
|
' 8**sad asj lja foo',
|
||||||
HTTP_AUTHORIZATION=self.auth_string,
|
HTTP_AUTHORIZATION=self.auth_string,
|
||||||
content_type='application/x-yaml')
|
content_type='application/x-yaml')
|
||||||
self.assertEquals(resp.status_code, 400)
|
self.assertEqual(resp.status_code, 400)
|
||||||
|
|
||||||
class Issue36RegressionTests(MainTests):
|
class Issue36RegressionTests(MainTests):
|
||||||
"""
|
"""
|
||||||
|
@ -352,7 +352,7 @@ class Issue36RegressionTests(MainTests):
|
||||||
try:
|
try:
|
||||||
response = self.client.post('/api/entries.xml',
|
response = self.client.post('/api/entries.xml',
|
||||||
{'file':fp}, HTTP_AUTHORIZATION=self.auth_string)
|
{'file':fp}, HTTP_AUTHORIZATION=self.auth_string)
|
||||||
self.assertEquals(1, len(self.request.FILES), 'request.FILES on POST is empty when it should contain 1 file')
|
self.assertEqual(1, len(self.request.FILES), 'request.FILES on POST is empty when it should contain 1 file')
|
||||||
finally:
|
finally:
|
||||||
fp.close()
|
fp.close()
|
||||||
|
|
||||||
|
@ -366,29 +366,29 @@ class Issue36RegressionTests(MainTests):
|
||||||
try:
|
try:
|
||||||
response = self.client.put('/api/entry-%d.xml' % self.data.pk,
|
response = self.client.put('/api/entry-%d.xml' % self.data.pk,
|
||||||
{'file': fp}, HTTP_AUTHORIZATION=self.auth_string)
|
{'file': fp}, HTTP_AUTHORIZATION=self.auth_string)
|
||||||
self.assertEquals(1, len(self.request.FILES), 'request.FILES on PUT is empty when it should contain 1 file')
|
self.assertEqual(1, len(self.request.FILES), 'request.FILES on PUT is empty when it should contain 1 file')
|
||||||
finally:
|
finally:
|
||||||
fp.close()
|
fp.close()
|
||||||
|
|
||||||
class ValidationTest(MainTests):
|
class ValidationTest(MainTests):
|
||||||
def test_basic_validation_fails(self):
|
def test_basic_validation_fails(self):
|
||||||
resp = self.client.get('/api/echo')
|
resp = self.client.get('/api/echo')
|
||||||
self.assertEquals(resp.status_code, 400)
|
self.assertEqual(resp.status_code, 400)
|
||||||
self.assertEquals(resp.content, 'Bad Request <ul class="errorlist">'
|
self.assertEqual(resp.content, 'Bad Request <ul class="errorlist">'
|
||||||
'<li>msg<ul class="errorlist"><li>This field is required.</li>'
|
'<li>msg<ul class="errorlist"><li>This field is required.</li>'
|
||||||
'</ul></li></ul>')
|
'</ul></li></ul>')
|
||||||
|
|
||||||
def test_basic_validation_succeeds(self):
|
def test_basic_validation_succeeds(self):
|
||||||
data = {'msg': 'donuts!'}
|
data = {'msg': 'donuts!'}
|
||||||
resp = self.client.get('/api/echo', data)
|
resp = self.client.get('/api/echo', data)
|
||||||
self.assertEquals(resp.status_code, 200)
|
self.assertEqual(resp.status_code, 200)
|
||||||
self.assertEquals(data, simplejson.loads(resp.content))
|
self.assertEqual(data, simplejson.loads(resp.content))
|
||||||
|
|
||||||
class PlainOldObject(MainTests):
|
class PlainOldObject(MainTests):
|
||||||
def test_plain_object_serialization(self):
|
def test_plain_object_serialization(self):
|
||||||
resp = self.client.get('/api/popo')
|
resp = self.client.get('/api/popo')
|
||||||
self.assertEquals(resp.status_code, 200)
|
self.assertEqual(resp.status_code, 200)
|
||||||
self.assertEquals({'type': 'plain', 'field': 'a field'}, simplejson.loads(resp.content))
|
self.assertEqual({'type': 'plain', 'field': 'a field'}, simplejson.loads(resp.content))
|
||||||
|
|
||||||
class ListFieldsTest(MainTests):
|
class ListFieldsTest(MainTests):
|
||||||
def init_delegate(self):
|
def init_delegate(self):
|
||||||
|
@ -404,8 +404,8 @@ class ListFieldsTest(MainTests):
|
||||||
"variety": "apple"
|
"variety": "apple"
|
||||||
}'''
|
}'''
|
||||||
resp = self.client.get('/api/list_fields/1')
|
resp = self.client.get('/api/list_fields/1')
|
||||||
self.assertEquals(resp.status_code, 200)
|
self.assertEqual(resp.status_code, 200)
|
||||||
self.assertEquals(resp.content, expect)
|
self.assertEqual(resp.content, expect)
|
||||||
|
|
||||||
|
|
||||||
def test_multiple_items(self):
|
def test_multiple_items(self):
|
||||||
|
@ -424,22 +424,22 @@ class ListFieldsTest(MainTests):
|
||||||
}
|
}
|
||||||
]'''
|
]'''
|
||||||
resp = self.client.get('/api/list_fields')
|
resp = self.client.get('/api/list_fields')
|
||||||
self.assertEquals(resp.status_code, 200)
|
self.assertEqual(resp.status_code, 200)
|
||||||
self.assertEquals(resp.content, expect)
|
self.assertEqual(resp.content, expect)
|
||||||
|
|
||||||
class ErrorHandlingTests(MainTests):
|
class ErrorHandlingTests(MainTests):
|
||||||
"""Test proper handling of errors by Resource"""
|
"""Test proper handling of errors by Resource"""
|
||||||
|
|
||||||
def test_response_not_allowed(self):
|
def test_response_not_allowed(self):
|
||||||
resp = self.client.post('/api/echo')
|
resp = self.client.post('/api/echo')
|
||||||
self.assertEquals(resp.status_code, 405)
|
self.assertEqual(resp.status_code, 405)
|
||||||
self.assertEquals(resp['Allow'], 'GET, HEAD')
|
self.assertEqual(resp['Allow'], 'GET, HEAD')
|
||||||
|
|
||||||
def test_not_found_because_of_unexpected_http_method(self):
|
def test_not_found_because_of_unexpected_http_method(self):
|
||||||
# not using self.client.head because it is not present in Django 1.0
|
# not using self.client.head because it is not present in Django 1.0
|
||||||
resp = self.client.get('/api/echo', REQUEST_METHOD='HEAD')
|
resp = self.client.get('/api/echo', REQUEST_METHOD='HEAD')
|
||||||
self.assertEquals(resp.status_code, 404)
|
self.assertEqual(resp.status_code, 404)
|
||||||
self.assertEquals(resp.content, '')
|
self.assertEqual(resp.content, '')
|
||||||
|
|
||||||
|
|
||||||
class Issue58ModelTests(MainTests):
|
class Issue58ModelTests(MainTests):
|
||||||
|
@ -471,9 +471,9 @@ class Issue58ModelTests(MainTests):
|
||||||
# test GET
|
# test GET
|
||||||
result = self.client.get('/api/issue58.json',
|
result = self.client.get('/api/issue58.json',
|
||||||
HTTP_AUTHORIZATION=self.auth_string).content
|
HTTP_AUTHORIZATION=self.auth_string).content
|
||||||
self.assertEquals(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
# test POST
|
# test POST
|
||||||
resp = self.client.post('/api/issue58.json', outgoing, content_type='application/json',
|
resp = self.client.post('/api/issue58.json', outgoing, content_type='application/json',
|
||||||
HTTP_AUTHORIZATION=self.auth_string)
|
HTTP_AUTHORIZATION=self.auth_string)
|
||||||
self.assertEquals(resp.status_code, 201)
|
self.assertEqual(resp.status_code, 201)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче