クラウドのシステム向けに 社内データを送信する運用環境が整っています。
.txtでのファイルを送信し終えると、.csvのファイルが 同フォルダに提供されます。
この送信データであるTEXTファイルと処理結果のCSVファイルの自動退避、及び処理結果であるCSVファイルをメール送信しようと考え、経験浅いながらPythonで以下を作ってみました。(ネット記事切貼りとこちらでの支援により)
送信すべきTEXTファイルを、このプログラムで監視しようとするフォルダに配置した上、送信処理手前で起動しています。
つまりは監視下にあるフォルダに CSVファイルの新規発生が メール送信・退避移動の発火にした作りです。
python
1from watchdog.events import FileSystemEventHandler 2from watchdog.observers import Observer 3import os 4import time 5 6from email.mime.text import MIMEText 7from email.mime.application import MIMEApplication 8from email.mime.multipart import MIMEMultipart 9from email.mime.base import MIMEBase 10from email.header import Header 11from email import policy 12from email import encoders 13from os.path import basename 14from email.utils import formatdate 15import os 16import sys 17import smtplib 18 19import datetime 20import shutil 21 22arges = sys.argv 23argcnt = len(arges) -1 #0番目のコマンドライン引数は当該プログラムのパスになるため 24 25class Email(): 26 def __init__(self): 27 28 self.mlsrv = "" 29 self.mlsrv_port = 587 30 self.mlsrv_id = "" 31 self.mlsrv_pw = "" 32 self.mlsrv_fraddress = "@.com" 33 34 35 def send_Mail(self, toaddress, ccaddress, bccaddress, subject, filepath): 36 try: 37 38 #メール送信の処理 割愛 39 40 except Exception as e: 41 42 43 finally: 44 return result 45 46 47 48class BackUp(): 49############################################################################################### 50# 送信処理が終わると、処理結果がCSVで 同フォルダに提供される⇒⇒⇒メール送信後に送信データと併せ退避 51 52 # 監視フォルダと 退避先フォルダが引数 53 def move_files(self, src_dir, dst_dir): 54 55 dt_now = datetime.datetime.now() 56 dst_dir = dst_dir + "/" + dt_now.strftime('%Y%m%d%H%M%S') 57 os.makedirs(dst_dir, exist_ok=True) #指定の退避先フォルダ内に日付時間フォルダを作成 58 59 for p in os.listdir(src_dir): #監視フォルダ内コレクションループ 60 fullpath = os.path.join(src_dir, p) #ファイルのフルパスを取得 61 62 wcnt = 0 #この関数動作由来の新規ファイルはサイズ0の可能性あり-->待機 63 while True: 64 size = os.path.getsize(fullpath) 65 if size == 0 : 66 wcnt += 1 67 if wcnt > 1800 : #無限ループ対策(30) 68 break 69 time.sleep(3) 70 else : 71 break 72 73 base, ext = os.path.splitext(p) 74 if ext == ".csv" : #サイズ1以上CSVファイルは処理結果内容-->メールで添付送信 75 if argcnt < 5 : 76 if argcnt == 4 : 77 result = mail.send_Mail(引数の数から宛先のみの指定) 78 elif argcnt == 3 : 79 result = mail.send_Mail(引数の数から宛先・CCのみの指定) 80 else : 81 result = mail.send_Mail(引数の数から宛先・CC・BCC全てを指定) 82 83 wcnt = 0 84 while True: 85 wcnt += 1 86 if wcnt > 1800 : #無限ループ対策(30) 87 break 88 try : 89 shutil.move(os.path.join(src_dir, p), dst_dir)#★移動できれば使用中でないと判断★ 90 break 91 except Exception as e: 92 time.sleep(1) #★移動できなければ送信中と判断、また移動をリトライ★ 93 94 95#★★★監視フォルダ内全てのファイルが移動退避し終えたら 関数を終わらせてアプリも閉じたい★★★ 96 97''' 98###################################################################################################### 99# # 100# # 101# # 102###################################################################################################### 103''' 104class ChangeHandler(FileSystemEventHandler): 105 def __init__(self, observer): 106 self.observer = observer 107 108 def on_created(self, event): 109 110 if argcnt < 5 : 111 if argcnt == 4 : 112 backup.move_files(arges[3], arges[4]) 113 elif argcnt == 3 : 114 backup.move_files(arges[2], arges[3]) 115 else : 116 backup.move_files(arges[4], arges[5]) 117 118 119 self.observer.unschedule_all()#★★ 監視フォルダに送信ファイル残ることがある。でも退避もされている! 120 self.observer.stop() #★★ しかも終わってくれない(新たな監視状況がつくりだされているような感じ) 121 122 123 124if __name__ in '__main__': 125 mail = Email() 126 backup = BackUp() 127 128 if argcnt < 5 : 129 if argcnt == 4 : 130 target_dir = arges[3] 131 elif argcnt == 3 : 132 target_dir = arges[2] 133 elif argcnt <= 2 : 134 print("引数不足、起動できません") 135 sys.exit(9) 136 else : 137 target_dir = arges[4] 138 139 140 observer = Observer() 141 event_handler = ChangeHandler(observer) 142 observer.schedule(event_handler, target_dir, recursive=True)#特定のフォルダを引数に与えて監視スタート 143 observer.start() 144 try: 145 while observer.is_alive(): 146 time.sleep(0.1) 147 except KeyboardInterrupt: 148 observer.unschedule_all() 149 observer.stop() 150 observer.join() 151
質問
元フォルダにファイルが残ってしまっている状況が発生しています。データの種類によって、元フォルダがクリアされている・されていないの違いがあるようです。
しかし 退避先フォルダには 元フォルダへ残ってしまったファイルも必ず配置されていることが確認できています。
本来メール報告とファイル退避を終えたら 【当該アプリケーション自体】を終わらせることを望んでいますが、先の問題が生じるパターンでは いつになっても終わらない問題も生じています。---->新たな監視状況が作られてしまっているような感じ?! でしょうか.....
これは 上記のコードで 一体何が悪く このような問題が起きてしまっているのでしょうか? どなたかご教示を頂けますと幸いです、よろしくお願い申し上げます。
追記20210307 10:10
ベンダ様から提供されているデータ送信処理のバットファイルに、自分のアプリが前もって起動されるよう挿入したのですが
データ種類の違いで データ送信処理の実装方法が異なるようです。このことから監視フォルダに生成されるCSVファイルの生成・使用タイミング(共有状況)に違いを生んでいる可能性があります。以下バットファイルの【違い】を表しました。
フリーの監視ソフトによって 送信すべきデータファイルが所定フォルダに配置されると 以下のバットファイルが動作するようになっていますが、これが再度実施されていて 自分のアプリケーションも再起動されている可能性があります....(でもフリーの監視ソフトにその記録が残っていない)
【問題ないパターン↓】
bat
1@ECHO OFF 2rem ######################################################### 3rem # 4rem ######################################################### 5 6START D:\今回作ったプログラム 引数1, 引数2, 引数3 7 8rem 送信処理、本来このコマンド行のみのバットファイルだが上記START文を追加 9 10UPSERT.bat "ITEMMASTER_upsert" 11``` 12 13【問題あるパターン↓】 14```bat 15@ECHO OFF 16rem ######################################################### 17rem # 18rem ######################################################### 19 20START D:\今回作ったプログラム 引数1, 引数2, 引数3 21 22rem 送信処理、本来このコマンド行のみのバットファイルだが上記START文を追加 23DELETE_INSERT.bat "STOCKS_export" "STOCKS_delete" "STOCKS_insert"
追加報告 20200307 11:40
送信データが移動元フォルダに残ってしまう事象につき、また当該アプリケーションが動作し続けることから以下を試行
①フリーソフトの当該バットファイルの実装設定(検知設定)を前回実行から3分過ぎない限り再実施無理なよう対応。
=> 効果なし、フリーソフトのログに当初から2重実行されている記録は残っていないので納得の結果
②自アプリケーション内で 新規ファイル察知(1バイト以上)後の メール・退避動作までの待機時間3分を挿入。
=>効果なし、相変わらず移動元フォルダに送信データ残るが 退避先フォルダには処理結果CSVと共に保管されている。
一体何が起きているのだと思い、移動元フォルダに残ったファイルを コマンドプロンプトから削除を試行
アクセスが拒否されました、と言われながら 移動はできた....状況ですね。
ベンダ様提供のプログラムが C#やVB.NETでいうUsingみたいなものを使っていない、というこでしょうか?
何か 当方のPython側で どうにか対策できないでしょうか
20210307 14:35 qnoirさん提供プログラム、デバッグ実行の結果
20210305 15:35 qnoirさん提供プログラム実行結果
【1回目↓】
log
12021-03-07 15:21:11,822 | Started to observe. [path : .\20210307_152111_6038_log.txt] 22021-03-07 15:21:35,150 | on_created() : C:\Tools\SalesforceConnect\data\SFA09\Reservation_insert_error.csv 32021-03-07 15:21:38,384 | on_modified(): C:\Tools\SalesforceConnect\data\SFA09\Reservation_insert_error.csv 42021-03-07 15:21:46,792 | on_modified(): C:\Tools\SalesforceConnect\data\SFA09\Reservation_insert_error.csv
【2回目↓】
log
12021-03-07 15:25:08,158 | Started to observe. [path : .\20210307_152508_5250_log.txt] 22021-03-07 15:25:34,611 | on_created() : C:\Tools\SalesforceConnect\data\SFA09\Reservation_insert_error.csv 32021-03-07 15:25:38,299 | on_modified(): C:\Tools\SalesforceConnect\data\SFA09\Reservation_insert_error.csv 42021-03-07 15:25:49,393 | on_modified(): C:\Tools\SalesforceConnect\data\SFA09\Reservation_insert_error.csv
回答1件
あなたの回答
tips
プレビュー