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

"""Page CMS functions related to the ``request`` object."""

from django.core.handlers.base import BaseHandler

from django.core.handlers.wsgi import WSGIRequest

from django.http import HttpResponse, HttpResponseRedirect

from django.shortcuts import render_to_response

from django.template import loader, Context, RequestContext

from django.core.urlresolvers import reverse

from pages import settings

 

def get_request_mock():

    """Build a ``request`` mock that can be used for testing."""

    bh = BaseHandler()

    bh.load_middleware()

    request = WSGIRequest({

        'REQUEST_METHOD': 'GET',

        'SERVER_NAME': 'test',

        'SERVER_PORT': '8000',

        'HTTP_HOST': 'testhost',

    })

    # Apply request middleware

    for middleware_method in bh._request_middleware:

        # LocaleMiddleware should never be applied a second time because

        # it would broke the current real request language

        if 'LocaleMiddleware' not in str(middleware_method.im_class):

            response = middleware_method(request)

    return request

 

class AutoRenderHttpError(Exception):

    """Cannot return context dictionary because a view returned an

    ``HttpResponse`` when a (template_name, context) tuple was expected."""

    pass

 

def auto_render(func):

    """

    This view decorator automatically calls the ``render_to_response``

    shortcut. A view that use this decorator should return a tuple of this

    form : (template name, context) instead of a ``HttpRequest`` object.

    """

    def _dec(request, *args, **kwargs):

        template_override = kwargs.pop('template_name', None)

        only_context = kwargs.pop('only_context', False)

        only_response = kwargs.pop('only_response', False)

        if only_context or only_response:

            # return only context dictionary or response

            response = func(request, *args, **kwargs)

            if only_response:

                return response

            if isinstance(response, HttpResponse):

                raise AutoRenderHttpError

            (template_name, context) = response

            return context

        response = func(request, *args, **kwargs)

        if isinstance(response, HttpResponse):

            return response

        (template_name, context) = response

        t = context['template_name'] = template_override or template_name

        return render_to_response(t, context,

                            context_instance=RequestContext(request))

    return _dec

 

def pages_view(view):

    """

    Provide the pages variables to the decorated view.

    """

    def _dec(request, *args, **kwargs):

        path = kwargs.pop('path', None)

        lang = kwargs.pop('lang', None)

        if path or lang:

            from pages.views import details

            response = details(request, path=path, lang=lang,

                only_context=True, delegation=False)

            context = response

            kwargs.update(context)

        return view(request, *args, **kwargs)

    return _dec

 

 

def get_slug_and_relative_path(path, lang=None):

    """Return the page's slug and relative path."""

    root = reverse('pages-root')

    if path.startswith(root):

        path = path[len(root):]

    if len(path) and path[-1] == '/':

        path = path[:-1]

    slug = path.split("/")[-1]

    if settings.PAGE_USE_LANGUAGE_PREFIX:

        lang = path.split("/")[0]

        path = path[(len(lang) + 1):]

    return slug, path, lang

 

def get_template_from_request(request, page=None):

    """

    Gets a valid template from different sources or falls back to the

    default template.

    """

    page_templates = settings.get_page_templates()

    if len(page_templates) == 0:

        return settings.DEFAULT_PAGE_TEMPLATE

    template = request.REQUEST.get('template', None)

    if template is not None and \

            (template in dict(page_templates).keys() or

            template == settings.DEFAULT_PAGE_TEMPLATE):

        return template

    if page is not None:

        return page.get_template()

    return settings.DEFAULT_PAGE_TEMPLATE

 

def get_language_from_request(request):

    """Return the most obvious language according the request."""

    language = request.GET.get('language', None)

    if language:

        return language

 

    if hasattr(request, 'LANGUAGE_CODE'):

        return settings.PAGE_LANGUAGE_MAPPING(str(request.LANGUAGE_CODE))

    else:

        return settings.PAGE_DEFAULT_LANGUAGE