76 |
76 |
"""
|
77 |
77 |
|
78 |
78 |
|
79 |
|
class SingleFileEventHandler(pyinotify.ProcessEvent):
|
80 |
|
"""Handle modify events for a single file.
|
|
79 |
class FileEventHandlerBase(pyinotify.ProcessEvent):
|
|
80 |
"""Base class for file event handlers.
|
|
81 |
|
|
82 |
@ivar watch_manager: Inotify watch manager
|
81 |
83 |
|
82 |
84 |
"""
|
|
85 |
def __init__(self, watch_manager):
|
|
86 |
"""Initializes this class.
|
|
87 |
|
|
88 |
@type watch_manager: pyinotify.WatchManager
|
|
89 |
@param watch_manager: inotify watch manager
|
|
90 |
|
|
91 |
"""
|
|
92 |
# pylint: disable-msg=W0231
|
|
93 |
# no need to call the parent's constructor
|
|
94 |
self.watch_manager = watch_manager
|
|
95 |
|
|
96 |
def process_default(self, event):
|
|
97 |
logging.error("Received unhandled inotify event: %s", event)
|
|
98 |
|
|
99 |
def AddWatch(self, filename, mask):
|
|
100 |
"""Adds a file watch.
|
|
101 |
|
|
102 |
@param filename: Path to file
|
|
103 |
@param mask: Inotify event mask
|
|
104 |
@return: Result
|
|
105 |
|
|
106 |
"""
|
|
107 |
result = self.watch_manager.add_watch(filename, mask)
|
|
108 |
|
|
109 |
ret = result.get(filename, -1)
|
|
110 |
if ret <= 0:
|
|
111 |
raise errors.InotifyError("Could not add inotify watcher (%s)" % ret)
|
|
112 |
|
|
113 |
return result[filename]
|
83 |
114 |
|
|
115 |
def RemoveWatch(self, handle):
|
|
116 |
"""Removes a handle from the watcher.
|
|
117 |
|
|
118 |
@param handle: Inotify handle
|
|
119 |
@return: Whether removal was successful
|
|
120 |
|
|
121 |
"""
|
|
122 |
result = self.watch_manager.rm_watch(handle)
|
|
123 |
|
|
124 |
return result[handle]
|
|
125 |
|
|
126 |
|
|
127 |
class SingleFileEventHandler(FileEventHandlerBase):
|
|
128 |
"""Handle modify events for a single file.
|
|
129 |
|
|
130 |
"""
|
84 |
131 |
def __init__(self, watch_manager, callback, filename):
|
85 |
132 |
"""Constructor for SingleFileEventHandler
|
86 |
133 |
|
... | ... | |
92 |
139 |
@param filename: config file to watch
|
93 |
140 |
|
94 |
141 |
"""
|
95 |
|
# pylint: disable-msg=W0231
|
96 |
|
# no need to call the parent's constructor
|
97 |
|
self.watch_manager = watch_manager
|
98 |
|
self.callback = callback
|
99 |
|
self.mask = pyinotify.EventsCodes.ALL_FLAGS["IN_IGNORED"] | \
|
100 |
|
pyinotify.EventsCodes.ALL_FLAGS["IN_MODIFY"]
|
101 |
|
self.file = filename
|
102 |
|
self.watch_handle = None
|
|
142 |
FileEventHandlerBase.__init__(self, watch_manager)
|
|
143 |
|
|
144 |
self._callback = callback
|
|
145 |
self._filename = filename
|
|
146 |
|
|
147 |
self._watch_handle = None
|
103 |
148 |
|
104 |
149 |
def enable(self):
|
105 |
|
"""Watch the given file
|
|
150 |
"""Watch the given file.
|
106 |
151 |
|
107 |
152 |
"""
|
108 |
|
if self.watch_handle is None:
|
109 |
|
result = self.watch_manager.add_watch(self.file, self.mask)
|
110 |
|
if not self.file in result or result[self.file] <= 0:
|
111 |
|
raise errors.InotifyError("Could not add inotify watcher")
|
112 |
|
else:
|
113 |
|
self.watch_handle = result[self.file]
|
|
153 |
if self._watch_handle is not None:
|
|
154 |
return
|
|
155 |
|
|
156 |
# Class '...' has no 'IN_...' member, pylint: disable-msg=E1103
|
|
157 |
mask = (pyinotify.EventsCodes.IN_MODIFY |
|
|
158 |
pyinotify.EventsCodes.IN_IGNORED)
|
|
159 |
|
|
160 |
self._watch_handle = self.AddWatch(self._filename, mask)
|
114 |
161 |
|
115 |
162 |
def disable(self):
|
116 |
|
"""Stop watching the given file
|
|
163 |
"""Stop watching the given file.
|
117 |
164 |
|
118 |
165 |
"""
|
119 |
|
if self.watch_handle is not None:
|
120 |
|
result = self.watch_manager.rm_watch(self.watch_handle)
|
121 |
|
if result[self.watch_handle]:
|
122 |
|
self.watch_handle = None
|
|
166 |
if self._watch_handle is not None and self.RemoveWatch(self._watch_handle):
|
|
167 |
self._watch_handle = None
|
123 |
168 |
|
124 |
169 |
# pylint: disable-msg=C0103
|
125 |
170 |
# this overrides a method in pyinotify.ProcessEvent
|
... | ... | |
132 |
177 |
# case we'll need to create a watcher for the "new" file. This can be done
|
133 |
178 |
# by the callback by calling "enable" again on us.
|
134 |
179 |
logging.debug("Received 'ignored' inotify event for %s", event.path)
|
135 |
|
self.watch_handle = None
|
136 |
|
self.callback(False)
|
|
180 |
self._watch_handle = None
|
|
181 |
self._callback(False)
|
137 |
182 |
|
138 |
183 |
# pylint: disable-msg=C0103
|
139 |
184 |
# this overrides a method in pyinotify.ProcessEvent
|
... | ... | |
143 |
188 |
# replacing any file with a new one, at filesystem level, rather than
|
144 |
189 |
# actually changing it. (see utils.WriteFile)
|
145 |
190 |
logging.debug("Received 'modify' inotify event for %s", event.path)
|
146 |
|
self.callback(True)
|
147 |
|
|
148 |
|
def process_default(self, event):
|
149 |
|
logging.error("Received unhandled inotify event: %s", event)
|
|
191 |
self._callback(True)
|