Passed
Push — 2.x ( a93928...ced756 )
by Jordi
08:02 queued 01:02
created

get_sticker_templates()   B

Complexity

Conditions 7

Size

Total Lines 71
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 71
rs 7.76
c 0
b 0
f 0
cc 7
nop 1

How to fix   Long Method   

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:

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-2025 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
import glob
22
import os
23
24
from pkg_resources import resource_filename
25
from plone.resource.utils import iterDirectoriesOfType
26
from senaite.core.schema.vocabulary import to_simple_vocabulary
27
from zope.interface import implementer
28
from zope.schema.interfaces import IVocabularyFactory
29
30
31
@implementer(IVocabularyFactory)
32
class StickerTemplatesVocabulary(object):
33
    """Provides all available stickers
34
    """
35
36
    def __call__(self, context, filter_by_type=False):
37
        templates = get_sticker_templates(filter_by_type=filter_by_type)
38
        return to_simple_vocabulary([(t["id"], t["title"]) for t in templates])
39
40
41
StickerTemplatesVocabularyFactory = StickerTemplatesVocabulary()
42
43
44
def get_sticker_templates(filter_by_type=None):
45
    """Returns a list of sticker records
46
47
    Each sticker record is a dictionary of the following structure:
48
49
        {
50
            "id": <template_id>,
51
            "title": <template_title>,
52
        }
53
54
    If the template lives outside the senaite.core add-on, both the
55
    template_id and template_title include a prefix that matches with
56
    the add-on identifier.
57
58
    The template_title is the same name as the id, but with whitespaces and
59
    without extension.
60
61
    As an example, for a template from the my.product add-on located in
62
    templates/stickers, and with a filename "EAN128_default_small.pt",
63
    the dictionary will look like:
64
65
        {
66
            "id": "my.product:EAN128_default_small.pt",
67
            "title": "my.product: EAN128 default small",
68
        }
69
70
    If filter by type is given in the request, only the templates under the
71
    path with the type name will be fetched.
72
73
    Example: If filter_by_type=='worksheet', only *.pt files under a folder
74
    with this name will be displayed.
75
76
    :param filter_by_type: sticker type, e.g. "batch" or "worksheet"
77
    :returns: list of sticker records
78
    """
79
    resdirname = "stickers"
80
    if filter_by_type:
81
        fs_path = os.path.join(
82
            "browser", "stickers", "templates", resdirname, filter_by_type)
83
    else:
84
        fs_path = os.path.join("browser", "stickers", "templates", resdirname)
85
86
    templates_dir = resource_filename("senaite.core", fs_path)
87
    templates_subdir = os.path.join(templates_dir, "*.pt")
88
    templates = [os.path.split(x)[-1] for x in glob.glob(templates_subdir)]
89
90
    # Retrieve the templates from other add-ons
91
    for templates_resource in iterDirectoriesOfType(resdirname):
92
        prefix = templates_resource.__name__
93
        if prefix == "senaite.core":
94
            continue
95
        directory = templates_resource.directory
96
        # Only use the directory asked in "filter_by_type"
97
        if filter_by_type:
98
            directory = directory + "/" + filter_by_type
99
        if os.path.isdir(directory):
100
            dirlist = os.listdir(directory)
101
            exts = ["{0}:{1}".format(prefix, tpl) for tpl in dirlist if
102
                    tpl.endswith(".pt")]
103
            templates.extend(exts)
104
105
    out = []
106
    templates.sort()
107
    for template in templates:
108
        title = template[:-3]
109
        title = title.replace("_", " ")
110
        title = title.replace(":", ": ")
111
        out.append({"id": template,
112
                    "title": title})
113
114
    return out
115