#!/int/python # # bindingftp.py # # Keith Waclena # """Send and receive files to and from BoundToPlease. """ __author__ = "Keith Waclena, k-waclena@uchicago.edu" __version__ = "0.0" __patchlevel__ = "0" __production__ = 1 import main # partially apply f to args def app(f, *args): return lambda x, f=f, args=args: apply(f, args + (x,)) class Main(main.main): """main.main subclass: set configuration parameters, define command line options, etc. """ Usage = "-s|-g" chunksize = 32 * 1024 remotegetdir = "return" remotesenddir = "send" host = "ftp.boundtoplease.com" user = "66595007" password = "chicago" localgetdir = "/projects/preservation/binding/receive" localsenddir = "/projects/preservation/binding/send" rcpts = ["gsmith@boundtoplease.com", "kblevi@boundtoplease.com", "keith@lib.uchicago.edu", "eanderso@midway.uchicago.edu",] ## host = "stone" ## user = "bnd" ## password = "Leather!" ## localgetdir = "./receive" ## localsenddir = "./send" ## rcpts = ["keith@lib.uchicago.edu"] msg = ("The following files have been uploaded to the %s directory;" % remotesenddir, "in the %s account; files with an 'r' in the name are" % user, "rush jobs.", "") subject = "Bind These" From = "University of Chicago Library Binding " try: options = [main.opt("s", doc = "send files"), main.opt("g", doc = "get files"), main.opt("v", doc = "set VERBOSITY level to 1"), ] except main.opt, o: self.dryrot("%s: %s" % (o, o.error)) def main(self): "Main routine." from ftplib import FTP try: sending, getting, self.verbose.verbosity = ( main.opts(self.options).get("s", "g", "v") ) except main.opts, o: self.usage(o.error) if sending and getting or not (sending or getting): self.usage("must specify exactly one of -s or -g") self.verbose(1, "Connecting to %s" % self.host) self.ftp = FTP(self.host, self.user, self.password) try: if sending: self.send() else: self.get() finally: self.verbose(2, "QUIT") self.ftp.quit() def get(self): """Get data from remote host.""" import os, ftplib try: os.chdir(self.localgetdir) except os.error, (_, err): self.fatal("%s (%s)" % (err, self.localgetdir)) self.verbose(2, "CWD %s" % self.remotegetdir) self.ftp.cwd(self.remotegetdir) directory = self.ftp.nlst() if len(directory) > 0: for file in directory: if file[:5] == "total": # bug in NetWare FTP server: "The server will return # a stream of names of files *and no other information*." # -- RFC 959 [emphasis mine] # the server always returns the string "total 0" continue if file in (".", ".."): continue self.verbose(1, "Retrieving %s" % file) try: self.currentfile = open(file, "w") os.chmod(file, 0664) try: self.ftp.retrbinary("RETR %s" % file, self.snarf, self.chunksize) finally: self.currentfile.close() except IOError, (_, err): self.warning("%s (%s)" % (err, file)) except ftplib.all_errors, err: self.warning("%s (%s)" % (err, file)) else: self.warning("no files to retrieve") def send(self): """Send data to remote host.""" import os, ftplib, mailer from string import join try: os.chdir(self.localsenddir) except os.error, (_, err): self.fatal("%s (%s)" % (err, self.localsenddir)) self.verbose(2, "CWD %s" % self.remotegetdir) self.ftp.cwd(self.remotesenddir) directory = os.listdir(".") if len(directory) > 0: files = [] for file in directory: self.verbose(1, "Sending %s" % file) try: fp = open(file) try: self.ftp.storbinary("STOR %s" % file, fp, self.chunksize) finally: fp.close() except IOError, (_, err): self.warning("%s (%s)" % (err, file)) except ftplib.all_errors, err: self.warning("%s (%s)" % (err, file)) else: self.verbose(1, "Deleting %s" % file) os.unlink(file) files.append(file) if files: self.verbose(1, "sending mail to %s" % join(self.rcpts, ", ")) fp = mailer.sendmail(join(self.rcpts, ", "), subject = self.subject, From = self.From) fp.write("%s\n %s\n" % (join(self.msg, "\n"), join(files, "\n "))) fp.close() else: self.warning("no files to send") def snarf(self, data): """Callback for ftp object's retrbinary method.""" self.currentfile.write(data) Main(production = __production__)() # Local Variables: # py-indent-offset: 4 # fill-column: 76 # End: