# This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # Copyright 2005 Dan Williams and Red Hat, Inc. import threading import urllib import string import os import socket import URLopener import OpenSSL import CommonErrors import exceptions import FileTransfer class FileUploader(FileTransfer.FileTransfer): def __init__(self, url, files, filevar, cgi_vars=None, certs=None): FileTransfer.FileTransfer.__init__(self, certs) self._files = {} self._url = url if files and type(files) == type(""): files = [files] if not files or type(files) is not type([]): raise ValueError("Require a list of files to upload.") for fpath in files: self._files[os.path.abspath(fpath)] = (None, None) self._filevar = filevar if cgi_vars: if type(cgi_vars) is not type([]): raise ValueError("cgi_vars must be a list of tuples") for var in cgi_vars: if type(var) is not type(()): raise ValueError("cgi_vars must be a list of tuples") self._cgi_vars = cgi_vars def _action(self, cgivars=None): result = None err_msg = None try: result = self._opener.open(self._url, cgivars) except socket.error, exc: if not CommonErrors.canIgnoreSocketError(exc): err_msg = "Socket Error: %s" % exc except IOError, exc: if not CommonErrors.canIgnoreSocketError(exc): err_msg = "IOError Error: %s" % exc return (result, err_msg) def run(self): final_result = FileTransfer.FT_RESULT_SUCCESS msg = None for fpath in self._files.keys(): fd = open(fpath, "r") cgivars = [(self._filevar, fd)] cgivars = cgivars + self._cgi_vars (result, msg) = self._process_one_transfer(cgivars) fd.close() self._files[fpath] = (result, msg) if result == FileTransfer.FT_RESULT_FAILED: final_result = FileTransfer.FT_RESULT_FAILED msg = "Upload of %s failed because: %s" % (fpath, msg) break if self._cancel: final_result = FileTransfer.FT_RESULT_CANCELED break if self._callback: self._callback(final_result, self._cb_data, msg) ########################################################### # Testing stuff ########################################################### import sys, time class UlCallbackData: def __init__(self, x, t): self.num = x self.tracker = t self.dl = None def set_dl(self, dl): self.dl = dl class UlTracker: def __init__(self): self.lst = [] def add(self, ulcbdata): self.lst.append(ulcbdata) def remove(self, ulcbdata): self.lst.remove(ulcbdata) def num(self): return len(self.lst) def UploadCallback(status, ulcbdata, msg=""): print "Finished with %d (%s: %s)" % (ulcbdata.num, status, msg) ulcbdata.tracker.remove(ulcbdata) if __name__ == '__main__': if len(sys.argv) < 5: print "Usage: python FileUploader.py key_and_cert ca_cert peer_ca_cert fname1 fname2 ..." sys.exit(1) certs = {} certs['key_and_cert'] = sys.argv[1] certs['ca_cert'] = sys.argv[2] certs['peer_ca_cert'] = sys.argv[3] print "Starting..." dlt = UlTracker() x = 0 files = [] for fname in sys.argv[4:]: files.append(os.path.abspath(fname)) while x < 100: wr = UlCallbackData(x, dlt) try: time.sleep(0.25) except KeyboardInterrupt: break data = [] data.append(('jobid', x)) data.append(('arch', 'i386')) ful = FileUploader("https://localhost:8886/upload", files, 'filedata', data, certs) ful.set_callback(UploadCallback, wr) dlt.add(wr) ful.start() x = x + 1 while dlt.num() > 0: try: time.sleep(1) except KeyboardInterrupt: print "Quitting..." os._exit(0)