# Path: xpaw/errors.py
# class ClientError(Exception):
#     """
#     Downloader client error.
#     """
# 
# class NotEnabled(Exception):
#     """
#     Not enabled.
#     """
# 
# class HttpError(Exception):
#     """
#     HTTP status is not 2xx.
#     """
# 
#     def __init__(self, *args, response=None, **kwargs):
#         self.response = response
#         super().__init__(*args, **kwargs)
# 
# Path: xpaw/utils.py
# def with_not_none_params(**kwargs):
#     params = {}
#     for k, v in kwargs.items():
#         if v is not None:
#             params[k] = v
#     return params


import logging
from xpaw.errors import ClientError, NotEnabled, HttpError
from xpaw.utils import with_not_none_params

class RetryMiddleware:
    RETRY_ERRORS = (ClientError,)
    RETRY_HTTP_STATUS = (500, 502, 503, 504, 408, 429)

    def __init__(self, max_retry_times=3, retry_http_status=None):
        self._max_retry_times = max_retry_times
        self._retry_http_status = retry_http_status or self.RETRY_HTTP_STATUS

    def __repr__(self):
        cls_name = self.__class__.__name__
        return '{}(max_retry_times={}, retry_http_status={})' \
            .format(cls_name, repr(self._max_retry_times), repr(self._retry_http_status))

    @classmethod
    def from_crawler(cls, crawler):
        config = crawler.config
        if not config.getbool('retry_enabled'):
            raise NotEnabled
        return cls(**with_not_none_params(max_retry_times=config.getint('max_retry_times'),
                                          retry_http_status=config.getlist('retry_http_status')))

    def handle_response(self, request, response):
        for p in self._retry_http_status:
            if self.match_status(p, response.status):
                return self.retry(request, "HTTP status={}".format(response.status))

    @staticmethod
    def match_status(pattern, status):
        if isinstance(pattern, int):

# Path: xpaw/errors.py
# class ClientError(Exception):
#     """
#     Downloader client error.
#     """
# 
# class NotEnabled(Exception):
#     """
#     Not enabled.
#     """
# 
# class HttpError(Exception):
#     """
#     HTTP status is not 2xx.
#     """
# 
#     def __init__(self, *args, response=None, **kwargs):
#         self.response = response
#         super().__init__(*args, **kwargs)
# 
# Path: xpaw/utils.py
# def with_not_none_params(**kwargs):
#     params = {}
#     for k, v in kwargs.items():
#         if v is not None:
#             params[k] = v
#     return params


# Path: xpaw/extensions/retry.py
import logging
from xpaw.errors import ClientError, NotEnabled, HttpError
from xpaw.utils import with_not_none_params


class RetryMiddleware:
    RETRY_ERRORS = (ClientError,)
    RETRY_HTTP_STATUS = (500, 502, 503, 504, 408, 429)

    def __init__(self, max_retry_times=3, retry_http_status=None):
        self._max_retry_times = max_retry_times
        self._retry_http_status = retry_http_status or self.RETRY_HTTP_STATUS

    def __repr__(self):
        cls_name = self.__class__.__name__
        return '{}(max_retry_times={}, retry_http_status={})' \
            .format(cls_name, repr(self._max_retry_times), repr(self._retry_http_status))

    @classmethod
    def from_crawler(cls, crawler):
        config = crawler.config
        if not config.getbool('retry_enabled'):
            raise NotEnabled
        return cls(**with_not_none_params(max_retry_times=config.getint('max_retry_times'),
                                          retry_http_status=config.getlist('retry_http_status')))

    def handle_response(self, request, response):
        for p in self._retry_http_status:
            if self.match_status(p, response.status):
                return self.retry(request, "HTTP status={}".format(response.status))

    @staticmethod
    def match_status(pattern, status):
        if isinstance(pattern, int):

            return pattern == status