Exemplo n.º 1
0
class Response:
    default_status = 200
    default_content_type = 'text/html; charset=UTF-8'

    def __init__(self, body: str='', status: int=None, headers: Dict=None,
                 **more_headers) -> None:
        self.headers = Headers()
        self.body = body
        self._status_code = status or self.default_status
        self._cookies = SimpleCookie()  # type: ignore

        if headers:
            for name, value in headers.items():
                self.headers.add_header(name, value)
        if more_headers:
            for name, value in more_headers.items():
                self.headers.add_header(name, value)

    @property
    def status_code(self):
        """ The HTTP status code as an integer (e.g. 404)."""
        return self._status_code

    @property
    def status(self):
        """ The HTTP status line as a string (e.g. ``404 Not Found``)."""
        if not 100 <= self._status_code <= 999:
            raise ValueError('Status code out of range.')
        status = _HTTP_STATUS_LINES.get(self._status_code)
        return str(status or ('{} Unknown'.format(self._status_code)))

    @status.setter
    def status(self, status_code: int):
        if not 100 <= status_code <= 999:
            raise ValueError('Status code out of range.')
        self._status_code = status_code

    @property
    def headerlist(self) -> List[Tuple[str, str]]:
        """ WSGI conform list of (header, value) tuples. """
        out = []  # type: List[Tuple[str, str]]
        if 'Content-Type' not in self.headers:
            self.headers.add_header('Content-Type', self.default_content_type)
        out += [(key, value)
                for key in self.headers.keys()
                for value in self.headers.get_all(key)]
        if self._cookies:
            for c in self._cookies.values():
                out.append(('Set-Cookie', c.OutputString()))
        return [(k, v.encode('utf8').decode('latin1')) for (k, v) in out]

    def set_cookie(self, key: str, value: Any, expires: str=None, path: str=None, **options: Dict[str, Any]) -> None:
        from datetime import timedelta, datetime, date
        import time
        self._cookies[key] = value
        if expires:
            self._cookies[key]['expires'] = expires
        if path:
            self._cookies[key]['path'] = path

        for k, v in options.items():
            if k == 'max_age':
                if isinstance(v, timedelta):
                    v = v.seconds + v.days * 24 * 3600  # type: ignore
            if k == 'expires':
                if isinstance(v, (date, datetime)):
                    v = v.timetuple()  # type: ignore
                elif isinstance(v, (int, float)):
                    v = v.gmtime(value)  # type: ignore
                v = time.strftime("%a, %d %b %Y %H:%M:%S GMT", v)  # type: ignore
            self._cookies[key][k.replace('_', '-')] = v  # type: ignore

    def delete_cookie(self, key, **kwargs) -> None:
        kwargs['max_age'] = -1
        kwargs['expires'] = 0
        self.set_cookie(key, '', **kwargs)

    def apply(self, other):
        self.status = other._status_code
        self._cookies = other._cookies
        self.headers = other.headers
        self.body = other.body