mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-17 07:41:26 +00:00
add djangorestframework
This commit is contained in:
175
thirdpart/djangorestframework/utils/__init__.py
Normal file
175
thirdpart/djangorestframework/utils/__init__.py
Normal file
@@ -0,0 +1,175 @@
|
||||
from django.utils.encoding import smart_unicode
|
||||
from django.utils.xmlutils import SimplerXMLGenerator
|
||||
from django.core.urlresolvers import resolve
|
||||
from django.conf import settings
|
||||
|
||||
from djangorestframework.compat import StringIO
|
||||
|
||||
import re
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
|
||||
#def admin_media_prefix(request):
|
||||
# """Adds the ADMIN_MEDIA_PREFIX to the request context."""
|
||||
# return {'ADMIN_MEDIA_PREFIX': settings.ADMIN_MEDIA_PREFIX}
|
||||
|
||||
from mediatypes import media_type_matches, is_form_media_type
|
||||
from mediatypes import add_media_type_param, get_media_type_params, order_by_precedence
|
||||
|
||||
MSIE_USER_AGENT_REGEX = re.compile(r'^Mozilla/[0-9]+\.[0-9]+ \([^)]*; MSIE [0-9]+\.[0-9]+[a-z]?;[^)]*\)(?!.* Opera )')
|
||||
|
||||
def as_tuple(obj):
|
||||
"""
|
||||
Given an object which may be a list/tuple, another object, or None,
|
||||
return that object in list form.
|
||||
|
||||
IE:
|
||||
If the object is already a list/tuple just return it.
|
||||
If the object is not None, return it in a list with a single element.
|
||||
If the object is None return an empty list.
|
||||
"""
|
||||
if obj is None:
|
||||
return ()
|
||||
elif isinstance(obj, list):
|
||||
return tuple(obj)
|
||||
elif isinstance(obj, tuple):
|
||||
return obj
|
||||
return (obj,)
|
||||
|
||||
|
||||
def url_resolves(url):
|
||||
"""
|
||||
Return True if the given URL is mapped to a view in the urlconf, False otherwise.
|
||||
"""
|
||||
try:
|
||||
resolve(url)
|
||||
except Exception:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
# From http://www.koders.com/python/fidB6E125C586A6F49EAC38992CF3AFDAAE35651975.aspx?s=mdef:xml
|
||||
#class object_dict(dict):
|
||||
# """object view of dict, you can
|
||||
# >>> a = object_dict()
|
||||
# >>> a.fish = 'fish'
|
||||
# >>> a['fish']
|
||||
# 'fish'
|
||||
# >>> a['water'] = 'water'
|
||||
# >>> a.water
|
||||
# 'water'
|
||||
# >>> a.test = {'value': 1}
|
||||
# >>> a.test2 = object_dict({'name': 'test2', 'value': 2})
|
||||
# >>> a.test, a.test2.name, a.test2.value
|
||||
# (1, 'test2', 2)
|
||||
# """
|
||||
# def __init__(self, initd=None):
|
||||
# if initd is None:
|
||||
# initd = {}
|
||||
# dict.__init__(self, initd)
|
||||
#
|
||||
# def __getattr__(self, item):
|
||||
# d = self.__getitem__(item)
|
||||
# # if value is the only key in object, you can omit it
|
||||
# if isinstance(d, dict) and 'value' in d and len(d) == 1:
|
||||
# return d['value']
|
||||
# else:
|
||||
# return d
|
||||
#
|
||||
# def __setattr__(self, item, value):
|
||||
# self.__setitem__(item, value)
|
||||
|
||||
|
||||
# From xml2dict
|
||||
class XML2Dict(object):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def _parse_node(self, node):
|
||||
node_tree = {}
|
||||
# Save attrs and text, hope there will not be a child with same name
|
||||
if node.text:
|
||||
node_tree = node.text
|
||||
for (k,v) in node.attrib.items():
|
||||
k,v = self._namespace_split(k, v)
|
||||
node_tree[k] = v
|
||||
#Save childrens
|
||||
for child in node.getchildren():
|
||||
tag, tree = self._namespace_split(child.tag, self._parse_node(child))
|
||||
if tag not in node_tree: # the first time, so store it in dict
|
||||
node_tree[tag] = tree
|
||||
continue
|
||||
old = node_tree[tag]
|
||||
if not isinstance(old, list):
|
||||
node_tree.pop(tag)
|
||||
node_tree[tag] = [old] # multi times, so change old dict to a list
|
||||
node_tree[tag].append(tree) # add the new one
|
||||
|
||||
return node_tree
|
||||
|
||||
|
||||
def _namespace_split(self, tag, value):
|
||||
"""
|
||||
Split the tag '{http://cs.sfsu.edu/csc867/myscheduler}patients'
|
||||
ns = http://cs.sfsu.edu/csc867/myscheduler
|
||||
name = patients
|
||||
"""
|
||||
result = re.compile("\{(.*)\}(.*)").search(tag)
|
||||
if result:
|
||||
value.namespace, tag = result.groups()
|
||||
return (tag, value)
|
||||
|
||||
def parse(self, file):
|
||||
"""parse a xml file to a dict"""
|
||||
f = open(file, 'r')
|
||||
return self.fromstring(f.read())
|
||||
|
||||
def fromstring(self, s):
|
||||
"""parse a string"""
|
||||
t = ET.fromstring(s)
|
||||
unused_root_tag, root_tree = self._namespace_split(t.tag, self._parse_node(t))
|
||||
return root_tree
|
||||
|
||||
|
||||
def xml2dict(input):
|
||||
return XML2Dict().fromstring(input)
|
||||
|
||||
|
||||
# Piston:
|
||||
class XMLRenderer():
|
||||
def _to_xml(self, xml, data):
|
||||
if isinstance(data, (list, tuple)):
|
||||
for item in data:
|
||||
xml.startElement("list-item", {})
|
||||
self._to_xml(xml, item)
|
||||
xml.endElement("list-item")
|
||||
|
||||
elif isinstance(data, dict):
|
||||
for key, value in data.iteritems():
|
||||
xml.startElement(key, {})
|
||||
self._to_xml(xml, value)
|
||||
xml.endElement(key)
|
||||
|
||||
elif data is None:
|
||||
# Don't output any value
|
||||
pass
|
||||
|
||||
else:
|
||||
xml.characters(smart_unicode(data))
|
||||
|
||||
def dict2xml(self, data):
|
||||
stream = StringIO.StringIO()
|
||||
|
||||
xml = SimplerXMLGenerator(stream, "utf-8")
|
||||
xml.startDocument()
|
||||
xml.startElement("root", {})
|
||||
|
||||
self._to_xml(xml, data)
|
||||
|
||||
xml.endElement("root")
|
||||
xml.endDocument()
|
||||
return stream.getvalue()
|
||||
|
||||
def dict2xml(input):
|
||||
return XMLRenderer().dict2xml(input)
|
32
thirdpart/djangorestframework/utils/breadcrumbs.py
Normal file
32
thirdpart/djangorestframework/utils/breadcrumbs.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from django.core.urlresolvers import resolve
|
||||
|
||||
def get_breadcrumbs(url):
|
||||
"""Given a url returns a list of breadcrumbs, which are each a tuple of (name, url)."""
|
||||
|
||||
from djangorestframework.views import View
|
||||
|
||||
def breadcrumbs_recursive(url, breadcrumbs_list):
|
||||
"""Add tuples of (name, url) to the breadcrumbs list, progressively chomping off parts of the url."""
|
||||
|
||||
try:
|
||||
(view, unused_args, unused_kwargs) = resolve(url)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
# Check if this is a REST framework view, and if so add it to the breadcrumbs
|
||||
if isinstance(getattr(view, 'cls_instance', None), View):
|
||||
breadcrumbs_list.insert(0, (view.cls_instance.get_name(), url))
|
||||
|
||||
if url == '':
|
||||
# All done
|
||||
return breadcrumbs_list
|
||||
|
||||
elif url.endswith('/'):
|
||||
# Drop trailing slash off the end and continue to try to resolve more breadcrumbs
|
||||
return breadcrumbs_recursive(url.rstrip('/'), breadcrumbs_list)
|
||||
|
||||
# Drop trailing non-slash off the end and continue to try to resolve more breadcrumbs
|
||||
return breadcrumbs_recursive(url[:url.rfind('/') + 1], breadcrumbs_list)
|
||||
|
||||
return breadcrumbs_recursive(url, [])
|
||||
|
113
thirdpart/djangorestframework/utils/mediatypes.py
Normal file
113
thirdpart/djangorestframework/utils/mediatypes.py
Normal file
@@ -0,0 +1,113 @@
|
||||
"""
|
||||
Handling of media types, as found in HTTP Content-Type and Accept headers.
|
||||
|
||||
See http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
|
||||
"""
|
||||
|
||||
from django.http.multipartparser import parse_header
|
||||
|
||||
|
||||
def media_type_matches(lhs, rhs):
|
||||
"""
|
||||
Returns ``True`` if the media type in the first argument <= the
|
||||
media type in the second argument. The media types are strings
|
||||
as described by the HTTP spec.
|
||||
|
||||
Valid media type strings include:
|
||||
|
||||
'application/json; indent=4'
|
||||
'application/json'
|
||||
'text/*'
|
||||
'*/*'
|
||||
"""
|
||||
lhs = _MediaType(lhs)
|
||||
rhs = _MediaType(rhs)
|
||||
return lhs.match(rhs)
|
||||
|
||||
|
||||
def is_form_media_type(media_type):
|
||||
"""
|
||||
Return True if the media type is a valid form media type as defined by the HTML4 spec.
|
||||
(NB. HTML5 also adds text/plain to the list of valid form media types, but we don't support this here)
|
||||
"""
|
||||
media_type = _MediaType(media_type)
|
||||
return media_type.full_type == 'application/x-www-form-urlencoded' or \
|
||||
media_type.full_type == 'multipart/form-data'
|
||||
|
||||
|
||||
def add_media_type_param(media_type, key, val):
|
||||
"""
|
||||
Add a key, value parameter to a media type string, and return the new media type string.
|
||||
"""
|
||||
media_type = _MediaType(media_type)
|
||||
media_type.params[key] = val
|
||||
return str(media_type)
|
||||
|
||||
|
||||
def get_media_type_params(media_type):
|
||||
"""
|
||||
Return a dictionary of the parameters on the given media type.
|
||||
"""
|
||||
return _MediaType(media_type).params
|
||||
|
||||
|
||||
def order_by_precedence(media_type_lst):
|
||||
"""
|
||||
Returns a list of lists of media type strings, ordered by precedence.
|
||||
Precedence is determined by how specific a media type is:
|
||||
|
||||
3. 'type/subtype; param=val'
|
||||
2. 'type/subtype'
|
||||
1. 'type/*'
|
||||
0. '*/*'
|
||||
"""
|
||||
ret = [[], [], [], []]
|
||||
for media_type in media_type_lst:
|
||||
precedence = _MediaType(media_type).precedence
|
||||
ret[3 - precedence].append(media_type)
|
||||
return ret
|
||||
|
||||
|
||||
class _MediaType(object):
|
||||
def __init__(self, media_type_str):
|
||||
if media_type_str is None:
|
||||
media_type_str = ''
|
||||
self.orig = media_type_str
|
||||
self.full_type, self.params = parse_header(media_type_str)
|
||||
self.main_type, sep, self.sub_type = self.full_type.partition('/')
|
||||
|
||||
def match(self, other):
|
||||
"""Return true if this MediaType satisfies the given MediaType."""
|
||||
for key in self.params.keys():
|
||||
if key != 'q' and other.params.get(key, None) != self.params.get(key, None):
|
||||
return False
|
||||
|
||||
if self.sub_type != '*' and other.sub_type != '*' and other.sub_type != self.sub_type:
|
||||
return False
|
||||
|
||||
if self.main_type != '*' and other.main_type != '*' and other.main_type != self.main_type:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@property
|
||||
def precedence(self):
|
||||
"""
|
||||
Return a precedence level from 0-3 for the media type given how specific it is.
|
||||
"""
|
||||
if self.main_type == '*':
|
||||
return 0
|
||||
elif self.sub_type == '*':
|
||||
return 1
|
||||
elif not self.params or self.params.keys() == ['q']:
|
||||
return 2
|
||||
return 3
|
||||
|
||||
def __str__(self):
|
||||
return unicode(self).encode('utf-8')
|
||||
|
||||
def __unicode__(self):
|
||||
ret = "%s/%s" % (self.main_type, self.sub_type)
|
||||
for key, val in self.params.items():
|
||||
ret += "; %s=%s" % (key, val)
|
||||
return ret
|
61
thirdpart/djangorestframework/utils/staticviews.py
Normal file
61
thirdpart/djangorestframework/utils/staticviews.py
Normal file
@@ -0,0 +1,61 @@
|
||||
from django.contrib.auth.views import *
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
import base64
|
||||
|
||||
|
||||
# BLERGH
|
||||
# Replicate django.contrib.auth.views.login simply so we don't have get users to update TEMPLATE_CONTEXT_PROCESSORS
|
||||
# to add ADMIN_MEDIA_PREFIX to the RequestContext. I don't like this but really really want users to not have to
|
||||
# be making settings changes in order to accomodate django-rest-framework
|
||||
@csrf_protect
|
||||
@never_cache
|
||||
def api_login(request, template_name='djangorestframework/login.html',
|
||||
redirect_field_name=REDIRECT_FIELD_NAME,
|
||||
authentication_form=AuthenticationForm):
|
||||
"""Displays the login form and handles the login action."""
|
||||
|
||||
redirect_to = request.REQUEST.get(redirect_field_name, '')
|
||||
|
||||
if request.method == "POST":
|
||||
form = authentication_form(data=request.POST)
|
||||
if form.is_valid():
|
||||
# Light security check -- make sure redirect_to isn't garbage.
|
||||
if not redirect_to or ' ' in redirect_to:
|
||||
redirect_to = settings.LOGIN_REDIRECT_URL
|
||||
|
||||
# Heavier security check -- redirects to http://example.com should
|
||||
# not be allowed, but things like /view/?param=http://example.com
|
||||
# should be allowed. This regex checks if there is a '//' *before* a
|
||||
# question mark.
|
||||
elif '//' in redirect_to and re.match(r'[^\?]*//', redirect_to):
|
||||
redirect_to = settings.LOGIN_REDIRECT_URL
|
||||
|
||||
# Okay, security checks complete. Log the user in.
|
||||
auth_login(request, form.get_user())
|
||||
|
||||
if request.session.test_cookie_worked():
|
||||
request.session.delete_test_cookie()
|
||||
|
||||
return HttpResponseRedirect(redirect_to)
|
||||
|
||||
else:
|
||||
form = authentication_form(request)
|
||||
|
||||
request.session.set_test_cookie()
|
||||
|
||||
#current_site = get_current_site(request)
|
||||
|
||||
return render_to_response(template_name, {
|
||||
'form': form,
|
||||
redirect_field_name: redirect_to,
|
||||
#'site': current_site,
|
||||
#'site_name': current_site.name,
|
||||
'ADMIN_MEDIA_PREFIX': settings.ADMIN_MEDIA_PREFIX,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def api_logout(request, next_page=None, template_name='djangorestframework/login.html', redirect_field_name=REDIRECT_FIELD_NAME):
|
||||
return logout(request, next_page, template_name, redirect_field_name)
|
Reference in New Issue
Block a user