| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
 | """
The :mod:`compatability` module provides support for backwards compatability with older versions of django/python.
"""
# cStringIO only if it's available
try:
    import cStringIO as StringIO
except ImportError:
    import StringIO
# parse_qs 
try:
    # python >= ?
    from urlparse import parse_qs
except ImportError:
    # python <= ?
    from cgi import parse_qs
   
# django.test.client.RequestFactory (Django >= 1.3) 
try:
    from django.test.client import RequestFactory
except ImportError:
    from django.test import Client
    from django.core.handlers.wsgi import WSGIRequest
    
    # From: http://djangosnippets.org/snippets/963/
    # Lovely stuff
    class RequestFactory(Client):
        """
        Class that lets you create mock :obj:`Request` objects for use in testing.
        
        Usage::
        
            rf = RequestFactory()
            get_request = rf.get('/hello/')
            post_request = rf.post('/submit/', {'foo': 'bar'})
        
        This class re-uses the :class:`django.test.client.Client` interface. Of which
        you can find the docs here__.
        
        __ http://www.djangoproject.com/documentation/testing/#the-test-client
        
        Once you have a `request` object you can pass it to any :func:`view` function, 
        just as if that :func:`view` had been hooked up using a URLconf.
        """
        def request(self, **request):
            """
            Similar to parent class, but returns the :obj:`request` object as soon as it
            has created it.
            """
            environ = {
                'HTTP_COOKIE': self.cookies,
                'PATH_INFO': '/',
                'QUERY_STRING': '',
                'REQUEST_METHOD': 'GET',
                'SCRIPT_NAME': '',
                'SERVER_NAME': 'testserver',
                'SERVER_PORT': 80,
                'SERVER_PROTOCOL': 'HTTP/1.1',
            }
            environ.update(self.defaults)
            environ.update(request)
            return WSGIRequest(environ)
# django.views.generic.View (Django >= 1.3)
try:
    from django.views.generic import View
    if not hasattr(View, 'head'):
        # First implementation of Django class-based views did not include head method 
        # in base View class - https://code.djangoproject.com/ticket/15668
        class ViewPlusHead(View):
            def head(self, request, *args, **kwargs):
                return self.get(request, *args, **kwargs)
        View = ViewPlusHead
        
except ImportError:
    from django import http
    from django.utils.functional import update_wrapper
    # from django.utils.log import getLogger
    # from django.utils.decorators import classonlymethod
    
    # logger = getLogger('django.request') - We'll just drop support for logger if running Django <= 1.2
    # Might be nice to fix this up sometime to allow djangorestframework.compat.View to match 1.3's View more closely
    
    class View(object):
        """
        Intentionally simple parent class for all views. Only implements
        dispatch-by-method and simple sanity checking.
        """
    
        http_method_names = ['get', 'post', 'put', 'delete', 'head', 'options', 'trace']
    
        def __init__(self, **kwargs):
            """
            Constructor. Called in the URLconf; can contain helpful extra
            keyword arguments, and other things.
            """
            # Go through keyword arguments, and either save their values to our
            # instance, or raise an error.
            for key, value in kwargs.iteritems():
                setattr(self, key, value)
    
        # @classonlymethod - We'll just us classmethod instead if running Django <= 1.2
        @classmethod
        def as_view(cls, **initkwargs):
            """
            Main entry point for a request-response process.
            """
            # sanitize keyword arguments
            for key in initkwargs:
                if key in cls.http_method_names:
                    raise TypeError(u"You tried to pass in the %s method name as a "
                                    u"keyword argument to %s(). Don't do that."
                                    % (key, cls.__name__))
                if not hasattr(cls, key):
                    raise TypeError(u"%s() received an invalid keyword %r" % (
                        cls.__name__, key))
    
            def view(request, *args, **kwargs):
                self = cls(**initkwargs)
                return self.dispatch(request, *args, **kwargs)
    
            # take name and docstring from class
            update_wrapper(view, cls, updated=())
    
            # and possible attributes set by decorators
            # like csrf_exempt from dispatch
            update_wrapper(view, cls.dispatch, assigned=())
            return view
    
        def dispatch(self, request, *args, **kwargs):
            # Try to dispatch to the right method; if a method doesn't exist,
            # defer to the error handler. Also defer to the error handler if the
            # request method isn't on the approved list.
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            self.request = request
            self.args = args
            self.kwargs = kwargs
            return handler(request, *args, **kwargs)
    
        def http_method_not_allowed(self, request, *args, **kwargs):
            allowed_methods = [m for m in self.http_method_names if hasattr(self, m)]
            #logger.warning('Method Not Allowed (%s): %s' % (request.method, request.path),
            #    extra={
            #        'status_code': 405,
            #        'request': self.request
            #    }
            #)
            return http.HttpResponseNotAllowed(allowed_methods)
        def head(self, request, *args, **kwargs):
            return self.get(request, *args, **kwargs)
try:
    import markdown
    import re
    
    class CustomSetextHeaderProcessor(markdown.blockprocessors.BlockProcessor):
        """
        Override `markdown`'s :class:`SetextHeaderProcessor`, so that ==== headers are <h2> and ---- headers are <h3>.
        
        We use <h1> for the resource name.
        """
    
        # Detect Setext-style header. Must be first 2 lines of block.
        RE = re.compile(r'^.*?\n[=-]{3,}', re.MULTILINE)
    
        def test(self, parent, block):
            return bool(self.RE.match(block))
    
        def run(self, parent, blocks):
            lines = blocks.pop(0).split('\n')
            # Determine level. ``=`` is 1 and ``-`` is 2.
            if lines[1].startswith('='):
                level = 2
            else:
                level = 3
            h = markdown.etree.SubElement(parent, 'h%d' % level)
            h.text = lines[0].strip()
            if len(lines) > 2:
                # Block contains additional lines. Add to  master blocks for later.
                blocks.insert(0, '\n'.join(lines[2:]))
            
    def apply_markdown(text):
        """
        Simple wrapper around :func:`markdown.markdown` to apply our :class:`CustomSetextHeaderProcessor`,
        and also set the base level of '#' style headers to <h2>.
        """
        
        extensions = ['headerid(level=2)']
        safe_mode = False,
        output_format = markdown.DEFAULT_OUTPUT_FORMAT
        md = markdown.Markdown(extensions=markdown.load_extensions(extensions),
                               safe_mode=safe_mode, 
                               output_format=output_format)
        md.parser.blockprocessors['setextheader'] = CustomSetextHeaderProcessor(md.parser)
        return md.convert(text)
except ImportError:
    apply_markdown = None
 |