【问题标题】:Python Watchdog error when files are downloaded from FTP从 FTP 下载文件时出现 Python Watchdog 错误
【发布时间】:2014-07-16 16:13:49
【问题描述】:

我正在使用 Watchdog 来监视目录中是否有新的 .xml 文件在某个时间间隔内通过 ftplib 下载。当Watchdog看到文件时,on_created()会触发一个函数来处理/解析xml,但是文件下载似乎还没有完成,导致后续函数出现丢失数据的错误。

我在调用函数之前添加了一个 time.sleep(1) 来缓解错误,但在现实世界中添加延迟似乎是一种不可靠的方法。我想知道是否有一种类似于 promise 函数的方法我可以使用而不是延迟。或者也许我完全误诊了这个问题并且有一个简单的答案?接受任何建议。

仅供参考...文件大小可能从大约 100K 到 4-5mg 不等。

FTP功能

def download(f):
    ftpt = ftplib.FTP(server)
    ftpt.login(username, password)
    ftpt.cwd(ftp_dir)
    print 'Connected to FTP directory'
    if f.startswith('TLC-EMAILUPDATE'):
        if os.path.exists(dl_dir + f) == 0:
            fhandle = open(os.path.join(dl_dir, f), 'wb')
            print 'Getting ' + f
            ftpt.retrbinary('RETR ' + f, fhandle.write)
            fhandle.close()
        elif os.path.exists(dl_dir + f) == 1:
            print 'File', f, 'Already Exists, Skipping Download'


ftp = ftplib.FTP(server)
ftp.login(username, password)
ftp.cwd(ftp_dir)
infiles = ftp.nlst()

pool = Pool(4)
pool.map(download, in files)

看门狗

def on_created(self, event):
    self.processfile(event)
    base = os.path.basename(event.src_path)
    if base.startswith('TLC-EMAILUPDATE'):
        print 'File for load report has been flagged'
        xmldoc = event.src_path
        if os.path.isfile(xmldoc) == 1:
            print 'File download complete'
            send_email(xmldoc)

发送邮件(带睡眠)

content变量抛出异常,解析无法从下载的文件中读取任何数据。

def send_email(xmldoc):
    time.sleep(2)
    content = str(parse_xml.create_template(xmldoc))
    msg = MIMEText(content, TEXT_SUBTYPE)
    msg['Subject'] = EMAIL_SUBJECT
    msg['From'] = EMAIL_SENDER
    msg['To'] = listToStr(EMAIL_RECEIVERS)

    try:
        smtpObj = SMTP(GMAIL_SMTP, GMAIL_SMTP_PORT)
        smtpObj.ehlo()
        smtpObj.starttls()
        smtpObj.ehlo()
        smtpObj.login(user=EMAIL_SENDER, password=EMAIL_PASS)
        smtpObj.sendmail(EMAIL_SENDER, EMAIL_RECEIVERS, msg.as_string())
        smtpObj.quit()
        print 'Email has been sent to %s' % EMAIL_RECEIVERS
    except SMTPException as error:
        print 'Error: unable to send email : {err}'.format(err=error)

【问题讨论】:

    标签: python io ftp subprocess python-watchdog


    【解决方案1】:

    简单的答案:切换到监控CLOSE_WRITE 事件。唉Watchdog 不直接支持它。要么:

    1) 切换到pyinotify 并使用以下代码——仅限 Linux,而不是 OSX

    2) 将 Watchdog 与 on_any_event() 一起使用

    pyinotify 示例源码

    import os, sys
    
    import pyinotify
    
    class VideoComplete(pyinotify.ProcessEvent):
        def process_IN_CLOSE_WRITE(self, event):
            sys.stdout.write(
                'video complete: {}\n'.format(event.pathname)
            )
            sys.stdout.flush()
    
    def main():
        wm = pyinotify.WatchManager()
        notifier = pyinotify.Notifier(
            wm, default_proc_fun=VideoComplete(),
            )
        mask = pyinotify.ALL_EVENTS
        path = os.path.expanduser('~/Downloads/incoming')
        wm.add_watch(path, mask, rec=True, auto_add=True)
        notifier.loop()
    
    if __name__=='__main__':
        main()
    

    下载文件

    echo beer > ~/Downloads/incoming/beer.txt
    

    输出

    video complete: /home/johnm/Downloads/incoming/beer.txt
    

    【讨论】:

    • 谢谢! Pyinotify 和 OSX 不会在沙盒中一起玩。将加载到一个 linux 机器上,我会让你知道会发生什么。
    • @jp_inc:哦,对不起。是的,让我知道你发现了什么!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    相关资源
    最近更新 更多