Passed
Push — master ( a941d3...c56b62 )
by Alexander
02:42
created

tcms.core.views   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 10
eloc 75
dl 0
loc 133
rs 10
c 0
b 0
f 0

2 Functions

Rating   Name   Duplication   Size   Complexity  
A navigation() 0 5 1
A server_error() 0 8 1

3 Methods

Rating   Name   Duplication   Size   Complexity  
B TranslationMode.get_browser_language() 0 35 6
A TranslationMode.get() 0 21 1
A DashboardView.get_context_data() 0 26 1
1
# -*- coding: utf-8 -*-
2
from django import http
3
from django.views import i18n
4
from django.conf import settings
5
from django.template import loader
6
from django.shortcuts import render
7
from django.db.models import Count, Q
8
from django.utils import translation
9
from django.utils.translation import trans_real
10
from django.utils.decorators import method_decorator
11
from django.views.generic.base import View
12
from django.views.generic.base import TemplateView
13
from django.contrib.auth.decorators import login_required
14
from django.views.decorators.csrf import requires_csrf_token
15
16
from tcms.testplans.models import TestPlan
17
from tcms.testruns.models import TestRun
18
19
20
@method_decorator(login_required, name='dispatch')
21
class DashboardView(TemplateView):  # pylint: disable=missing-permission-required
22
23
    template_name = 'dashboard.html'
24
25
    def get_context_data(self, **kwargs):
26
        """List all recent TestPlans and TestRuns"""
27
        test_plans = TestPlan.objects.filter(
28
            author=self.request.user
29
        ).order_by(
30
            '-plan_id'
31
        ).select_related(
32
            'product', 'type'
33
        ).annotate(
34
            num_runs=Count('run', distinct=True)
35
        )
36
        test_plans_disable_count = test_plans.filter(is_active=False).count()
37
38
        test_runs = TestRun.objects.filter(
39
            Q(manager=self.request.user) |
40
            Q(default_tester=self.request.user) |
41
            Q(case_run__assignee=self.request.user),
42
            stop_date__isnull=True,
43
        ).order_by('-run_id').distinct()
44
45
        return {
46
            'test_plans_count': test_plans.count(),
47
            'test_plans_disable_count': test_plans_disable_count,
48
            'last_15_test_plans': test_plans.filter(is_active=True)[:15],
49
            'last_15_test_runs': test_runs[:15],
50
            'test_runs_count': test_runs.count(),
51
        }
52
53
54
def navigation(request):  # pylint: disable=missing-permission-required
55
    """
56
    iframe navigation workaround until we migrate everything to patternfly
57
    """
58
    return render(request, 'navigation.html')
59
60
61
@requires_csrf_token
62
def server_error(request):  # pylint: disable=missing-permission-required
63
    """
64
        Render the error page with request object which supports
65
        static URLs so we can load a nice picture.
66
    """
67
    template = loader.get_template('500.html')
68
    return http.HttpResponseServerError(template.render({}, request))
69
70
71
class TranslationMode(View):  # pylint: disable=missing-permission-required
72
    """
73
        Turns on and off translation mode by switching language to
74
        Esperanto!
75
    """
76
    @staticmethod
77
    def get_browser_language(request):
78
        """
79
            Returns *ONLY* the language that is sent by the browser via the
80
            Accept-Language headers. Defaults to ``settings.LANGUAGE_CODE`` if
81
            that doesn't work!
82
83
            This is the language we switch back to when translation mode is turned off.
84
85
            Copied from the bottom half of
86
            ``django.utils.translation.trans_real.get_language_from_request()``
87
88
            .. note::
89
90
                Using ``get_language_from_request()`` doesn't work for us because
91
                it first inspects session and cookies and we've already set Esperanto
92
                in both the session and the cookie!
93
        """
94
        accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
95
        for accept_lang, _unused in trans_real.parse_accept_lang_header(accept):
96
            if accept_lang == '*':
97
                break
98
99
            if not trans_real.language_code_re.search(accept_lang):
100
                continue
101
102
            try:
103
                return translation.get_supported_language_variant(accept_lang)
104
            except LookupError:
105
                continue
106
107
        try:
108
            return translation.get_supported_language_variant(settings.LANGUAGE_CODE)
109
        except LookupError:
110
            return settings.LANGUAGE_CODE
111
112
    def get(self, request):
113
        """
114
            In the HTML template we'd like to work with simple links
115
            however the view which actually switches the language needs
116
            to be called via POST so we simulate that here!
117
118
            If the URL doesn't explicitly specify language then we turn-off
119
            translation mode by switching back to browser preferred language.
120
        """
121
        browser_lang = self.get_browser_language(request)
122
        post_body = "%s=%s" % (i18n.LANGUAGE_QUERY_PARAMETER,
123
                               request.GET.get(i18n.LANGUAGE_QUERY_PARAMETER, browser_lang))
124
        request.META['REQUEST_METHOD'] = 'POST'
125
        request.META['CONTENT_LENGTH'] = len(post_body)
126
        request.META['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
127
128
        post_request = request.__class__(request.META)
129
        # pylint: disable=protected-access
130
        post_request._post = http.QueryDict(post_body, encoding=post_request._encoding)
131
132
        return i18n.set_language(post_request)
133