I'm intending to use Python watchdog to handle a directory where files are written to,
and I'm only interested in image files, trouble is I dont quite grok the code at this page.
This is my attempt:
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
class Beat(PatternMatchingEventHandler):
def on_create(self,event):
print event.src_path
if __name__ == "__main__":
patt = ['\w+[.]jpeg']
event_handler = Beat(patterns=patt,ignore_directories=True,)
observer = Observer()
path = "./"
observer.schedule(event_handler, path, recursive=True)
observer.start()
I'm trying to use the pattern matching class, but I'm getting nothing. How is it supposed to be used?
Based on the source code, fnmatch is being used under the hood. fnmatch can only do UNIX glob-style pattern matching. Which means you may have better luck with *.jpg than \w+[.]jpeg
You can actually use the RegexMatchingEventHandler instead of PatternMatchingEventHandler to accomplish exactly what you want to do:
from watchdog.observers import Observer
from watchdog.events import RegexMatchingEventHandler
class ExampleHandler(RegexMatchingEventHandler):
def on_create(self, event):
print(event.src_path)
if __name__ == "__main__":
pattern = '\w+\.jpeg'
event_handler = ExampleHandler(regexes=[pattern], ignore_directories=True)
observer = Observer()
path = "./"
observer.schedule(event_handler, path, recursive=True)
observer.start()
import time
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
Related
I am trying to use the ''watchdog'' package in python to monitor the change of my folder.
The following code are copied directly from the watchdog documentation, and it works fine.
import sys
import logging
from watchdog.observers import Observer
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 = '.'
event_handler = LoggingEventHandler()
observer = Observer()
observer.schedule(event_handler, path, recursive=False)
observer.start()
try:
while observer.is_alive():
observer.join(1)
finally:
observer.stop()
observer.join()
However, when I tried to change the "path" variable, the code might not work.
For example, if path='./build/', I can see the changes in './build/' folder as expected, but if path='./build/result/', the terminal prints nothing no matter what changes I make to the corresponding folder.
I don't understand why, and I have to ask for help.
I am using ubuntu-20.04LTS through WSL2.
I'm working with watchdog library, and want to send e-mails when a file is saved on a folder.
My problem is that when I save any pdf file on the folder, the module registers 4 modified events, and send four e-mails. Can anyone suggest how can I fix it ?
Here is my code. I used print just to exemplify.
'''
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class Handler(FileSystemEventHandler):
def on_modified(self, event):
print('Modified')
folder_to_track = 'path'
observer = Observer()
event_handler = Handler()
observer.schedule(event_handler, folder_to_track, recursive=True)
observer.start()
try:
print('Monitoring')
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
print('Done')
observer.join()
'''
Output:
Modified
Modified
Modified
Modified
I produced a script that detects the changes on files that are located in a specific directory. I'm trying to write all these changes to a changes.txt file. For this purpose I'm using the sys.stdout = open('changes.txt','w') instruction.
The problem is that whenever I run the script and change a file in the directory and save it, an empty file called changes.txt is created. This file is never written!
#!/usr/bin/python
import time
import sys
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
sys.stdout = open('changes.txt','w')
class MyHandler(FileSystemEventHandler):
def on_modified(self, event):
print "something happened!"
if __name__ == "__main__":
event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, path='.', recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
I'd recommend something like
#!/usr/bin/python
import time
import sys
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class MyHandler(FileSystemEventHandler):
def __init__(self, f):
self.f = f
def on_modified(self, event):
self.f.write("something happened!\n")
self.f.flush()
if __name__ == "__main__":
with open('changes.txt','w') as f:
event_handler = MyHandler(f)
observer = Observer()
observer.schedule(event_handler, path='.', recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
as you can see, the control over where your outputwill be written to has been handed to the caller (the one instanciating MyHandler) instead of the callee (on_modified).
This means you can also do
event_handler = MyHandler(sys.stdout)
and see the output instead of the output being put into the file.
An additional benefit: using a context manager you can be sure the file is closed properly, even if errors occurr.
I am trying to get the name of a file that changes periodically.
I am using watchdog to do this.
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
timestr = time.strftime("%Y.%m.%d-%H.%M.%S")
class MyHandler(FileSystemEventHandler):
def on_modified(self, event):
change_log = open('change_log_' + timestr + '.txt', 'aw')
change_log.write('Time the file changed: ' + timestr + '\n')
change_log.close()
if __name__ == "__main__":
event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, path='.', recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
For some reason this prints out about 62 lines in the "change_log" file. This is not very useful.
What I would like to do is to print the name of the file that changed, or store it in a variable to pass to my other module.
In your example, if you need a file name, it is necessary to replace 'change_log_' with event.src_path. See the official code for more details.
You can also see the use of event.src_path in this answer as I used it in the printout.
It looks like the event object that is sent to your handler includes the information that you seek:
http://pythonhosted.org/watchdog/api.html#watchdog.events.FileSystemEvent
Use the src_path property of the event object that's passed into your FileSystemEvent subclass handler method to get the filename.
I am trying to use Python Watchdog to monitor a directory for changes. However, when I try to run the Quickstart example:
import time
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
if __name__ == "__main__":
event_handler = LoggingEventHandler()
observer = Observer()
observer.schedule(event_handler, path='.', recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
by putting in it the file test.py, nothing displays in the Terminal window where I ran it. What is causing this to happen, and how can I fix it?
Try the example on github: https://github.com/gorakhargosh/watchdog
This example seems to work as opposed to the one on the docs site that does not.