我很高兴使用 watchdog 包,特别是PollingObserver来监视目录中的文件事件。它工作得很好 - 直到我正在观看的目录被删除。接下来发生的是轮询目录的代码调用stat(),并引发异常。处理这个问题的最佳方法是什么?我不知道如何捕获此异常,因为它位于单独的线程中。
示例代码:
import sys
import time
import logging
from watchdog.observers.polling import PollingObserver
from watchdog.events import LoggingEventHandler
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
path = sys.argv[1] if len(sys.argv) > 1 else '.'
event_handler = LoggingEventHandler()
observer = PollingObserver()
print("Watching: ", path)
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
Run Code Online (Sandbox Code Playgroud)
要明白我的意思,请将现有目录作为参数传递,然后将其删除。
我想在 FTP 目录中添加新文件后立即将文件从 FTP 服务器获取到本地。
我知道可以使用看门狗观察器看到本地计算机上目录的更改。
但我想检查 FTP 服务器上目录的更改(添加新文件、删除文件)。
如何实现这一目标?
我用来检查本地计算机上目录更改的代码:
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import ftplib
import time
class ExampleHandler(FileSystemEventHandler):
def on_created(self, event):
print "Got event for file %s" % event.src_path
session = ftplib.FTP('address','username','password')
path='/directory/to/check'
session.cwd(path)
observer = Observer()
event_handler = ExampleHandler()
observer.schedule(event_handler, path_of_the_directory)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
Run Code Online (Sandbox Code Playgroud) 我正在寻找带有看门狗观察器的基于烧瓶的 Web 应用程序的示例。更具体地说,我想使用看门狗观察器来检测预定义目录中的任何更改,并根据更改更新 Web 应用程序。我可以为它们中的每一个找到许多示例,即基于烧瓶的 Web 应用程序和看门狗观察者示例。
但是,我不知道如何集成两个示例并顺利运行它们。谁能提供一个简单的例子?
另外,我想知道我是否可以用 Celery 工人运行看门狗观察者?
谢谢
编辑:我使用芹菜工人来运行看门狗观察者来观察目录及其子目录,如下所示:
@celery.task(bind=True)
def _watcher(self):
observer = Observer()
handler = MyHandler()
observer.schedule(handler, '.')
observer.start()
try:
while True:
if not handler.event_q.empty():
event, ts = handler.event_q.get()
self.update_state(state='PROGRESS', meta={'src_path': event.src_path, 'event_type': event.event_type})
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
return {'src_path': 'srcpath', 'event_type': 'eventtype'}
Run Code Online (Sandbox Code Playgroud)
然后,从前端,每隔 1 秒,它调用 GET 函数来更新任何更改(如果有)。这有点hacky。
我最终想要实现的是 1) 继续观察目录及其子目录,2) 如果有任何更改,则根据更改更新数据库以及 3) 根据更改更新前端。
到目前为止,我可以使用看门狗(上面代码中的 MyHandler 类)根据文件系统中的更改更新数据库。但是,我仍然在寻找更好的解决方案来观察 Flask 框架内的变化并更新前端的变化。
我正在重温 python 语言,但在设置环境时遇到了困难。
我正在使用 - Mac Mojave (10.14) - python 2.7.10(与系统一起打包)- python 3.7.4(使用自制软件安装)-自制软件 2.1.14 - pip 19.2.3
尝试通过 pip 安装看门狗时遇到错误消息。我相信该错误是由 pip 尝试安装在 python 2.7 文件夹(没有足够的权限)而不是 python 3 文件夹中引起的
我试过卸载、重新安装和升级 python 3
尝试通过 pip 安装看门狗时遇到以下错误消息
1 error generated.
Error compiling module, falling back to pure Python
running install_lib
creating /Library/Python/2.7/site-packages/yaml
error: could not create '/Library/Python/2.7/site-packages/yaml': Permission denied
----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/4d/spq3r5t92654252ql994_l540000gr/T/pip-install-nqmq6O/PyYAML/setup.py'"'"'; __file__='"'"'/private/var/folders/4d/spq3r5t92654252ql994_l540000gr/T/pip-install-nqmq6O/PyYAML/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, …Run Code Online (Sandbox Code Playgroud) 我正在运行本文中的代码,并进行了一些更改以监视仅一种格式(位于.csv指定目录中)的文件创建/添加。
现在的问题是:
每当添加的新文件不是 .csv 格式时,我的程序就会中断(停止监视,但继续运行);为了弥补这一点,这就是我对ignore_patterns参数所做的事情(但在添加其他格式的新文件后程序仍然停止监视):
PatternMatchingEventHandler(patterns="*.csv", ignore_patterns=["*~"], ignore_directories=True, case_sensitive=True)
完整的代码是:
import time
import csv
from datetime import datetime
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
from os import path
from pandas import read_csv
# class that takes care of everything
class file_validator(PatternMatchingEventHandler):
def __init__(self, source_path):
# setting parameters for 'PatternMatchingEventHandler'
super(file_validator, self).__init__(patterns="*.csv", ignore_patterns=["*~"], ignore_directories=True, case_sensitive=True)
self.source_path = source_path
self.print_info = None
def on_created(self, event):
# this is the new file that was created …Run Code Online (Sandbox Code Playgroud) 我刚刚开始在 Mac 上使用Python 中的Watchdog 库,并且正在进行一些基本测试以确保一切按照我的预期运行。不幸的是,它们不是——我似乎只能获取包含注册事件的文件的文件夹的路径,而不是文件本身的路径。
下面是一个简单的测试程序(对 Watchdog 提供的示例稍加修改),用于在注册事件时打印出事件类型、路径和时间。
import time
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
from watchdog.events import FileSystemEventHandler
class TestEventHandler(FileSystemEventHandler):
def on_any_event(self, event):
print("event noticed: " + event.event_type +
" on file " + event.src_path + " at " + time.asctime())
if __name__ == "__main__":
event_handler = TestEventHandler()
observer = Observer()
observer.schedule(event_handler, path='~/test', recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
Run Code Online (Sandbox Code Playgroud)
src_path 变量应包含发生事件的文件的路径。
但是,在我的测试中,当我修改文件时, src_path 仅打印包含该文件的文件夹的路径,而不是文件本身的路径。例如,当我修改moon.txt文件夹中的文件时europa,程序会打印以下输出:
event noticed: …Run Code Online (Sandbox Code Playgroud) 我正在尝试学习 python-watchdog,但我有点困惑为什么我设置的作业运行不止一次。所以,这是我的设置:
#handler.py
import os
from watchdog.events import FileSystemEventHandler
from actions import run_something
def getext(filename):
return os.path.splitext(filename)[-1].lower()
class ChangeHandler(FileSystemEventHandler):
def on_any_event(self, event):
if event.is_directory:
return
if getext(event.src_path) == '.done':
run_something()
else:
print "event not directory.. exiting..."
pass
Run Code Online (Sandbox Code Playgroud)
观察者设置如下:
#observer.py
import os
import time
from watchdog.observers import Observer
from handler import ChangeHandler
BASEDIR = "/path/to/some/directory/bin"
def main():
while 1:
event_handler = ChangeHandler()
observer = Observer()
observer.schedule(event_handler, BASEDIR, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
if __name__ == '__main__': …Run Code Online (Sandbox Code Playgroud) 重命名监视程序中正在监视的文件会生成on_moved事件触发器.我遇到的问题是没有办法告诉文件被移动/重命名的内容(因为重命名文件时也会发生on_moved事件触发器).有什么方法可以将它构建到看门狗中,还是应该在我正在编写的程序中构建一个变通方法?
这是一些示例代码
#!/usr/bin/python
'''
Created on 2014-07-03
'''
import sys
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
'''
Extend FileSystemEventHandler to be able to write custom on_any_event method
'''
class MyHandler(FileSystemEventHandler):
'''
Overwrite the methods for creation, deletion, modification, and moving
to get more information as to what is happening on output
'''
def on_created(self, event):
print("created: " + event.src_path)
def on_deleted(self, event):
print("deleted: " + event.src_path)
def on_modified(self, event):
print("modified: " + event.src_path)
def on_moved(self, event): …Run Code Online (Sandbox Code Playgroud) 我创建了一个修改过的看门狗示例,以便监视已添加到 Windows 中特定目录的 .jpg 照片文件。
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
paths = []
xp_mode = 'off'
class FileHandler(FileSystemEventHandler):
def on_created(self, event):
if xp_mode == 'on':
if not event.is_directory and not 'thumbnail' in event.src_path:
print "Created: " + event.src_path
paths.append(event.src_path)
def on_modified(self, event):
if not event.is_directory and not 'thumbnail' in event.src_path:
print "Modified: " + event.src_path
paths.append(event.src_path)
if __name__ == "__main__":
path = 'C:\\'
event_handler = FileHandler()
observer = Observer()
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
while …Run Code Online (Sandbox Code Playgroud) python-watchdog ×10
python ×9
python-3.x ×2
celery ×1
csv ×1
filesystems ×1
flask ×1
ftp ×1
ftplib ×1
macos ×1
pip ×1
python-2.7 ×1
pywin32 ×1