Completed
Pull Request — master (#2842)
by Edward
05:16
created

search_pack_index()   F

Complexity

Conditions 14

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 14
dl 0
loc 29
rs 2.7581
c 3
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like search_pack_index() 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
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
import itertools
17
18
import requests
19
import six
20
from oslo_config import cfg
21
22
from st2common.persistence.pack import Pack
23
24
__all__ = [
25
    'get_pack_by_ref',
26
    'fetch_pack_index',
27
    'search_pack_index'
28
]
29
30
EXCLUDE_FIELDS = [
31
    "repo_url",
32
    "email"
33
]
34
35
SEARCH_PRIORITY = [
36
    "name",
37
    "keywords"
38
]
39
40
41
def get_pack_by_ref(pack_ref):
42
    """
43
    Retrieve PackDB by the provided reference.
44
    """
45
    pack_db = Pack.get_by_ref(pack_ref)
46
    return pack_db
47
48
49
def fetch_pack_index(index_url=None):
50
    """
51
    Fetch the pack indexes (either from the config or provided as an argument)
52
    and return the object.
53
    """
54
    if not index_url:
55
        index_urls = cfg.CONF.content.index_url
56
    elif isinstance(index_url, str):
57
        index_urls = [index_url]
58
    elif hasattr(index_url, '__iter__'):
59
        index_urls = index_url
60
    else:
61
        raise TypeError('"index_url" should either be a string or an iterable object.')
62
63
    result = {}
64
    for index_url in index_urls:
65
        result.update(requests.get(index_url).json())
66
    return result
67
68
69
def search_pack_index(query=None, pack=None, exclude=None, priority=None):
70
    """
71
    Search the pack index either by pack name or by query.
72
    Returns a pack object if the pack name is specified, otherwise returns
73
    a list of matches for a query.
74
    """
75
    if (not query and not pack) or (query and pack):
76
        raise ValueError("Either a query or a pack name must be specified.")
77
    if not exclude:
78
        exclude = EXCLUDE_FIELDS
79
    if not priority:
80
        priority = SEARCH_PRIORITY
81
82
    index = fetch_pack_index()
83
84
    if pack:
85
        return index.get(pack, None)
86
87
    matches = [[] for _ in xrange(len(priority) + 1)]
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'xrange'
Loading history...
88
    for pack in six.itervalues(index):
89
        for key, value in six.iteritems(pack):
90
            if key not in exclude and query in value:
91
                if key in priority:
92
                    matches[priority.index(key)].append(pack)
93
                else:
94
                    matches[-1].append(pack)
95
                break
96
97
    return list(itertools.chain.from_iterable(matches))
98