Statistics
| Branch: | Tag: | Revision:

root / snf-common / synnefo / util / entry_points.py @ f8af937f

History | View | Annotate | Download (5 kB)

1
# Copyright 2011 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
import sys
35
import pkg_resources
36
import types
37
import os
38

    
39
from collections import defaultdict
40

    
41
# List of python distribution names which entry points will get excluded
42
# from snf-common settings extension mechanism
43
EXCLUDED_PACKAGES = os.environ.get('SYNNEFO_EXCLUDE_PACKAGES', '').split(":")
44

    
45

    
46
def get_entry_points(ns, name):
47
    for entry_point in pkg_resources.iter_entry_points(group=ns):
48
        if entry_point.name == name and \
49
                not entry_point.dist.project_name in EXCLUDED_PACKAGES:
50
            yield entry_point
51

    
52

    
53
def extend_module(module_name, attrs):
54
    module = sys.modules[module_name]
55
    for k, v in attrs.iteritems():
56
        setattr(module, k, v)
57

    
58

    
59
def entry_point_to_object(ep):
60
    object_or_func = ep.load()
61

    
62
    # user defined entry point is a function
63
    # get the return value
64
    obj = object_or_func
65
    if hasattr(object_or_func, '__call__'):
66
        obj = object_or_func()
67

    
68
    if isinstance(obj, types.ModuleType):
69
        dct = {}
70
        for k in dir(obj):
71
            if k.startswith("__"):
72
                continue
73
            dct[k] = getattr(obj, k)
74

    
75
        obj = dct
76

    
77
    return obj
78

    
79

    
80
def extend_module_from_entry_point(module_name, ns):
81
    """
82
    Extend a settings module from entry_point hooks
83
    """
84
    for e in get_entry_points(ns, 'default_settings'):
85
        extend_module(module_name, entry_point_to_object(e))
86

    
87

    
88
def extend_dict_from_entry_point(settings_object, ns, entry_point_name):
89
    for e in get_entry_points(ns, entry_point_name):
90
        settings_object.update(entry_point_to_object(e))
91

    
92
    return settings_object
93

    
94

    
95
def extend_list_from_entry_point(settings_object, ns, entry_point_name,
96
                                 unique=True):
97
    settings_object = list(settings_object)
98
    for e in get_entry_points(ns, entry_point_name):
99
        obj = entry_point_to_object(e)
100
        for row in obj:
101
            # skip duplicate entries
102
            if row in settings_object:
103
                continue
104

    
105
            if type(row) == dict and (row.get('before', False) or
106
                                      row.get('after', False)):
107

    
108
                insert_at = len(settings_object)
109
                if row.get('before', False):
110
                    try:
111
                        position = settings_object.index(row.get('before'))
112
                        insert_at = position - 1
113
                    except ValueError:
114
                        pass
115
                else:
116
                    try:
117
                        position = settings_object.index(row.get('after'))
118
                        insert_at = position + 1
119
                    except ValueError:
120
                        pass
121

    
122
                if insert_at < 0:
123
                    insert_at = 0
124

    
125
                inserts = row.get('insert', [])
126
                if not type(inserts) == list:
127
                    inserts = [inserts]
128

    
129
                for entry in inserts:
130
                    if not entry in settings_object:
131
                        settings_object.insert(insert_at, entry)
132
                        insert_at = insert_at + 1
133
            else:
134
                settings_object.append(row)
135

    
136
    return settings_object
137

    
138

    
139
def collect_defaults(ns):
140
    settings = defaultdict(lambda: [])
141
    for e in get_entry_points('synnefo', 'default_settings'):
142
        attrs = dir(e.load())
143
        settings[e.dist.key] = settings[e.dist.key] + attrs
144

    
145
    return settings
146

    
147

    
148
def extend_settings(mname, ns):
149
    extend_module_from_entry_point(mname, ns)
150

    
151

    
152
def extend_urls(patterns, ns):
153
    for e in get_entry_points(ns, 'urls'):
154
        patterns += e.load()
155

    
156
    return patterns