Python Code Notes

Information by python engineer

【watchdog】フォルダ・ファイルを監視する方法【Python】

f:id:vigilantPotato:20210716011130p:plain
watchdogモジュールを使用することで、特定フォルダ内のファイル・フォルダの状態を監視し、状態に合わせた処理を設定することができる。以下、watchdogの基本的な使い方と応用例をまとめた。


【スポンサーリンク】


ファイル・フォルダの更新をコンソールに表示

公式ドキュメントで示されている簡単な使用例を示す。

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler

if __name__ == "__main__":
    #ロギングの設定
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    path = sys.argv[1] if len(sys.argv) > 1 else '.'    #監視対象のpathを設定
    event_handler = LoggingEventHandler()   #イベントハンドラ生成
    observer = Observer()       #監視オブジェクト生成
    observer.schedule(          #監視設定
        event_handler,
        path,
        recursive=True
        )
    observer.start()            #監視開始
    try:
        while True:             #ctrl-Cが押されるまで実行
            time.sleep(1)       #1秒停止
    except KeyboardInterrupt:   #ctrl-C実行時
        observer.stop()         #監視修了
    observer.join()

実行するとカレントディレクトの監視を行い、ファイル・フォルダが生成・更新・削除されるとコンソールにその内容がリアルタイムで表示される。ctrl-Cを押すと監視を終了する。

2021-07-16 00:07:49 - Created directory: .\新しいフォルダー
2021-07-16 00:07:56 - Created directory: .\新しいフォルダー (2)
2021-07-16 00:07:59 - Deleted file: .\新しいフォルダー (2)
2021-07-16 00:08:43 - Modified file: .\watchdog.html

[↑ 目次へ]


【スポンサーリンク】


イベントハンドラを上書きして動作を変更

イベントハンドラオブジェクトを上書きすることで、イベント発生時の動作を変更することができる。以下、イベントハンドラオブジェクトを上書きして、ファイル・フォルダ生成時と削除時の動作を変更する例を示す。

import time
import sys
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler


#LoggingEvenHandlerを上書きして動作を変更
class LoggingEventHandler2(LoggingEventHandler):
    def on_created(self, event):    
        print("生成されました。" + event.src_path)

    def on_deleted(self, event):
        print("削除されました" + event.src_path)

if __name__ == "__main__":
    path = sys.argv[1] if len(sys.argv) > 1 else '.'
    event_handler = LoggingEventHandler2()
    observer = Observer()       #監視オブジェクト生成
    observer.schedule(          #監視設定
        event_handler,
        path,
        recursive=True
        )
    observer.start()            #監視開始
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
        observer.join()

ファイル・フォルダが生成されたときに実行されるon_createdメソッドと、削除されたときに実行されるon_deletedメソッドを上書きして、コンソールに表示する内容を変更している。

削除されました.\新しいフォルダー
生成されました。.\新しいフォルダー

以下、イベントハンドラのメソッドと、それが実行される条件の一覧を示す。イベントに合わせて処理を設定することができる。

  • on_any_event イベント発生
  • on_created フォルダ・ファイル生成
  • on_deleted フォルダ・ファイル削除
  • on_modified フォルダ・ファイル更新
  • on_moved フォルダ・ファイルを移動・リネーム

[↑ 目次へ]


【スポンサーリンク】


tkinterで監視のON/OFFを切り替え

応用例として、tkinterで監視のON/OFFを切り替えと結果を表示する例を示す。

import os
import sys
import tkinter
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler

global var_text #フォルダ・ファイル名格納用変数

class LoggingEventHandler2(LoggingEventHandler):
    """
    イベント監視クラス
    """
    def on_created(self, event):    #イベント発生時に実行
        var_text.set(os.path.basename(event.src_path))


class CheckLogg(tkinter.Checkbutton):
    """
    フォルダ監視ON/OFF切替チェックボタン
    """
    def __init__(self, root):
        self.var = tkinter.BooleanVar(root, value=False)

        super().__init__(
            root,
            text="監視 ON/OFF",
            variable=self.var,
            command=self.switch_logging,    #クリック時に実行する関数
            )
        self.pack() #チェックボタン表示

        self.event_handler=LoggingEventHandler2()   #イベントハンドラオブジェクト生成
        self.path = sys.argv[1] if len(sys.argv) > 1 else '.'


    def switch_logging(self):           #クリック時に実行
        if self.var.get():  #ONの場合
            self.observer = Observer()  #Observerオブジェクト生成
            self.observer.schedule(     #スレッド作成
                self.event_handler,
                self.path,
                recursive=True
                )
            self.observer.start()       #スレッド開始
        else:               #OFFの場合
            self.observer.stop()        #スレッド停止
            self.observer.join()        #スレッド完了まで待機


class ShowFilename(tkinter.Label):
    """
    フォルダ・ファイル名表示用ラベル
    """
    def __init__(self, root):
        super().__init__(
            root,
            width=15,
            relief="ridge",
            textvariable=var_text,
            )
        self.pack() #ラベル表示


if __name__ == "__main__":
    root = tkinter.Tk()

    var_text = tkinter.StringVar(root)  #フォルダ・ファイル名格納用変数
    c = CheckLogg(root)                 #チェックボタン生成
    s = ShowFilename(root)              #ラベル生成
    
    root.mainloop()

実行するとチェックボックスとラベルが表示され、チェックボックスで監視のON/OFFを切り替えることができる。フォルダ・ファイルの新規作成を監視し、結果をラベルに表示させる。

f:id:vigilantPotato:20210716011230p:plain
f:id:vigilantPotato:20210716011240p:plain

【スポンサーリンク】