~hdlorean-watcher/hdlorean/watcher

« back to all changes in this revision

Viewing changes to src/hdloreand/watcher/PyinotifyHandler.py

  • Committer: Winterfuse
  • Date: 2008-04-26 18:37:39 UTC
  • mfrom: (86.4.65 testing)
  • Revision ID: adrianbn@gmail.com-20080426183739-4da142meii94zrzb
Baseline

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
#
7
7
#HDLorean is free software: you can redistribute it and/or modify
8
8
#it under the terms of the GNU General Public License as published by
9
 
#the Free Software Foundation, either version 3 of the License, or
10
 
#(at your option) any later version.
 
9
#the Free Software Foundation, either version 2 of the License.
11
10
 
12
11
#HDLorean is distributed in the hope that it will be useful,
13
12
#but WITHOUT ANY WARRANTY; without even the implied warranty of
26
25
import os
27
26
import GlobalExceptions
28
27
from hdlogger import HDLogger
 
28
import thread
29
29
 
30
30
## @brief a handler for inotiy events
31
31
#
63
63
        __log = None
64
64
        ## contains the number of watches
65
65
        __nWatches = 0
 
66
        ##indicates the status of the notifier
 
67
        __isStarted = False
66
68
 
67
69
 
68
70
        ## @brief takes a list of paths and adds each one to watched.
71
73
        # The handler is initialized with those sets
72
74
        # a notifier is created with the watched set and the handler
73
75
        # @see Watcher
 
76
        # @param start if start is true, the notification of events is going to start just after create the
 
77
        # instance if pyinotifyhandler
74
78
        # @author: Jorge
75
 
        def __init__(self,handler,watched,blacklist,whitelist,reBlacklist,parentsList):
 
79
        def __init__(self,handler,watched,blacklist,whitelist,reBlacklist,parentsList,start):
76
80
                self.__logger = HDLogger.HDLogger()
77
81
                self.__log = self.__logger.setupHDLogger('hdlorean.Watcher.PyinotifyHandler')
78
82
                try:
85
89
                self.__reBlacklist = reBlacklist
86
90
                self.__parentlist = parentsList
87
91
                self.__watchedlist = watched
88
 
                # expanded files
89
 
                for item in watched:
90
 
                        try:
91
 
                                self.addToWatched(item)
92
 
                        except GlobalExceptions.InvalidPath:
93
 
                                self.__log.error('Invalid path ' + item)
94
 
                #parents
95
 
                for item in parentsList:
96
 
                        try:
97
 
                                self.addParentToWatched(item)
98
 
                        except GlobalExceptions.InvalidPath:
99
 
                                self.__log.error('Invalid path ' + item)
100
 
                for item in blacklist:
101
 
                        self.removeFromWatched(item)
102
 
                for item in reBlacklist:
103
 
                        self.removeFromWatched(item)
104
92
                self.__handler = handler
105
 
                self.__notifier = ThreadedNotifier(self.__watched,self.__handler)
106
 
 
 
93
                if start:
 
94
                        # expanded files
 
95
                        for item in watched:
 
96
                                try:
 
97
                                        self.addToWatched(item)
 
98
                                except GlobalExceptions.InvalidPath:
 
99
                                        self.__log.error('Invalid path ' + item)
 
100
                        #parents
 
101
                        for item in parentsList:
 
102
                                try:
 
103
                                        self.addParentToWatched(item)
 
104
                                except GlobalExceptions.InvalidPath:
 
105
                                        self.__log.error('Invalid path ' + item)
 
106
                        for item in blacklist:
 
107
                                self.removeFromWatched(item)
 
108
                        for item in reBlacklist:
 
109
                                self.removeFromWatched(item)
 
110
                        self.__notifier = ThreadedNotifier(self.__watched,self.__handler)
107
111
        #deprecated
108
112
        ## @brief Callback method to be notified by Watcher of the changes made in the lists
109
113
        #
116
120
                for add in added:
117
121
                        try:
118
122
                                self.addToWatched(add)
119
 
                                print 'added '+ add
 
123
                                #print 'added '+ add
120
124
                        except GlobalExceptions.InvalidPath:
121
125
                                self.__log.error('Invald path' + add)
122
126
                for rm in removed:
123
127
                        self.removeFromWatched(rm)
124
 
                        print 'removed ' + rm
 
128
                        #print 'removed ' + rm
125
129
                for add in parentAdded:
126
130
                        self.addParentToWatched(add)
127
 
                        print 'added p '+ add
 
131
                        #print 'added p '+ add
128
132
                for rm in parentRemoved:
129
133
                        #remove from watched can be used to remove parents
130
134
                        self.removeFromWatched(rm)
131
 
                        print 'removed p'+ rm
 
135
                        #print 'removed p'+ rm
 
136
                        
 
137
                        
 
138
        def addToWatched(self,path):
 
139
                thread.start_new_thread(self.__threadedAddToWatched,(path,))
 
140
 
132
141
 
133
142
        ## @brief adds a single path to __watched.
134
143
        #
136
145
        # then adds path to watched resources with the appropriate flags
137
146
        # @param path type=string  add the file or directoriy path to watched
138
147
        # @author Jorge
139
 
        def addToWatched(self,path):
 
148
        def __threadedAddToWatched(self,path):
140
149
        # first of all we must know if the path exist, then if it's file or dir
141
150
        # TODO: it seems that WatchManager.add checks if the path is valid...check it
142
151
                if os.path.exists(path):
148
157
                                        EventsCodes.IN_MOVED_FROM
149
158
                                _dic = self.__watched.add_watch(path, mask, None, True, True)
150
159
                                self.__updateDictionaries(_dic,True)
151
 
                                self.__log.debug('dictionary paths '+repr(self.__pathDic))
152
 
                                self.__log.debug('dictionary wd '+repr(self.__wdDic))
 
160
                                #self.__log.debug('dictionary paths '+repr(self.__pathDic))
 
161
                                #self.__log.debug('dictionary wd '+repr(self.__wdDic))
153
162
                                self.__nWatches = len(self.__pathDic)
154
163
                                self.__log.debug('Addition. Number of watches = '+ repr(self.__nWatches))
155
164
                                if(self.__nWatches >= 0.8 * inotify.max_user_watches.value):
163
172
                                #TODO: refactor this if-else
164
173
                                        pass
165
174
                else:
 
175
                        print 'joder, ha cascado path =' + path
166
176
                        raise GlobalExceptions.InvalidPath
167
177
                
168
178
 
205
215
        def startNotifier(self):
206
216
                if not(self.__notifier.isAlive()):
207
217
                        self.__notifier.start()
 
218
                        self.__isStarted = True
208
219
                else:
209
220
                        raise GlobalExceptions.NotifierRunning
210
221
        
214
225
        def stopNotifier(self):
215
226
                if self.__notifier.isAlive():
216
227
                        self.__notifier.stop()
 
228
                        self.__isStarted = False
217
229
                else:
218
230
                        raise GlobalExceptions.NotifierStopped
219
 
                        
 
231
                
220
232
                        
221
233
        def removeFromWatched(self,path):
 
234
                thread.start_new_thread(self.__threadedRemoveFromWatched,(path,))
 
235
                
 
236
                                        
 
237
        def __threadedRemoveFromWatched(self,path):
222
238
        #pyinotify don't return a dictionary of wd and paths, instead of this we obtain
223
239
        #a dictionary of wd and boolean
224
240
                if path != '':
244
260
                                        except KeyError:
245
261
                                                #borramos la entrada que da error en _wdDic
246
262
                                                deleteMe.append(key)
 
263
                                else:
 
264
                                        deleteMe.append(key)
247
265
                        #here we proceed with the deletion of the pairs that we don't have on __wdDic nor __pathDic
248
266
                        for rm in deleteMe:
249
 
                                del _dic[key]
 
267
                                del _dic[rm]
250
268
                        self.__updateDictionaries(_dic,False)
251
269
                        self.__nWatches = len(self.__pathDic)
252
270
                        self.__log.debug('Remove. Number of watches =' + repr(self.__nWatches))
299
317
        def __updateDictionaries(self,dictionary,add):
300
318
                if add:
301
319
                        self.__pathDic.update(dictionary)
302
 
                        print 'dictionary ----------> '+repr(dictionary)
303
 
                        print 'new------------------> '+repr(self.__pathDic)
 
320
                        #print 'dictionary ----------> '+repr(dictionary)
 
321
                        #print 'new------------------> '+repr(self.__pathDic)
304
322
                        #the next is more simple than it appears
305
323
                        # the wdDic keys are the values of dictionary
306
324
                        for key in dictionary:
323
341
                        self.addToWatched(path)
324
342
                for path in self.__parentlist:
325
343
                        self.addToWatched(path)
 
344
                if not self.__isStarted:
 
345
                        for item in self.__blacklist:
 
346
                                self.removeFromWatched(item)
 
347
                        for item in self.__reBlacklist:
 
348
                                self.removeFromWatched(item)
 
349
                        self.__notifier = ThreadedNotifier(self.__watched,self.__handler)                       
 
350
                        self.startNotifier()
 
351
                        self.__log.info('Started')
 
352
                                        
326
353
                        
327
354
        def update(self,mask):
328
355
                if mask == False:
334
361
                for item in self.__watchedlist: 
335
362
                        wd = self.__pathDic[item]
336
363
                        self.__watched.update_watch(wd, mask,None, True)
 
364
                        
337
365
##
338
366
##              FOR DEBUGING PROPOSAL
339
367
##REMEMBER: This CODE has been moved into Watcher