我正在使用Watchdog来监控目录并使其与Dropbox保持同步。
我面临的情况是每次从Dropbox下载文件时,都会触发上传事件,因为我需要写入Watchdog监控的目录。这是我正在使用的代码。
event_handler = UploadHandler.UploadHandler()
observer = Observer()
observer.schedule(event_handler, path=APP_PATH, recursive=True)
observer.start()
try:
while True:
# Apply download here
time.sleep(20)
except KeyboardInterrupt:
observer.stop()
observer.join()
有没有办法在我应用下载时“暂停”观察者,并在我完成后再次“取消暂停”它?
答案 0 :(得分:1)
花了很多时间(现在凌晨5点,为任何错别字和东西道歉)这两个答案在这里无济于事,我感到愚蠢,并为我的需求实现了一个更简单的解决方案。 / p>
摘要(以下代码)
global
或类似内容的PAUSED
on_modified
内或您在事件处理程序中使用的任何事件函数,请检查PAUSED is True
。将它放在文件的顶部:
global PAUSED
PAUSED = False
将它放在EventHandler.on_modified()
或任何事件处理程序中,以及您正在使用的任何事件函数:
# Retrieve global
global PAUSED
# If PAUSED, exit
if PAUSED is True:
return
# If not, pause anything else from running and continue
PAUSED = True
# Do stuff here
# Once finished, allow other things to run
PAUSED = False
推理:这将完全忽略尝试在暂停期间运行的任何内容。我需要这个,因为看门狗每次“文件修改”事件最多会激活5次,因为文件仍然被写入。这可确保它只触发一次,暂停,并且在其他重复事件到期之前不会恢复。
答案 1 :(得分:0)
您可以覆盖类dispatch_events
的方法Observer
,以跳过您不想发送的事件。以下是如何执行此操作的示例:
class SkipObserver(watchdog.observers.Observer):
def __init__(self, *args):
Observer.__init__(self, *args)
self._skip_list = []
def skip(self, event):
with self._lock:
self._skip_list.append(event)
def dispatch_events(self, event_queue, timeout):
event, watch = event_queue.get(block=True, timeout=timeout)
try:
if event in self._skip_list:
self._skip_list.remove(event)
else:
self._dispatch_event(event, watch)
except KeyError:
pass
event_queue.task_done()
现在在示例中将Observer
替换为SkipObserver
,并使用方法skip
跳过事件。小心在处理程序中使用skip
,因为这会以死锁结束,skip
在此处实现阻塞。在处理事件时,观察者被锁定。
如果要为每个处理程序指定跳过,可以使用与上述处理程序类似的方法。
答案 2 :(得分:0)
我需要暂停功能,所以我使用以下观察者:
import time
import contextlib
import watchdog.observers
class PausingObserver(watchdog.observers.Observer):
def dispatch_events(self, *args, **kwargs):
if not getattr(self, '_is_paused', False):
super(PausingObserver, self).dispatch_events(*args, **kwargs)
def pause(self):
self._is_paused = True
def resume(self):
time.sleep(self.timeout) # allow interim events to be queued
self.event_queue.queue.clear()
self._is_paused = False
@contextlib.contextmanager
def ignore_events(self):
self.pause()
yield
self.resume()
然后我可以使用pause()
和resume()
方法直接暂停观察者,但我的主要用例是当我只想忽略因写入目录而导致的任何事件时。我正在观看,我使用上下文管理器:
import os
import datetime
import watchdog.events
class MyHandler(watchdog.events.FileSystemEventHandler):
def on_modified(self, event):
with OBSERVER.ignore_events():
with open('./watchdir/modifications.log', 'a') as f:
f.write(datetime.datetime.now().strftime("%H:%M:%S") + '\n')
if __name__ == '__main__':
watchdir = 'watchdir'
if not os.path.exists(watchdir):
os.makedirs(watchdir)
OBSERVER = PausingObserver()
OBSERVER.schedule(MyHandler(), watchdir, recursive=True)
OBSERVER.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
OBSERVER.stop()
OBSERVER.join()
您可以通过将两个代码块保存在一个文件中,运行它,以及在创建的' watchdir'中添加/编辑/删除文件来测试它。目录。修改的时间戳将附加到' watchdir / modifications.log'。
此功能appears to be built into pyinotify,但该库仅适用于linux,而watchdog与操作系统无关。