Passed
Push — master ( 354e15...69376c )
by Jordi
04:34
created

SearchableText()   F

Complexity

Conditions 16

Size

Total Lines 53
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 43
dl 0
loc 53
rs 2.4
c 0
b 0
f 0
cc 16
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 build.bika.lims.adapters.identifiers.SearchableText() 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-2019 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
import json
22
from operator import itemgetter
23
24
import plone
25
from archetypes.schemaextender.interfaces import IOrderableSchemaExtender
26
from archetypes.schemaextender.interfaces import ISchemaModifier
27
from bika.lims import bikaMessageFactory as _
28
from bika.lims import safe_unicode
29
from bika.lims.browser import BrowserView
30
from bika.lims.browser.widgets import RecordsWidget
31
from bika.lims.fields import ExtRecordsField
32
from bika.lims.interfaces import IHaveIdentifiers
33
from plone.indexer import indexer
34
from zope.component import adapts
35
from zope.interface import implements
36
37
38
@indexer(IHaveIdentifiers)
39
def IdentifiersIndexer(instance):
40
    """Return a list of unique Identifier strings
41
    This populates the Identifiers Keyword index, but with some
42
    replacements to prevent the word-splitter etc from taking effect.
43
    """
44
    identifiers = instance.Schema()['Identifiers'].get(instance)
45
    return [safe_unicode(i['Identifier']) for i in identifiers]
46
47
48
Identifiers = ExtRecordsField(
49
    'Identifiers',
50
    required=False,
51
    type='identifiers',
52
    searchable=True,
53
    subfields=('IdentifierType', 'Identifier', 'Description'),
54
    required_subfields=('IdentifierType', 'Identifier'),
55
    subfield_labels={'IdentifierType': _('Identifier Type'),
56
                     'Identifier': _('Identifier'),
57
                     'Description': _('Description')},
58
    subfield_validators={'IdentifierType': 'identifiervalidator',
59
                         'Identifier': 'identifiervalidator'},
60
    subfield_sizes={'IdentifierType': 10,
61
                    'Identifier': 15,
62
                    'Description': 32},
63
    widget=RecordsWidget(
64
        label=_('Identifiers for this object'),
65
        description=_(
66
            "Select identifiers by which this object can be referenced."),
67
        visible={'view': 'visible',
68
                 'edit': 'visible'},
69
        combogrid_options={
70
            'IdentifierType': {
71
                'colModel': [
72
                    {'columnName': 'identifiertype_uid', 'hidden': True},
73
                    {'columnName': 'IdentifierType', 'width': '30',
74
                     'label': _('Identifier Type')},
75
                    {'columnName': 'Description', 'width': '70',
76
                     'label': _('Description')}
77
                ],
78
                'url': 'getidentifiertypes',
79
                'showOn': True,
80
                'width': '500px',
81
            }
82
        }
83
    )
84
)
85
86
87
class IHaveIdentifiersSchemaExtender(object):
88
    adapts(IHaveIdentifiers)
89
    implements(IOrderableSchemaExtender)
90
91
    fields = [
92
        Identifiers,
93
    ]
94
95
    def __init__(self, context):
96
        self.context = context
97
98
    def getOrder(self, schematas):
99
        """Return modified order of field schemats.
100
        """
101
        schemata = self.context.schema['description'].schemata
102
        fields = schematas[schemata]
103
        fields.insert(fields.index('description') + 1,
104
                      'Identifiers')
105
        return schematas
106
107
    def getFields(self):
108
        return self.fields
109
110
111
class IHaveIdentifiersSchemaModifier(object):
112
    adapts(IHaveIdentifiers)
113
    implements(ISchemaModifier)
114
115
    def __init__(self, context):
116
        self.context = context
117
118
    def fiddle(self, schema):
119
        schemata = schema['description'].schemata
120
        schema['Identifiers'].schemata = schemata
121
        schema.moveField('Identifiers', after='description')
122
        return schema
123
124
125
class ajaxGetIdentifierTypes(BrowserView):
126
    """ Identifier types vocabulary source for jquery combo dropdown box
127
    """
128
129
    def __call__(self):
130
        plone.protect.CheckAuthenticator(self.request)
131
        searchTerm = 'searchTerm' in self.request and self.request[
132
            'searchTerm'].lower() or ''
133
        page = self.request['page']
134
        nr_rows = self.request['rows']
135
        sord = self.request['sord']
136
        sidx = self.request['sidx']
137
        rows = []
138
139
        # lookup objects from ZODB
140
        brains = self.bika_setup_catalog(portal_type='IdentifierType',
141
                                         is_active=True)
142
        if brains and searchTerm:
143
            brains = [p for p in brains if p.Title.lower(
144
            ).find(searchTerm) > -1]
145
146
        for p in brains:
147
            rows.append({'IdentifierType': p.Title,
148
                         'Description': p.Description})
149
150
        rows = sorted(rows, cmp=lambda x, y: cmp(x.lower(
151
        ), y.lower()), key=itemgetter(sidx and sidx or 'IdentifierType'))
152
        if sord == 'desc':
153
            rows.reverse()
154
        pages = len(rows) / int(nr_rows)
155
        pages += divmod(len(rows), int(nr_rows))[1] and 1 or 0
156
        ret = {'page': page,
157
               'total': pages,
158
               'records': len(rows),
159
               'rows': rows[(int(page) - 1) * int(nr_rows): int(page) * int(
160
                   nr_rows)]}
161
        return json.dumps(ret)
162