Completed
Push — dev-0.5.2 ( 16c7f4...cb9d21 )
by Felipe A.
02:58
created

WathdogEventAdapter.__init__()   A

Complexity

Conditions 1

Size

Total Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
c 1
b 0
f 1
dl 0
loc 2
rs 10
1
2
import threading
3
import collections
4
import warnings
5
import os.path
6
7
import watchdog.observers
8
import watchdog.events
9
10
11
class Event(list):
12
    '''
13
    Event subscription list.
14
15
    A list of callable objects. Calling an instance of this will cause a
16
    call to each item in the list in ascending order by index.
17
18
    Usage:
19
    >>> def f(x):
20
    ...     print 'f(%s)' % x
21
    >>> def g(x):
22
    ...     print 'g(%s)' % x
23
    >>> e = Event()
24
    >>> e()
25
    >>> e.append(f)
26
    >>> e(123)
27
    f(123)
28
    >>> e.remove(f)
29
    >>> e()
30
    >>> e += (f, g)
31
    >>> e(10)
32
    f(10)
33
    g(10)
34
    >>> del e[0]
35
    >>> e(2)
36
    g(2)
37
    '''
38
39
    lock_class = threading.Lock
40
    queue_class = collections.deque
41
42
    def __init__(self, iterable=()):
43
        self._lock = self.lock_class()
44
        self._queue = self.queue_class()
45
        super(Event, self).__init__(iterable)
46
47
    def __call__(self, *args, **kwargs):
48
        self._queue.append((args, kwargs))
49
        while self._queue:
50
            if self._lock.acquire(blocking=False):
51
                try:
52
                    args, kwargs = self._queue.popleft()
53
                    for f in self:
54
                        f(*args, **kwargs)
55
                finally:
56
                    self._lock.release()
57
            else:
58
                break
59
60
    def __repr__(self):
61
        return "Event(%s)" % list.__repr__(self)
62
63
64
class EventManager(collections.defaultdict):
65
    '''
66
    Attribute-dict creating :class:`Event` objects on demand.
67
68
    Usage:
69
    >>> def f(x):
70
    ...     print 'f(%s)' % x
71
    >>> def g(x):
72
    ...     print 'g(%s)' % x
73
    >>> m = EventManager()
74
    >>> 'e' in m
75
    False
76
    >>> m.e.append(f)
77
    >>> 'e' in m
78
    True
79
    >>> m.e(123)
80
    f(123)
81
    >>> m.e.remove(f)
82
    >>> m.e()
83
    >>> m.e += (f, g)
84
    >>> m.e(10)
85
    f(10)
86
    g(10)
87
    >>> del m.e[0]
88
    >>> m.e(2)
89
    g(2)
90
    '''
91
    def __init__(self):
92
        super(EventManager, self).__init__(Event)
93
94
    def __getattr__(self, name):
95
        return self[name]
96
97
98
class WathdogEventAdapter(object):
99
    observer_class = watchdog.observers.Observer
100
    event_class = collections.namedtuple(
101
        'FSEvent', ('type', 'path', 'source', 'is_directory')
102
        )
103
    event_map = {
104
        watchdog.events.EVENT_TYPE_MOVED: 'fs_move',
105
        watchdog.events.EVENT_TYPE_DELETED: 'fs_create',
106
        watchdog.events.EVENT_TYPE_CREATED: 'fs_modify',
107
        watchdog.events.EVENT_TYPE_MODIFIED: 'fs_remove'
108
        }
109
    _observer = None
110
111
    def __init__(self, manager):
112
        self.manager = manager
113
114
    def dispatch(self, wevent):
115
        event = self.event_class(
116
            self.event_map[wevent.event_type],
117
            wevent.dest_path if type == 'fs_move' else wevent.src_path,
118
            wevent.src_path,
119
            wevent.is_directory
120
            )
121
        event_type_specific = '%s_%s' % (
122
            event.type,
123
            'file' if event.is_directory else 'directory'
124
            )
125
        self.manager['fs_any'](event)
126
        self.manager[event.type](event)
127
        self.manager[event_type_specific](event)
128
129
    def watch(self, path):
130
        if not os.path.isdir(path):
131
            warnings.warn(
132
                'Path %r is not observable.',
133
                category=RuntimeWarning,
134
                stacklevel=2
135
                )
136
            return
137
        observer = self._observer or self.observer_class()
138
        observer.schedule(self, path, recursive=True)
139
        if not self._observer:
140
            observer.start()
141
            self._observer = observer
142
143
    def clear(self):
144
        observer = self._observer
145
        if observer:
146
            observer.unschedule_all()
147
            observer.stop()
148
            observer.join()
149
        self._observer = None
150