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

search_pack_index()   F

Complexity

Conditions 14

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 14
c 2
b 0
f 0
dl 0
loc 30
rs 2.7581

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
from oslo_config import cfg
17
import requests
18
import itertools
19
20
from st2common.persistence.pack import Pack
21
22
__all__ = [
23
    'get_pack_by_ref',
24
    'fetch_pack_index',
25
    'search_pack_index'
26
]
27
28
EXCLUDE_FIELDS = [
29
    "repo_url",
30
    "email"
31
]
32
33
SEARCH_PRIORITY = [
34
    "name",
35
    "keywords"
36
]
37
38
39
def get_pack_by_ref(pack_ref):
40
    """
41
    Retrieve PackDB by the provided reference.
42
    """
43
    pack_db = Pack.get_by_ref(pack_ref)
44
    return pack_db
45
46
47
def fetch_pack_index(index_url=None):
48
    """
49
    Fetch the pack indexes (either from the config or provided as an argument)
50
    and return the object.
51
    """
52
    if not index_url:
53
        index_urls = cfg.CONF.content.index_url
54
    elif isinstance(index_url, str):
55
        index_urls = [index_url]
56
    elif hasattr(index_url, '__iter__'):
57
        index_urls = index_url
58
    else:
59
        raise TypeError('"index_url" should either be a string or an iterable object.')
60
61
    result = {}
62
    for index_url in index_urls:
63
        result.update(requests.get(index_url).json())
64
    return result
65
66
67
def search_pack_index(query=None, pack=None, exclude=None, priority=None):
68
    """
69
    Search the pack index either by pack name or by query.
70
    Returns a pack object if the pack name is specified, otherwise returns
71
    a list of matches for a query.
72
    """
73
    if (not query and not pack) or (query and pack):
74
        raise ValueError("Either a query or a pack name must be specified.")
75
    if not exclude:
76
        exclude = EXCLUDE_FIELDS
77
    if not priority:
78
        priority = SEARCH_PRIORITY
79
80
    index = fetch_pack_index()
81
82
    if pack:
83
        return index.get(pack, None)
84
85
    pack_list = index.values()
86
    matches = [[] for _ in xrange(len(priority)+1)]
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'xrange'
Loading history...
87
    for pack in pack_list:
88
        for key, value in pack.items():
89
            if key not in exclude and query in value:
90
                if key in priority:
91
                    matches[priority.index(key)].append(pack)
92
                else:
93
                    matches[-1].append(pack)
94
                break
95
96
    return list(itertools.chain.from_iterable(matches))
97