如何只处理一次脚本

问题描述 投票:0回答:1

我的代码可以工作,但我希望 podman 命令在 file_queue 为空时唯一运行。但它在复制到 /ARRIVAGE_TEST/ 的数据结束之前开始,并且无限期地运行。添加到 ARRIVAGE_TEST 后,另一个脚本 test_gilles_conf.py 将文件复制/粘贴到另一个目录。

import os
import time
from pathlib import Path
from inotify.adapters import Inotify
import subprocess
from collections import deque
from threading import Lock, Thread

WATCH_DIR = Path('/***/ARRIVAGE_TEST')
SCRIPT_PATH = Path('/***/test_gilles_conf.py')

file_queue = deque()
queue_lock = Lock()
last_event_time = {"time": time.time()}
photoprism_process = None

def handle_event(event):
    (header, type_names, watch_path, name) = event

    if 'IN_CLOSE_WRITE' in type_names:
        filepath = Path(watch_path) / name
        with queue_lock:
            file_queue.append(str(filepath))
        return time.time()
    return None

def process_files():
    global photoprism_process
    podman_command_running = False  # Flag to track if the Podman command is already running
    while True:
        with queue_lock:
            if file_queue and time.time() - last_event_time["time"] > 5:
                if photoprism_process is None or photoprism_process.poll() is not None:
                    filepath = file_queue.popleft()
                    try:
                        env = os.environ.copy()
                        env["LAST_FILE_PATH"] = filepath
                        subprocess.run(["python3", str(SCRIPT_PATH)], env=env)
                    except Exception as e:
                        print(f"Error running script: {e}")
            else:
                if not file_queue and time.time() - last_event_time["time"] > 5 and not podman_command_running:
                    podman_command_running = True  # Set the flag to indicate that the Podman command is running
                    try:
                        photoprism_process = subprocess.run(["sudo", "podman", "exec", "photoprism-app", "photoprism", "index"])
                    except Exception as e:
                        print(f"Error running Podman command: {e}")
                    finally:
                        podman_command_running = False  # Reset the flag after the command completes
                time.sleep(1)  # Wait for 1 second before checking again

def watch_directory(directory):
    i = Inotify()
    i.add_watch(str(directory))
    print("Starting file watch...")
    processing_thread = Thread(target=process_files, daemon=True)
    processing_thread.start()
    try:
        for event in i.event_gen():
            if event is not None:
                event_time = handle_event(event)
                if event_time is not None:
                    last_event_time["time"] = event_time
    finally:
        i.remove_watch(str(directory))
        processing_thread.join()  # wait for the processing thread to finish
        
if __name__ == "__main__":
    watch_directory(WATCH_DIR)

这是一个脚本,用于在将文件接收到 ARRIVAGE_TEST 后监视并执行另一个脚本。我希望 podman 命令在处理所有文件后启动,但它不像我期望的那样工作。你能帮我吗?

我试试这个:

else:
                if not file_queue and time.time() - last_event_time["time"] > 5 and not podman_command_running:
                    podman_command_running = True  # Set the flag to indicate that the Podman command is running
                    try:
                        photoprism_process = subprocess.run(["sudo", "podman", "exec", "photoprism-app", "photoprism", "index"])
                    except Exception as e:
                        print(f"Error running Podman command: {e}")
                    finally:
                        podman_command_running = False  # Reset the flag after the command completes
                time.sleep(1)  # Wait for 1 second before checking again

但是当 podman 命令完成时,它总是会重新启动它。

python events watch deque inotify
1个回答
0
投票

我已经解决了这个问题。但我还有另一个问题:如果文件 1、2、3 被复制到 /ARRIVAGE_TEST/,则脚本尚未执行。它在写入完成后处理它们。但是,如果文件 4,5,6 与 /ARRIVAGE_TEST/ 并行复制(文件 1,2,3 尚未完成复制),它仍然运行 podman 命令,但我希望仅在所有文件已由其他脚本 (test_gilles_conf.py) 处理。

import os
import time
from pathlib import Path
from inotify.adapters import Inotify
import subprocess
from collections import deque
from threading import Lock, Thread

WATCH_DIR = Path('/**/ARRIVAGE_TEST')
SCRIPT_PATH = Path('/**/test_gilles_conf.py')

file_queue = deque()
queue_lock = Lock()
last_event_time = time.time()
podman_command_running = True  # Initialize the variable before the while loop
def handle_event(event):
    global last_event_time
    (header, type_names, watch_path, name) = event

    if 'IN_CLOSE_WRITE' in type_names:
        filepath = Path(watch_path) / name
        with queue_lock:
            file_queue.append(str(filepath))
        last_event_time = time.time()

def process_files():
    global podman_command_running
    while True:
        with queue_lock:
            if len(file_queue) > 0 and time.time() - last_event_time > 5:
                filepath = file_queue.popleft()
                try:
                    env = os.environ.copy()
                    env["LAST_FILE_PATH"] = filepath
                    subprocess.run(["python3", SCRIPT_PATH], env=env)
                    podman_command_running = False
                except Exception as e:
                    print(f"Error running script: {e}")
            else:
                if len(file_queue) == 0 and time.time() - last_event_time > 5 and podman_command_running == False:
                    podman_command_running = True  # Set the flag to indicate that the Podman command is running
                    try:
                        photoprism_process = subprocess.run(["sudo", "podman", "exec", "photoprism-app", "photoprism", "index"])
                        photoprism_process = None
                    except Exception as e:
                        print(f"Error running Podman command: {e}")
        time.sleep(1)  # Wait for 1 second before checking again
def watch_directory(directory):
    i = Inotify()
    i.add_watch(str(directory))
    print("Starting file watch...")
    processing_thread = Thread(target=process_files, daemon=True)
    processing_thread.start()
    try:
        for event in i.event_gen():
            if event is not None:
                handle_event(event)
    finally:
        i.remove_watch(str(directory))

if __name__ == "__main__":
    watch_directory(WATCH_DIR)
© www.soinside.com 2019 - 2024. All rights reserved.