Watchdog ignore pattern - python

I tried working with other posts on here about this, but couldn't get it to work. I'm a newbie with Python.
I need help with ignore_pattern.
I'm uploading images to a folder and temporarily images are being added with __, so the actual image added while file is uploading is __image-name.jpg. After it's done uploading it gets added again as image-name.jpg (and deletes the __image-name.jpg.
I want to ignore all the __image-name.jpg files with watchdog.
Here's my code:
class Watcher:
DIRECTORY_TO_WATCH = "director/where/images/are/uploaded"
def __init__(self):
self.observer = Observer()
def run(self):
event_handler = Handler()
self.observer.schedule(event_handler, self.DIRECTORY_TO_WATCH, recursive=True)
self.observer.start()
try:
while True:
time.sleep(5)
except:
self.observer.stop()
print("Error")
self.observer.join()
class Handler(FileSystemEventHandler):
#staticmethod
def on_any_event(event):
if event.is_directory:
return None
elif event.event_type == 'created':
# Take any action here when a file is first created.
print(event.src_path)
img = Image.open(event.src_path)
for result in engine.classify_with_image(img, top_k=3):
print('---------------------------')
print(labels[result[0]])
print('Score : ', result[1])
# elif event.event_type == 'modified':
# Taken any action here when a file is modified.
# print("Received modified event - %s." % event.src_path)
elif event.event_type == 'deleted':
# Taken any action here when a file is deleted.
print("Received deleted event - %s." % event.src_path)
if __name__ == '__main__':
w = Watcher()
w.run()
Thank you so much.

Does event.src_path returns a string? If so you can use the startswith method of the string class to skip over the images you don't want.
For example:
elif event.event_type == 'created':
# Take any action here when a file is first created.
print(event.src_path)
# Check if this filename starts with "__" and execute the next block
if not event.src_path.startswith('__'):
img = Image.open(event.src_path)
for result in engine.classify_with_image(img, top_k=3):
print('---------------------------')
print(labels[result[0]])
print('Score : ', result[1])
# else do nothing

Related

Passing methods into methods Python

I have a class in python. What I am trying to achieve is to pass one method into another. Say I have a method that is scanning for directories on a page and another method that opens the wordlist for which it will format all the words to pass into the method that is scanning the directories.
My issue is that the method that is formatting the words by stripping them, is not being passed into the method that is scanning directories.
class exampleClass:
def __init__(self):
pass
def openWordlist(self):
try:
with open(wordlist, 'r') as file:
for word in file:
word = word.strip()
except FileNotFoundError:
print('File does not exist')
def scanDomain(self):
try:
domain = 'http://' + targetURL + '/' + word
r = requests.get(domain)
if r.status_code == 200:
print(f'[+] {domain}')
else:
if isVerbose:
print(f'[~] {domain}')
if r.status_code == 200:
print(f'[+] {domain}')
except requests.exceptions.ConnectionError:
print('[!] CONNECTION ERROR! Exiting...')
sys.exit(0)
if __name__ == '__main__':
obj = exampleClass()
obj.openWordlist()
obj.scanDomain()
My goal is to pass the method openWordlist() to the scanDomain() method so it gets to read that wordlist and parse each request.
To call a method inside another method, you can call it using the self argument (which represents your class inside its methods).
class MyClass:
def __init__(self):
pass
def foo(self):
return True
def bar(self):
res = self.foo()
return res
It's not clear from your example how openWordlist and scanDomain are supposed to interact. I infer from the shared variable word that it is supposed to be shared between the two methods. A good way to do this is to make word an attribute of the class instance.
class exampleClass:
def __init__(self):
self.words = None
self.targetURL = ""
def openWordlist(self, wordlist):
try:
with open(wordlist, 'r') as file:
self.words = [word.strip() for word in file]
except FileNotFoundError:
print('File does not exist')
def scanDomain(self):
for word in self.words:
domain = 'http://' + self.targetURL + '/' + word
try:
r = requests.get(domain)
except requests.exceptions.ConnectionError:
print('[!] CONNECTION ERROR! Exiting...')
continue
if r.status_code == 200:
print(f'[+] {domain}')
else:
if isVerbose:
print(f'[~] {domain}')
I'm not sure if it is what you want, but you can simply add an argument to the function that should receive the other function, and then execute the function that was passed like this:
class exampleClass():
def openWordList(self):
print("Do something else")
def scanDomain(self, a_function):
print("Do something")
a_function()
if __name__ == "__main__":
obj = exampleClass()
obj.scanDomain(obj.openWordList)

File Monitoring using watchdog library

I have written one python script to monitor one local folder which is having only .txt files and i want to start this script automatically if some changes happened to the folder(created,deleted or updated)
I tried to run this script and also tried to make changes in the directory, but i couldn't see any output and no error messages. It always says "Process finished with exit code 0" can any one review my code and give me some tips where to correct to get the expected out put.
import os
import sys
import time
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
#Step 1 Create the event handler
if __name__ == "__main__":
patterns = ".txt"
ignore_patterns = None
ignore_directories = False
case_sensitive = True
event_handler = PatternMatchingEventHandler(patterns, ignore_patterns, ignore_directories, case_sensitive)
#step 2 Handle all the events
def on_created(event):
print("new files has been created!")
def on_deleted(event):
print("Some files has been Deleted")
def on_modified(event):
print("Some files has been modified")
def on_moved(event):
print("Some files has been moved")
#step 3 specify to the handler that we want these functions to be called
event_handler.on_created = on_created
event_handler.on_deleted = on_deleted
event_handler.on_modified = on_modified
event_handler.on_moved = on_moved
#step 4 create an observer
path = "T:\Laboratory\Instruments\Worklists\TrackMateRacks\old"
go_recursively = True
my_observer = Observer()
my_observer.path(event_handler, path, recursive=go_recursively)
# start the observer
my_observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
my_observer.stop()
my_observer.join()
you have to move the lines after " # start the observer" to the very left.
otherwise there will be executed nothing. that lines are part of on_moved(). but you want them to be executed if you start the script.
or
for most programs it's useful to add this line:
if __name__ == '__main__':
bevore line "# start the observer"
than your my_observer.start() will be executed, if you call your script. but if you import your script in another script, this will not be executed, but the other script can use all the functions, you created.
It seems, that you're really new to Python. You've to watch the indents, they're part of the syntax.
Exceptionally I reformat the complete code for you:
import os
import sys
import time
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
#Step 1 Create the event handler
patterns = ".txt"
ignore_patterns = None
ignore_directories = False
case_sensitive = True
event_handler = PatternMatchingEventHandler(patterns, ignore_patterns, ignore_directories, case_sensitive)
#step 2 Handle all the events
def on_created(event):
print("new files has been created!")
def on_deleted(event):
print("Some files has been Deleted")
def on_modified(event):
print("Some files has been modified")
def on_moved(event):
print("Some files has been moved")
#step 3 specify to the handler that we want these functions to be called
event_handler.on_created = on_created
event_handler.on_deleted = on_deleted
event_handler.on_modified = on_modified
event_handler.on_moved = on_moved
#step 4 create an observer
def main():
path = "T:\Laboratory\Instruments\Worklists\TrackMateRacks\old"
go_recursively = True
my_observer = Observer()
my_observer.path(event_handler, path, recursive=go_recursively)
# start the observer
my_observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
my_observer.stop()
my_observer.join()
if __name__ == "__main__":
main()
#end of file
Good luck!

message_filters doesn't call the callback function

I'm trying to use the message_filters in order to subscribe to two topics. Here's my code
class sync_listener:
def __init__(self):
self.image_sub = message_filters.Subscriber('camera/rgb/image_color', Image)
self.info_sub = message_filters.Subscriber('camera/projector/camera_info', CameraInfo)
self.ts = message_filters.TimeSynchronizer([self.image_sub, self.info_sub], 10)
self.ts.registerCallback(self.callback)
def callback(self, image, camera_info):
print("done")
def main(args):
ls = sync_listener()
rospy.init_node('sample_message_filters', anonymous=True)
try:
rospy.spin()
except KeyboardInterrupt:
print("Shutting down")
if __name__ == '__main__':
main(sys.argv)
But it never goes to the callback function. It just freezes at rospy.spin().
Rather than using TimeSynchronizer I used ApproximateTimeSynchronizer and it worked. So, I changed the code to-
class sync_listener:
def __init__(self):
self.image_sub = message_filters.Subscriber('camera/rgb/image_color', Image)
self.info_sub = message_filters.Subscriber('camera/projector/camera_info', CameraInfo)
self.ts = message_filters.ApproximateTimeSynchronizer([self.image_sub, self.info_sub], 1, 1) # Changed code
self.ts.registerCallback(self.callback)
def callback(self, image, camera_info):
print("done")
def main(args):
ls = sync_listener()
rospy.init_node('sample_message_filters', anonymous=True)
try:
rospy.spin()
except KeyboardInterrupt:
print("Shutting down")
if __name__ == '__main__':
main(sys.argv)
Before finding this solution, I just used global variables to access the message of the first topic by assigning the message to the global variable in the callback and used it on the callback of the second, and that's how I was able to work with both. It's not clean but saves hours of frustration.

watchdog in directory monitoring is not working

I want to watch a folder for addition, modification and deletion of file and execute a command whenever any of this event occurs.
I found this tutorial that helped https://www.michaelcho.me/article/using-pythons-watchdog-to-monitor-changes-to-a-directory
so here is the code I now have
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class Watcher:
DIRECTORY_TO_WATCH = "/Users/***/desktop/google drive/protpics"
def __init__(self):
self.observer = Observer()
def run(self):
event_handler = Handler()
self.observer.schedule(event_handler, self.DIRECTORY_TO_WATCH, recursive=True)
self.observer.start()
try:
while True:
time.sleep(5)
except:
self.observer.stop()
print("Error")
self.observer.join()
class Handler(FileSystemEventHandler):
#staticmethod
def on_my_event(event):
if event.is_directory:
return None
elif event.event_type == 'created':
#Take any action here when a file is first created.
print ("Recived created event - %s" % event.src_path)
elif event.event_type == 'modified':
# Take any action here when a file is modified.
print ("Recieved modified event - %s" % event.src_path)
if __name__ == '__main__':
W = Watcher()
W.run()
the problem now is that when I added a new file to the directory no message gets printed out. What am I doing wrong and how can I fix it?
Couldn't you figure out the difference between your code and example's? In your link, the author use on_any_event, but you are using on_my_event. There isn't a method named on_my_event.
Have a check at official document: http://pythonhosted.org/watchdog/api.html#watchdog.events.FileSystemEventHandler

re-using the variable in a function in a class in python

I will try to explain the problem I am facing with a small piece of code:
class MyHandler(PatternMatchingEventHandler):
patterns = ["*.csv","*.processing", "*.transforming","*.loading"]
def process(self, event):
eventFileName = event.src_path
eventType = event.event_type
if eventType == 'moved':
eventFileName = event.dest_path
fileNameWithPath, fileExtension = os.path.splitext(eventFileName)
if fileExtension == '.processing':
# Here some function is called to do something, and then appends ".loading" to the file name
testVariable = 75.3
if fileExtension == '.loading':
print testVariable
def on_moved(self, event):
self.process(event)
def on_created(self, event):
self.process(event)
if __name__ == '__main__':
observer = Observer()
observer.schedule(MyHandler(), path='.')
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
When I try to do the above I am getting this error: global name 'testVariable' is not defined which kinda makes sense but how do I make the above work? I tried to define "testVariable" globally and initiated to 0 and tried using it the way I showed in above code but it did not work as well.
I also tried initiating testVariable as testVariable=0 inside the class (right after "patterns = ....." line but I got this error: local variable "testVariable" referenced before assignment pointing towards print testVariable. So that didnot work as well.
"(...) how do I make the above work?"
By defining testVariable outside your conditional statements. E.g. here:
def process(self, event):
eventFileName = event.src_path
testVariable = 0
...
This will make it available within the process function. If you want it to be available throughout the class, you can define it here:
class MyHandler(PatternMatchingEventHandler):
patterns = ["*.csv","*.processing", "*.transforming","*.loading"]
testVariable = 0
But then you have to access it via the self object within functions like so:
def process(self, event):
...
if fileExtension == '.processing':
# Here some function is called to do something, and then appends ".loading" to the file name
self.testVariable = 75.3
testVariable only exists if you have the extension ".processing". If it's ".loading", the program tries to print a variable that hasn't been made to exist.
If statements do not create a garbage collecting scope in Python, so you don't have to "declare" it outside, so long as somewhere in your if-tree, tesVariable gets a value.
def process(self, event):
def extension():
eventFileName = event.src_path
eventType = event.event_type
if eventType == 'moved':
eventFileName = event.dest_path
return os.path.splitext(eventFileName)[1]
if extension() == '.processing':
...
if extension() == '.loading':
...

Categories