Python - 将多个文件添加到文件夹,但 运行 事件仅发生一次
Python - add multiple files to folder but run event only once
我正在尝试让看门狗监听文件夹更改 (adding/deleting) 个文件。
我的问题是,每次我从这个文件夹(及其子文件夹)copy-create/delete 几个文件,事件链开始一个接一个文件。
如何让 on_event()
方法在多个文件 creation/deletion 之后只被调用一次?
假设我要将两张图片复制到此文件夹。
我希望事件处理程序在文件传输完成后仅被调用一次,并且而不是两次——每个图像一次——因为它当前有效。
谢谢!
代码 运行s 在 raspberry pi 3 上 python 3.7.
代码如下:
import os
import time
import psutil
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
i = 0
def show_stats():
global i
read = "read #" + str(i) + ":"
mem = "\nmemory in use: " + str(psutil.virtual_memory().percent)+"%"
cpu = "\ncpu load: " + str(psutil.cpu_percent())+"%"
temp = "\ncurrent " + \
os.popen("vcgencmd measure_temp").readline().replace(
"=", ": ").replace("'C", " C°")
end = "\n=================="
i += 1
stats = read + mem + cpu + temp + end
return stats
class Watcher:
DIRECTORY_TO_WATCH = r'/home/pi/Desktop/jsSlider/images'
def __init__(self):
self.observer = Observer()
print("watching ", self.DIRECTORY_TO_WATCH, "...")
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)
print(show_stats())
except Exception as e:
self.observer.stop()
print(e)
self.observer.join()
class Handler(FileSystemEventHandler):
@staticmethod
def on_event(event):
wait = 1
elif event.event_type == 'created' or event.event_type == 'deleted':
print("Received event - %s. " %event.src_path, str(event.event_type))
time.sleep(wait) #i found that its best to give some timeout between commands because it overwhelmed the pi for some reason (one second seems to be enough)...
os.system('python /home/pi/Desktop/Slider/scripts/arr_edit.py') #recreate the JS array
time.sleep(wait)
os.system('cp -r /home/pi/Desktop/jsSlider/scripts/imgArr.js /home/pi/Desktop/jsSlider/themes/1') #copy the newly created JS array to its place
time.sleep(wait)
os.system('sudo pkill chromium') #"refresh" the page -the kiosk mode reactivates the process...
# os.system('cls')
print('done!')
if __name__ == '__main__':
w = Watcher()
w.run()
编辑我
有些诊所的电视连接到电视的 rpi3 性能很差,它在信息亭模式下显示本地 html 文件中的图像(带有一些 js 代码 - 幻灯片放映 运行现有的 JS 脚本 - 如果需要,我可以上传所有内容 | 图片也在 pi 本身上)。
我想要实现的是自动:
- 重新构建 JS 数组(使用有效的 python 脚本 - 代码如下 (arr_edit.py))。
- 将新数组复制到所需位置。 (shell 命令)
- 并使用“pkill chromium”重新启动 chromium。 (shell 命令)
现在,我不能允许每次有人 copies/deletes 多张 图像时,命令每次都会 运行 - 这意味着:
每当添加 2+ 张图像时,我都无法“重启”信息亭
(sudo pkill chromium) 每次创建一个文件。
每次您复制多个文件(在这种情况下为图像)时,对于在文件夹中创建的每个单独的 图像,都会调用一个完全独立的 event.created,因此,对于 5 张图像,将有 5 个不同的 event.created 事件会触发 on_event() 方法,每个事件都会在自己的回合中触发,从而使自助服务终端连续重启 5 次。 (现在想想如果发生 50 个文件传输会发生什么 - pi 会崩溃)
因此,我需要一种在文件传输完成后仅调用命令 1 次的方法,不管文件夹中有多少文件changed/created/deleted。
arr_edit.py(不完全是我的代码):
import os
dir_path = r'/home/pi/Desktop/jsSlider/images'
file_path = r'/home/pi/Desktop/jsSlider/scripts/imgArr.js'
directory = os.fsencode(dir_path)
arr_name = 'images=[\n'
start_str = '{"img":"./images/'
end_str = '"},\n'
images = ''
def writer(array, imagesList):
str_to_write = array + imagesList + ']'
f = open(file_path, 'w')
f.write(str_to_write)
f.close
file_list = os.listdir(directory)
for file in file_list:
filename = os.fsdecode(file)
if filename.endswith(".jpg") or filename.endswith(".jpeg") or filename.endswith(".webp") or filename.endswith(".webp"):
if file == file_list[len(file_list)-1]:
end_str = '"}\n'
images += start_str + filename + end_str
continue
else:
continue
writer(arr_name, images)
输出JS数组(来自imgArr.js内部的样本):
images=[
{"img":"./images/246.jpg"},
{"img":"./images/128.jpg"},
{"img":"./images/238.webp"},
{"img":"./images/198.jpg"},
{"img":"./images/247.webp"}
]
正如马克在评论中所建议的那样,
我添加了一个检查以查看 js 文件在过去 5 分钟内是否发生了变化。
如果文件更改,
再等 5 分钟,然后重新启动 cange(如果文件夹中添加了更多文件),这样新的、更大的文件也将显示在此 运行.
很有魅力!
非常感谢!!
这是最后的 watchdog.py
import os
import time
import psutil
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
i = 0
def show_stats():
global i
read = "read #" + str(i) + ":"
mem = "\nmemory in use: " + str(psutil.virtual_memory().percent)+"%"
cpu = "\ncpu load: " + str(psutil.cpu_percent())+"%"
temp = "\ncurrent " + \
os.popen("vcgencmd measure_temp").readline().replace(
"=", ": ").replace("'C", " C°")
end = "\n=================="
i += 1
stats = read + mem + cpu + temp + end
return stats
def wait_for_file(file):
time.sleep(300)
if age(file) >= 5:
modify()
def modify():
os.system('python /home/pi/Desktop/jsSlider/scripts/arr_edit.py')
os.system(
'cp -r /home/pi/Desktop/jsSlider/scripts/imgArr.js /home/pi/Desktop/jsSlider/themes/1')
time.sleep(1)
os.system('sudo pkill chromium')
# os.system('cls')
print("done!\nwatching...")
def age(filename):
return ((time.time() - os.path.getmtime(filename))//60)
class Watcher:
DIRECTORY_TO_WATCH = r'/home/pi/Desktop/jsSlider/images'
def __init__(self):
self.observer = Observer()
print("watching ", self.DIRECTORY_TO_WATCH, "...")
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)
print(show_stats())
except Exception as e:
self.observer.stop()
print(e)
self.observer.join()
class Handler(FileSystemEventHandler):
@ staticmethod
def on_any_event(event):
file = r'/home/pi/Desktop/jsSlider/scripts/imgArr.js'
if event.event_type == 'created' or event.event_type == 'deleted':
print("Received event - %s. " %
event.src_path, str(event.event_type))
time.sleep(5)
if age(file) < 5:
wait_for_file(file)
else:
modify()
if __name__ == '__main__':
w = Watcher()
w.run()
我正在尝试让看门狗监听文件夹更改 (adding/deleting) 个文件。
我的问题是,每次我从这个文件夹(及其子文件夹)copy-create/delete 几个文件,事件链开始一个接一个文件。
如何让 on_event()
方法在多个文件 creation/deletion 之后只被调用一次?
假设我要将两张图片复制到此文件夹。
我希望事件处理程序在文件传输完成后仅被调用一次,并且而不是两次——每个图像一次——因为它当前有效。
谢谢!
代码 运行s 在 raspberry pi 3 上 python 3.7.
代码如下:
import os
import time
import psutil
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
i = 0
def show_stats():
global i
read = "read #" + str(i) + ":"
mem = "\nmemory in use: " + str(psutil.virtual_memory().percent)+"%"
cpu = "\ncpu load: " + str(psutil.cpu_percent())+"%"
temp = "\ncurrent " + \
os.popen("vcgencmd measure_temp").readline().replace(
"=", ": ").replace("'C", " C°")
end = "\n=================="
i += 1
stats = read + mem + cpu + temp + end
return stats
class Watcher:
DIRECTORY_TO_WATCH = r'/home/pi/Desktop/jsSlider/images'
def __init__(self):
self.observer = Observer()
print("watching ", self.DIRECTORY_TO_WATCH, "...")
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)
print(show_stats())
except Exception as e:
self.observer.stop()
print(e)
self.observer.join()
class Handler(FileSystemEventHandler):
@staticmethod
def on_event(event):
wait = 1
elif event.event_type == 'created' or event.event_type == 'deleted':
print("Received event - %s. " %event.src_path, str(event.event_type))
time.sleep(wait) #i found that its best to give some timeout between commands because it overwhelmed the pi for some reason (one second seems to be enough)...
os.system('python /home/pi/Desktop/Slider/scripts/arr_edit.py') #recreate the JS array
time.sleep(wait)
os.system('cp -r /home/pi/Desktop/jsSlider/scripts/imgArr.js /home/pi/Desktop/jsSlider/themes/1') #copy the newly created JS array to its place
time.sleep(wait)
os.system('sudo pkill chromium') #"refresh" the page -the kiosk mode reactivates the process...
# os.system('cls')
print('done!')
if __name__ == '__main__':
w = Watcher()
w.run()
编辑我
有些诊所的电视连接到电视的 rpi3 性能很差,它在信息亭模式下显示本地 html 文件中的图像(带有一些 js 代码 - 幻灯片放映 运行现有的 JS 脚本 - 如果需要,我可以上传所有内容 | 图片也在 pi 本身上)。
我想要实现的是自动:
- 重新构建 JS 数组(使用有效的 python 脚本 - 代码如下 (arr_edit.py))。
- 将新数组复制到所需位置。 (shell 命令)
- 并使用“pkill chromium”重新启动 chromium。 (shell 命令)
现在,我不能允许每次有人 copies/deletes 多张 图像时,命令每次都会 运行 - 这意味着:
每当添加 2+ 张图像时,我都无法“重启”信息亭 (sudo pkill chromium) 每次创建一个文件。
每次您复制多个文件(在这种情况下为图像)时,对于在文件夹中创建的每个单独的 图像,都会调用一个完全独立的 event.created,因此,对于 5 张图像,将有 5 个不同的 event.created 事件会触发 on_event() 方法,每个事件都会在自己的回合中触发,从而使自助服务终端连续重启 5 次。 (现在想想如果发生 50 个文件传输会发生什么 - pi 会崩溃)
因此,我需要一种在文件传输完成后仅调用命令 1 次的方法,不管文件夹中有多少文件changed/created/deleted。
arr_edit.py(不完全是我的代码):
import os
dir_path = r'/home/pi/Desktop/jsSlider/images'
file_path = r'/home/pi/Desktop/jsSlider/scripts/imgArr.js'
directory = os.fsencode(dir_path)
arr_name = 'images=[\n'
start_str = '{"img":"./images/'
end_str = '"},\n'
images = ''
def writer(array, imagesList):
str_to_write = array + imagesList + ']'
f = open(file_path, 'w')
f.write(str_to_write)
f.close
file_list = os.listdir(directory)
for file in file_list:
filename = os.fsdecode(file)
if filename.endswith(".jpg") or filename.endswith(".jpeg") or filename.endswith(".webp") or filename.endswith(".webp"):
if file == file_list[len(file_list)-1]:
end_str = '"}\n'
images += start_str + filename + end_str
continue
else:
continue
writer(arr_name, images)
输出JS数组(来自imgArr.js内部的样本):
images=[
{"img":"./images/246.jpg"},
{"img":"./images/128.jpg"},
{"img":"./images/238.webp"},
{"img":"./images/198.jpg"},
{"img":"./images/247.webp"}
]
正如马克在评论中所建议的那样,
我添加了一个检查以查看 js 文件在过去 5 分钟内是否发生了变化。
如果文件更改,
再等 5 分钟,然后重新启动 cange(如果文件夹中添加了更多文件),这样新的、更大的文件也将显示在此 运行.
很有魅力!
非常感谢!!
这是最后的 watchdog.py
import os
import time
import psutil
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
i = 0
def show_stats():
global i
read = "read #" + str(i) + ":"
mem = "\nmemory in use: " + str(psutil.virtual_memory().percent)+"%"
cpu = "\ncpu load: " + str(psutil.cpu_percent())+"%"
temp = "\ncurrent " + \
os.popen("vcgencmd measure_temp").readline().replace(
"=", ": ").replace("'C", " C°")
end = "\n=================="
i += 1
stats = read + mem + cpu + temp + end
return stats
def wait_for_file(file):
time.sleep(300)
if age(file) >= 5:
modify()
def modify():
os.system('python /home/pi/Desktop/jsSlider/scripts/arr_edit.py')
os.system(
'cp -r /home/pi/Desktop/jsSlider/scripts/imgArr.js /home/pi/Desktop/jsSlider/themes/1')
time.sleep(1)
os.system('sudo pkill chromium')
# os.system('cls')
print("done!\nwatching...")
def age(filename):
return ((time.time() - os.path.getmtime(filename))//60)
class Watcher:
DIRECTORY_TO_WATCH = r'/home/pi/Desktop/jsSlider/images'
def __init__(self):
self.observer = Observer()
print("watching ", self.DIRECTORY_TO_WATCH, "...")
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)
print(show_stats())
except Exception as e:
self.observer.stop()
print(e)
self.observer.join()
class Handler(FileSystemEventHandler):
@ staticmethod
def on_any_event(event):
file = r'/home/pi/Desktop/jsSlider/scripts/imgArr.js'
if event.event_type == 'created' or event.event_type == 'deleted':
print("Received event - %s. " %
event.src_path, str(event.event_type))
time.sleep(5)
if age(file) < 5:
wait_for_file(file)
else:
modify()
if __name__ == '__main__':
w = Watcher()
w.run()