Passed
Push — master ( 694e2f...150a8e )
by Dean
09:10 queued 06:18
created

module_start()   B

Complexity

Conditions 6

Size

Total Lines 64

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 37.6815

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 64
ccs 1
cts 24
cp 0.0417
rs 7.69
cc 6
crap 37.6815

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 1
from threading import Thread
2 1
import logging
3 1
import os
4
5 1
from plugin.core.helpers.variable import resolve
6 1
from plugin.core.importer import import_modules
7
8 1
log = logging.getLogger(__name__)
9
10
11 1
MODULES = {}
12
13
14 1
def module(start=False, priority=100, blocking=False):
15 1
    def wrap(kls):
16 1
        module_register(kls, start=start, priority=priority, blocking=blocking)
17 1
        return kls
18
19 1
    return wrap
20
21
22 1
def module_register(kls, **kwargs):
23 1
    start = kwargs.get('start', False)
24
25 1
    if start:
26
        # Validate "start" option
27 1
        f_start = getattr(kls, 'start', None)
28
29 1
        if not f_start or not f_start.im_self:
30
            log.warn('Unable to find bound "start" method for %r', kls)
31
            start = False
32
33
    # Register module
34 1
    MODULES[kls] = {
35
        'start': start,
36
37
        'priority': kwargs.get('priority', 100),
38
        'blocking': kwargs.get('blocking', False)
39
    }
40
41
42 1
def module_start():
43
    # Import modules
44
    plugin_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
45
    log.debug('plugin_dir: %r', plugin_dir)
46
47
    import_modules(os.path.join(plugin_dir, 'api'), exclude=[
48
        '__init__.py',
49
        'core'
50
    ])
51
52
    import_modules(os.path.join(plugin_dir, 'api', 'account'), exclude=[
53
        '__init__.py'
54
    ])
55
56
    import_modules(os.path.join(plugin_dir, 'api', 'session'), exclude=[
57
        '__init__.py'
58
    ])
59
60
    import_modules(os.path.join(plugin_dir, 'managers'), exclude=[
61
        '__init__.py',
62
        'core'
63
    ])
64
65
    import_modules(os.path.join(plugin_dir, 'modules'), exclude=[
66
        '__init__.py',
67
        'backup',
68
        'core'
69
    ])
70
71
    import_modules(os.path.join(plugin_dir, 'scrobbler'), exclude=[
72
        '__init__.py',
73
        'core',
74
        'handlers',
75
        'methods'
76
    ])
77
78
    import_modules(os.path.join(plugin_dir, 'scrobbler', 'handlers'), exclude=[
79
        '__init__.py'
80
    ])
81
82
    # Start modules
83
    modules = sorted(MODULES.items(), key=lambda item: item[1]['priority'])
84
85
    log.debug('Starting %d module(s)...', len(modules))
86
87
    for kls, options in modules:
88
        if not options['start']:
89
            continue
90
91
        log.debug(' -> %s (priority: %d, blocking: %s)', kls.__name__, options['priority'], options['blocking'])
92
93
        f_start = getattr(kls, 'start')
94
95
        try:
96
            # Start module
97
            if options['blocking']:
98
                f_start()
99
            else:
100
                options['thread'] = spawn(f_start, _name=kls.__name__)
101
102
        except Exception, ex:
103
            log.error('Unable to start %r module: %s', kls, ex, exc_info=True)
104
105
    log.debug('Finished starting %d module(s)', len(modules))
106
107
108 1
def spawn(func, *args, **kwargs):
109
    name = kwargs.pop('_name', func.__name__)
110
111
    # Construct thread wrapper to log exceptions
112
    def wrapper(th_name, *args, **kwargs):
113
        try:
114
            func(*args, **kwargs)
115
        except Exception, ex:
116
            log.error('Thread "%s" raised an exception: %s', th_name, ex, exc_info=True)
117
118
    # Spawn thread
119
    try:
120
        thread = Thread(target=wrapper, name=name, args=[name] + (args or []), kwargs=kwargs)
121
        thread.start()
122
    except Exception, ex:
123
        log.warn('Unable to spawn thread: %s', ex, exc_info=True)
124
        return None
125
126
    log.info('Spawned thread with name "%s"', name)
127
    return thread
128
129
130 1
def synchronized(lock):
131
    def outer(func):
132
        def inner(*args, **kwargs):
133
            with resolve(lock, args[0]):
134
                return func(*args, **kwargs)
135
136
        return inner
137
138
    return outer
139