Trouble getting Watchdog observer to stop/join (python) - python

I'm using the watchdog python package to detect if a file has been downloaded (which I'm doing in selenium). This is the code I'm using and it successfully detects file creation, but my call to self.observer.stop() doesn't seem to work and the program stalls. Any thoughts?
class MyEventHandler(FileSystemEventHandler):
def __init__(self, observer):
self.observer = observer
def on_created(self, event):
print "file created"
self.observer.stop()
def check_download(download_folder):
file_location = download_folder
print(download_folder)
observer = Observer()
event_handler = MyEventHandler(observer)
observer.schedule(event_handler, file_location)
observer.start()
observer.join()
return 0

Fixed with:
class MyEventHandler(FileSystemEventHandler):
def __init__(self, observer):
self.observer = observer
def on_created(self, event):
if not event.src_path.endswith(".pdf"):
global check
check = 1 # signal download complete
def initiate_download(PDF, download_folder):
file_location = download_folder
global check
check = 0
observer = Observer()
event_handler = MyEventHandler(observer)
observer.schedule(event_handler, file_location)
observer.start()
PDF.click()
while check == 0:
time.sleep(1) # wait for download signal
observer.stop()
observer.join()
return 0
Probably not a "proper" solution but it seemed to do the trick.

Related

Duplicated output with Watchdog library

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

Detect the changes in a file and write them in a file

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.

Block until file in directory changes

I want to use watchdog to block until a file changes in a directory. What I'm doing is sleeping while a variable is False. The problem with this, though, is that I can't interrupt the sleep; there's still up to 1s delay to break when the file changes. How can I break out of the sleep and continue to the point after the sleep? Or more generically, block until a file changes? Here's my code:
import sys
import time
import os
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
if __name__ == "__main__":
observer = Observer()
def nothing():
pass
class FileChangeHandler(FileSystemEventHandler):
done = False
def on_any_event(self, event):
print 'Got event'
FileChangeHandler.done = True
path = sys.argv[1] if len(sys.argv) > 1 else '.'
event_handler = FileChangeHandler()
observer.schedule(event_handler, path, recursive=True)
observer.start()
while not event_handler.done:
time.sleep(1)
print 'Done'
observer.stop()
observer.join()

Run Python script when Directory is updated

I have a script which i want to execute when specific directory is updated. To be more specific: development team have 4 directories (lets say "a", "b", "c" and "d") which they update from time to time. I have a script which take as a parameter name of directory. I wan to execute this script with parameter "a" when directory "a" is updated. Is it Possible to do with Jenkins? If so, can I do same thing using SVN?
You can do that using python itself, with watchdog library.
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
class FileHandler(PatternMatchingEventHandler):
def process(self, event):
print event.src_path, event.event_type # print now only for degug
def on_modified(self, event):
self.process(event)
def on_created(self, event):
self.process(event)
if __name__ == '__main__':
args = sys.argv[1:]
observer = Observer()
observer.schedule(MyHandler(), path=args[0] if args else '.')
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()

Stop monitoring a file with watchdog

I have this small script to monitoring with watchdog one single file (test.txt).
Till now I got a screen message each time the file is modified but I need just the get the notification for the first time, it's mean to stop monitoring, is there any way I could tell watchdog to stop it?
Here is my code:
#!/usr/bin/python
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
file_to_scan = "test.txt"
class MyHandler(FileSystemEventHandler):
def on_modified(self, event):
if file_to_scan in event.src_path:
print "Got it!", event.src_path
#### I want to stop here the monitoring
def on_created(self, event):
pass
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()

Categories