Ejemplo n.º 1
0
    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