6

i would like to know how to check change of a specific file under a folder. I found that watchdog module could check change for files in folder but i need 1 file only (with fixed name).

Please kindly help on this and thanks.

class MyHandler(FileModifiedEvent):
    def on_modified(self, event):

if __name__ == "__main__":
        integrity_file_path = DATASTORE_DIRECTORY_PATH + '/schedule.xml'
        event_handler = MyHandler()
        observer = Observer()
        observer.schedule(MyHandler(), path=integrity_file_path,recursive=True)
        observer.start()

        try:
            while True:
                time.sleep(5)
        except KeyboardInterrupt:
            observer.stop()
        observer.join()

3 Answers 3

4

You can subclass the watchdog.events.PatternMatchingEventHandler event handler and modify it to do whatever you want in the case of an event. You would set the pattern to be the filename that you want to monitor.

However, this one's a bit tricky. Under the covers it's using pathtools.patterns to do its pattern matching. And it's also appending the directory to the pattern being matched. Which means you'll need to pass into the event handler the full path of your file as your filename "pattern" argument. If you don't, the pattern matching will fail and you won't get any event notifications.

Here's an example below:

import sys, os.path, time, logging
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler


class MyEventHandler(PatternMatchingEventHandler):
    def on_moved(self, event):
        super(MyEventHandler, self).on_moved(event)
        logging.info("File %s was just moved" % event.src_path)

    def on_created(self, event):
        super(MyEventHandler, self).on_created(event)
        logging.info("File %s was just created" % event.src_path)

    def on_deleted(self, event):
        super(MyEventHandler, self).on_deleted(event)
        logging.info("File %s was just deleted" % event.src_path)

    def on_modified(self, event):
        super(MyEventHandler, self).on_modified(event)
        logging.info("File %s was just modified" % event.src_path)

def main(file_path=None):
    logging.basicConfig(level=logging.INFO,
        format='%(asctime)s - %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S')
    watched_dir = os.path.split(file_path)[0]
    print 'watched_dir = {watched_dir}'.format(watched_dir=watched_dir)
    patterns = [file_path]
    print 'patterns = {patterns}'.format(patterns=', '.join(patterns))
    event_handler = MyEventHandler(patterns=patterns)
    observer = Observer()
    observer.schedule(event_handler, watched_dir, recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()



if __name__ == "__main__":
    if len(sys.argv) > 1:
        path = sys.argv[1]
        main(file_path=path.strip())
    else:
        sys.exit(1)

Executing the watchdog python script (before modifying the file):

(stackoverflow)[[email protected] stackoverflow]# python watchschedule.py /usr/local/src/stackoverflow/watchdog/schedule.xml
watched_dir = /usr/local/src/stackoverflow/watchdog
patterns = /usr/local/src/stackoverflow/watchdog/schedule.xml

Modifying the schedule.xml file in a separate console:

[[email protected] watchdog]# echo "I just modified this file" >> schedule.xml

Results after modifying schedule.xml:

(stackoverflow)[[email protected] stackoverflow]# python watchschedule.py /usr/local/src/stackoverflow/watchdog/schedule.xml
watched_dir = /usr/local/src/stackoverflow/watchdog
patterns = /usr/local/src/stackoverflow/watchdog/schedule.xml
2015-08-31 19:30:31 - File /usr/local/src/stackoverflow/watchdog/schedule.xml was just modified
Sign up to request clarification or add additional context in comments.

3 Comments

This works as advertised, Thank you. How would I take out the need for entering the file structure in the command line? Nothing seems to work. I've tried the three most logical places in the main function.
@ElliotRobert You can hardcode the file path. Under the if __name__ == "__main__": section, remove the entire if-else block and replace it with a call to the main() function, passing in your hardcoded path as an argument to main(). For example: main(file_path='/usr/local/src/stackoverflow/watchdog/schedule.xml')
This only worked for the directory it's self, including the file name would cause an error, I had to run the .strip() function on the full path with file name for it to work. Thanks a million Joe.
0

I would say you can check the modification time for the file according to

How to get file creation & modification date/times in Python?

Define a threshold and compare the current time with the modification time, you may know if the file is updated. This would work if the file is not getting modified super frequently.

But anyway, there's gonna be false alarm if someone opened the file, typed in some garbage then deleted and saved.

Comments

0

My guess is to check in on_modified() if isDirectory is true or not

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.