Passed
Push — 2.x ( 7870b7...db7972 )
by Ramon
09:50
created

FrontPageView.__call__()   F

Complexity

Conditions 14

Size

Total Lines 66
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 45
dl 0
loc 66
rs 3.6
c 0
b 0
f 0
cc 14
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like senaite.core.browser.frontpage.frontpage.FrontPageView.__call__() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of SENAITE.CORE.
4
#
5
# SENAITE.CORE is free software: you can redistribute it and/or modify it under
6
# the terms of the GNU General Public License as published by the Free Software
7
# Foundation, version 2.
8
#
9
# This program is distributed in the hope that it will be useful, but WITHOUT
10
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12
# details.
13
#
14
# You should have received a copy of the GNU General Public License along with
15
# this program; if not, write to the Free Software Foundation, Inc., 51
16
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
#
18
# Copyright 2018-2023 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
from bika.lims import api
22
from bika.lims.browser import BrowserView
23
from bika.lims.interfaces import IFrontPageAdapter
24
from plone import api as ploneapi
25
from plone.protect.utils import addTokenToUrl
26
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
27
from senaite.core.config.registry import CLIENT_LANDING_PAGE
28
from senaite.core.registry import get_registry_record
29
from zope.component import getAdapters
30
31
32
class FrontPageView(BrowserView):
33
    """SENAITE default Front Page
34
    """
35
    template = ViewPageTemplateFile("templates/frontpage.pt")
36
37
    def __call__(self):
38
        self.icon = "{}/{}".format(
39
            self.portal_url, "/++resource++bika.lims.images/chevron_big.png")
40
        setup = api.get_setup()
41
        login_url = "{}/{}".format(self.portal_url, "login")
42
        landingpage = setup.getLandingPage()
43
44
        # Anonymous Users get either redirected to the std. bika-frontpage or
45
        # to the custom landing page, which is set in setup. If no landing
46
        # page setup, then redirect to login page.
47
        if self.is_anonymous_user():
48
            # Redirect to the selected Landing Page
49
            if landingpage:
50
                return self.request.response.redirect(
51
                    landingpage.absolute_url())
52
            # Redirect to login page
53
            return self.request.response.redirect(login_url)
54
55
        # Authenticated Users get either the Dashboard, the std. login page
56
        # or the custom landing page. Furthermore, they can switch between the
57
        # Dashboard and the landing page.
58
        # Add-ons can have an adapter for front-page-url as well.
59
        for name, adapter in getAdapters((self.context,), IFrontPageAdapter):
60
            redirect_to = adapter.get_front_page_url()
61
            if redirect_to:
62
                return self.request.response.redirect(
63
                    self.portal_url + redirect_to)
64
65
        # First precedence: Request parameter `redirect_to`
66
        redirect_to = self.request.form.get("redirect_to", None)
67
        if redirect_to == "dashboard":
68
            return self.request.response.redirect(
69
                self.portal_url + "/senaite-dashboard")
70
        if redirect_to == "frontpage":
71
            if landingpage:
72
                return self.request.response.redirect(
73
                    landingpage.absolute_url())
74
            return self.template()
75
76
        # Second precedence: Dashboard enabled
77
        if self.is_dashboard_enabled():
78
            roles = self.get_user_roles()
79
            allowed = ["Manager", "LabManager", "LabClerk"]
80
            if set(roles).intersection(allowed):
81
                url = addTokenToUrl("{}/{}".format(
82
                    self.portal_url, "senaite-dashboard"))
83
                return self.request.response.redirect(url)
84
            if "Sampler" in roles or "SampleCoordinator" in roles:
85
                url = addTokenToUrl("{}/{}".format(
86
                    self.portal_url,
87
                    "samples?samples_review_state=to_be_sampled"))
88
                return self.request.response.redirect(url)
89
90
        # Third precedence: Custom Landing Page
91
        if landingpage:
92
            return self.request.response.redirect(landingpage.absolute_url())
93
94
        # Fourth precedence: Default landing page in client view
95
        client = api.get_current_client()
96
        if client:
97
            view = get_registry_record(CLIENT_LANDING_PAGE)
98
            url = "{}/{}".format(api.get_url(client), view)
99
            return self.request.response.redirect(url)
100
101
        # Last precedence: Front Page
102
        return self.template()
103
104
    def is_dashboard_enabled(self):
105
        """Checks if the dashboard is enabled
106
        """
107
        setup = api.get_setup()
108
        return setup.getDashboardByDefault()
109
110
    def is_anonymous_user(self):
111
        """Checks if the current user is anonymous
112
        """
113
        return ploneapi.user.is_anonymous()
114
115
    def get_user_roles(self):
116
        """Returns a list of roles for the current user
117
        """
118
        if self.is_anonymous_user():
119
            return []
120
        current_user = ploneapi.user.get_current()
121
        return ploneapi.user.get_roles(user=current_user)
122