def do_mass_payment(self, paymentList): assert len(paymentList) if self._apiMode == 'sandbox': self.API_ENDPOINT = self.PAYPAL_PAY_URL_SANDBOX elif self._apiMode == 'live': self.API_ENDPOINT = self.PAYPAL_PAY_URL_LIVE params = { 'METHOD': 'MassPay', 'CURRENCYCODE': 'USD', 'VERSION': '51.0', 'USER': self._user, 'PWD': self._password, 'SIGNATURE': self._signature } paymentCount = 0 for payment in paymentList: params['L_AMT%s' % (paymentCount)] = payment['amount'] params['L_EMAIL%s' % (paymentCount)] = payment['email'] req = urllib2.Request(self.API_ENDPOINT) params = utils.friendlyURLEncode(params) responseData = urllib2.urlopen(req, params) import cgi return cgi.parse_qs(responseData.read())
def makeHTTPRequestToURLExtended( requestURL, timeout=5, method="GET", postData=None, headers=None, cookies=None, followRedirect=True, maxRetries=0, timeoutBetweenRetries=0, ): """I make a HTTP GET request to the given URL. @param requestURL: The URL to send the request to @param timeout: The connect timeout (by default, 5 seconds). Set to 0 for no timeout. This is NOT the timeout between retries @param method: 'GET' or 'POST', defaults to 'GET'. If 'POST' is specified, postData must be set @param postData: The data that is sent in a POST request. Only valid if method is set to 'POST'. If specified, this can either be a string or unicode object (in which case it is sent as-is after being encoded to utf-8), or a dict, in which case it is URLEncoded into a utf-8 string and sent. @param headers: Any extra/overridden data for the request's HTTP headers. This must be a dictionary, or None. All entries in this dictionary should be strings, NOT unicode. @param cookies: Any cookies to be used with the request. This must be a dictionary, or None. @followRedirect: True by default to follow any redirects. Set to False to not follow. @maxRetries: The max # of retries (which we get failures with) before giving up @timeoutBetweenRetries: How long (in seconds) we wait before retries. This is in addition to our connect timeout, to the extent that it applies. @return: A deferred which will yield a dict in the form of {'success': <bool>, 'data': <responseBody>|<failureObject>} @type return: String """ def getPage(url, contextFactory=None, *args, **kwargs): """Download a web page as a string. Download a page. Return a deferred, which will callback with a page (as a string) or errback with a description of the error. See HTTPClientFactory to see what extra args can be passed. @note: This function taken from Twisted source code (twisted/web/client.py) and modified so that it wouldn't be noisy. Twisted source code is BSD licensed. """ scheme, host, port, path = http_client._parse(url) factory = http_client.HTTPClientFactory(url, *args, **kwargs) # CASTDOT-CUSTOM: make it so this function is not noisy factory.noisy = False if scheme == "https": from twisted.internet import ssl if contextFactory is None: contextFactory = ssl.ClientContextFactory() reactor.connectSSL(host, port, factory, contextFactory) # IGNORE:E1101 else: reactor.connectTCP(host, port, factory) # IGNORE:E1101 return factory.deferred def finished(responseText): log.msg( 'HTTP Request to "%s" (timeout=%s) finished: response: "%s"' % (requestURL, timeout, utils.truncate(responseText, 180)), lvl="d", ss="ss_webreq", ) return {"success": True, "data": responseText} def failed(reason, counter=1): log.msg(reason.value["response"]) if counter <= maxRetries: # try again... log.msg( 'Retrying HTTP request to "%s" (timeout=%s, retryTimeout=%s) (retry %i of %i). Failure reason: %s' % (requestURL, timeout, timeoutBetweenRetries, counter, maxRetries, reason), lvl="d2", ss="ss_webreq", ) if timeoutBetweenRetries: d = deferredWait(None, timeoutBetweenRetries) else: d = defer.succeed(True) d.addCallback( lambda result: getPage( requestURL, timeout=timeout, method=method, postdata=postData, headers=headers, cookies=cookies, followRedirect=int(followRedirect), ) ) d.addCallback(finished) d.addErrback(failed, counter=(counter + 1)) return d # no retries or retries exhausted log.msg( 'HTTP Request HTTP request to "%s" (timeout=%s) failed after %i retries: reason: %s' % (requestURL, timeout, maxRetries, reason), lvl="d", ss="ss_webreq", ) return {"success": False, "data": reason} # failure assert requestURL and isinstance(requestURL, (unicode, str)) assert isinstance(timeout, (int, long)) and timeout >= 0 assert method in ("GET", "POST") assert postData is None or (isinstance(postData, (basestring, dict)) and method == "POST") assert headers is None or isinstance(headers, dict) assert cookies is None or isinstance(cookies, dict) assert isinstance(followRedirect, bool) assert isinstance(maxRetries, (int, long)) and maxRetries >= 0 assert isinstance(timeoutBetweenRetries, (int, long)) and timeoutBetweenRetries >= 0 if isinstance(requestURL, unicode): try: requestURL = str(requestURL) except: raise Exception("Invalid requestURL: Cannot be converted to a str") # Content type should be "application/x-www-form-urlencoded" in the cases of POST data # (but don't override what may be there) if method == "POST" and (not headers or "Content-Type" not in headers): if not headers: headers = {} headers["Content-Type"] = "application/x-www-form-urlencoded" # open up a connection to the source store to get the recording data log.msg( 'Making HTTP request to "%s" (timeout=%s) (maxRetries=%i, retryTimeout=%i)...' % (requestURL, timeout, maxRetries, timeoutBetweenRetries), lvl="d2", ss="ss_webreq", ) if isinstance(postData, basestring): postData = postData.encode("utf-8") elif isinstance(postData, dict): postData = utils.friendlyURLEncode(postData) d = getPage( requestURL, timeout=timeout, method=method, postdata=postData, headers=headers, cookies=cookies, followRedirect=int(followRedirect), ) d.addCallback(finished) d.addErrback(failed) return d