Dectecting dir changes

Jean-Paul Calderone exarkun at divmod.com
Fri Dec 9 18:43:38 CET 2005


On Fri, 09 Dec 2005 16:50:05 +0000, Steve Holden <steve at holdenweb.com> wrote:
>chuck wrote:
>> I need to write a daemon for Solaris that monitors a directory for
>> incoming FTP transfers.  Under certain conditions, when the transfer is
>> complete I need to send an email notification, and do other stuff.
>> Win32 provides FindFirstChangeNotification(), but as best I can tell
>> this isn't supported on Solaris.
>>
>[...]
>>
>> Suggestions?
>>
>Write an FTP server in Python, then it will know exactly when each file
>transfer is complete, and it can do the mailing itself!

Or use an existing Python FTP server! ;)

Untested:

  from zope.interface import implements
  from twisted.protocols import ftp

  class UploadNotifyingAvatar(ftp.FTPShell):
      def uploadCompleted(self, path):
          """
          Override me!
          """
          # But, for example:
          from twisted.mail import smtp
          smtp.sendmail(
              '127.0.0.1',
              'ftp_server at localhost',
              ['ftp_admin at localhost'],
              'Hey!  Someone uploaded a file: %r' % (path,))

      def openForWriting(self, path):
          writer = ftp.FTPShell.openForWriting(path)
          return CloseNotifyingWriter(
              writer,
              lambda: self.uploadCompleted(path))
          
  class CloseNotifyingWriter(object):
      implements(ftp.IWriteFile)

      def __init__(self, wrappedWriter, onUploadCompletion):
          self.wrappedWriter = wrappedWriter
          self.onUploadCompletion = onUploadCompletion

      def receive(self):
          receiver = self.wrappedWriter.receive()
          receiver.addCallback(
              CloseNotifyingReceiver,
              self.onUploadCompletion)
          return receiver

  class CloseNotifyingReceiver(object):
      def __init__(self, wrappedReceiver, onUploadCompletion):
          self.wrappedReceiver = wrappedReceiver
          self.onUploadCompletion = onUploadCompletion

      def registerProducer(self, producer, streaming):
          return self.wrappedReceiver.registerProducer(producer, streaming)

      def unregisterProducer(self):
          # Upload's done!
          result = self.wrappedReceiver.unregisterProducer()
          self.onUploadCompletion()
          return result

      def write(self, bytes):
          return self.wrappedReceiver.write(bytes)

Hook it up to a Realm and a Portal and override uploadCompleted to taste and you've got an FTP server that should do you (granted, it's a little long - some of this code could be be factored to take advantage of parameterizable factories to remove a bunch of the boilerplate).

Jean-Paul



More information about the Python-list mailing list