我正在使用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()

当我应用下载时,有没有一种方法可以“暂停”观察者,完成后再次“取消暂停”它?

最佳答案

我需要暂停功能,因此我在使用以下观察器:

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与OS无关。

09-26 06:04