From 2db58930a6f8c955c4d437657bd07e2939a705f2 Mon Sep 17 00:00:00 2001
From: James Taylor <user234683@users.noreply.github.com>
Date: Sun, 16 Jun 2019 16:16:03 -0700
Subject: Convert watch page to flask framework

---
 python/werkzeug/wrappers/common_descriptors.py | 322 +++++++++++++++++++++++++
 1 file changed, 322 insertions(+)
 create mode 100644 python/werkzeug/wrappers/common_descriptors.py

(limited to 'python/werkzeug/wrappers/common_descriptors.py')

diff --git a/python/werkzeug/wrappers/common_descriptors.py b/python/werkzeug/wrappers/common_descriptors.py
new file mode 100644
index 0000000..e4107ee
--- /dev/null
+++ b/python/werkzeug/wrappers/common_descriptors.py
@@ -0,0 +1,322 @@
+from datetime import datetime
+from datetime import timedelta
+
+from .._compat import string_types
+from ..datastructures import CallbackDict
+from ..http import dump_age
+from ..http import dump_header
+from ..http import dump_options_header
+from ..http import http_date
+from ..http import parse_age
+from ..http import parse_date
+from ..http import parse_options_header
+from ..http import parse_set_header
+from ..utils import cached_property
+from ..utils import environ_property
+from ..utils import get_content_type
+from ..utils import header_property
+from ..wsgi import get_content_length
+
+
+class CommonRequestDescriptorsMixin(object):
+    """A mixin for :class:`BaseRequest` subclasses.  Request objects that
+    mix this class in will automatically get descriptors for a couple of
+    HTTP headers with automatic type conversion.
+
+    .. versionadded:: 0.5
+    """
+
+    content_type = environ_property(
+        "CONTENT_TYPE",
+        doc="""The Content-Type entity-header field indicates the media
+        type of the entity-body sent to the recipient or, in the case of
+        the HEAD method, the media type that would have been sent had
+        the request been a GET.""",
+    )
+
+    @cached_property
+    def content_length(self):
+        """The Content-Length entity-header field indicates the size of the
+        entity-body in bytes or, in the case of the HEAD method, the size of
+        the entity-body that would have been sent had the request been a
+        GET.
+        """
+        return get_content_length(self.environ)
+
+    content_encoding = environ_property(
+        "HTTP_CONTENT_ENCODING",
+        doc="""The Content-Encoding entity-header field is used as a
+        modifier to the media-type. When present, its value indicates
+        what additional content codings have been applied to the
+        entity-body, and thus what decoding mechanisms must be applied
+        in order to obtain the media-type referenced by the Content-Type
+        header field.
+
+        .. versionadded:: 0.9""",
+    )
+    content_md5 = environ_property(
+        "HTTP_CONTENT_MD5",
+        doc="""The Content-MD5 entity-header field, as defined in
+        RFC 1864, is an MD5 digest of the entity-body for the purpose of
+        providing an end-to-end message integrity check (MIC) of the
+        entity-body. (Note: a MIC is good for detecting accidental
+        modification of the entity-body in transit, but is not proof
+        against malicious attacks.)
+
+        .. versionadded:: 0.9""",
+    )
+    referrer = environ_property(
+        "HTTP_REFERER",
+        doc="""The Referer[sic] request-header field allows the client
+        to specify, for the server's benefit, the address (URI) of the
+        resource from which the Request-URI was obtained (the
+        "referrer", although the header field is misspelled).""",
+    )
+    date = environ_property(
+        "HTTP_DATE",
+        None,
+        parse_date,
+        doc="""The Date general-header field represents the date and
+        time at which the message was originated, having the same
+        semantics as orig-date in RFC 822.""",
+    )
+    max_forwards = environ_property(
+        "HTTP_MAX_FORWARDS",
+        None,
+        int,
+        doc="""The Max-Forwards request-header field provides a
+        mechanism with the TRACE and OPTIONS methods to limit the number
+        of proxies or gateways that can forward the request to the next
+        inbound server.""",
+    )
+
+    def _parse_content_type(self):
+        if not hasattr(self, "_parsed_content_type"):
+            self._parsed_content_type = parse_options_header(
+                self.environ.get("CONTENT_TYPE", "")
+            )
+
+    @property
+    def mimetype(self):
+        """Like :attr:`content_type`, but without parameters (eg, without
+        charset, type etc.) and always lowercase.  For example if the content
+        type is ``text/HTML; charset=utf-8`` the mimetype would be
+        ``'text/html'``.
+        """
+        self._parse_content_type()
+        return self._parsed_content_type[0].lower()
+
+    @property
+    def mimetype_params(self):
+        """The mimetype parameters as dict.  For example if the content
+        type is ``text/html; charset=utf-8`` the params would be
+        ``{'charset': 'utf-8'}``.
+        """
+        self._parse_content_type()
+        return self._parsed_content_type[1]
+
+    @cached_property
+    def pragma(self):
+        """The Pragma general-header field is used to include
+        implementation-specific directives that might apply to any recipient
+        along the request/response chain.  All pragma directives specify
+        optional behavior from the viewpoint of the protocol; however, some
+        systems MAY require that behavior be consistent with the directives.
+        """
+        return parse_set_header(self.environ.get("HTTP_PRAGMA", ""))
+
+
+class CommonResponseDescriptorsMixin(object):
+    """A mixin for :class:`BaseResponse` subclasses.  Response objects that
+    mix this class in will automatically get descriptors for a couple of
+    HTTP headers with automatic type conversion.
+    """
+
+    @property
+    def mimetype(self):
+        """The mimetype (content type without charset etc.)"""
+        ct = self.headers.get("content-type")
+        if ct:
+            return ct.split(";")[0].strip()
+
+    @mimetype.setter
+    def mimetype(self, value):
+        self.headers["Content-Type"] = get_content_type(value, self.charset)
+
+    @property
+    def mimetype_params(self):
+        """The mimetype parameters as dict. For example if the
+        content type is ``text/html; charset=utf-8`` the params would be
+        ``{'charset': 'utf-8'}``.
+
+        .. versionadded:: 0.5
+        """
+
+        def on_update(d):
+            self.headers["Content-Type"] = dump_options_header(self.mimetype, d)
+
+        d = parse_options_header(self.headers.get("content-type", ""))[1]
+        return CallbackDict(d, on_update)
+
+    location = header_property(
+        "Location",
+        doc="""The Location response-header field is used to redirect
+        the recipient to a location other than the Request-URI for
+        completion of the request or identification of a new
+        resource.""",
+    )
+    age = header_property(
+        "Age",
+        None,
+        parse_age,
+        dump_age,
+        doc="""The Age response-header field conveys the sender's
+        estimate of the amount of time since the response (or its
+        revalidation) was generated at the origin server.
+
+        Age values are non-negative decimal integers, representing time
+        in seconds.""",
+    )
+    content_type = header_property(
+        "Content-Type",
+        doc="""The Content-Type entity-header field indicates the media
+        type of the entity-body sent to the recipient or, in the case of
+        the HEAD method, the media type that would have been sent had
+        the request been a GET.""",
+    )
+    content_length = header_property(
+        "Content-Length",
+        None,
+        int,
+        str,
+        doc="""The Content-Length entity-header field indicates the size
+        of the entity-body, in decimal number of OCTETs, sent to the
+        recipient or, in the case of the HEAD method, the size of the
+        entity-body that would have been sent had the request been a
+        GET.""",
+    )
+    content_location = header_property(
+        "Content-Location",
+        doc="""The Content-Location entity-header field MAY be used to
+        supply the resource location for the entity enclosed in the
+        message when that entity is accessible from a location separate
+        from the requested resource's URI.""",
+    )
+    content_encoding = header_property(
+        "Content-Encoding",
+        doc="""The Content-Encoding entity-header field is used as a
+        modifier to the media-type. When present, its value indicates
+        what additional content codings have been applied to the
+        entity-body, and thus what decoding mechanisms must be applied
+        in order to obtain the media-type referenced by the Content-Type
+        header field.""",
+    )
+    content_md5 = header_property(
+        "Content-MD5",
+        doc="""The Content-MD5 entity-header field, as defined in
+        RFC 1864, is an MD5 digest of the entity-body for the purpose of
+        providing an end-to-end message integrity check (MIC) of the
+        entity-body. (Note: a MIC is good for detecting accidental
+        modification of the entity-body in transit, but is not proof
+        against malicious attacks.)""",
+    )
+    date = header_property(
+        "Date",
+        None,
+        parse_date,
+        http_date,
+        doc="""The Date general-header field represents the date and
+        time at which the message was originated, having the same
+        semantics as orig-date in RFC 822.""",
+    )
+    expires = header_property(
+        "Expires",
+        None,
+        parse_date,
+        http_date,
+        doc="""The Expires entity-header field gives the date/time after
+        which the response is considered stale. A stale cache entry may
+        not normally be returned by a cache.""",
+    )
+    last_modified = header_property(
+        "Last-Modified",
+        None,
+        parse_date,
+        http_date,
+        doc="""The Last-Modified entity-header field indicates the date
+        and time at which the origin server believes the variant was
+        last modified.""",
+    )
+
+    @property
+    def retry_after(self):
+        """The Retry-After response-header field can be used with a
+        503 (Service Unavailable) response to indicate how long the
+        service is expected to be unavailable to the requesting client.
+
+        Time in seconds until expiration or date.
+        """
+        value = self.headers.get("retry-after")
+        if value is None:
+            return
+        elif value.isdigit():
+            return datetime.utcnow() + timedelta(seconds=int(value))
+        return parse_date(value)
+
+    @retry_after.setter
+    def retry_after(self, value):
+        if value is None:
+            if "retry-after" in self.headers:
+                del self.headers["retry-after"]
+            return
+        elif isinstance(value, datetime):
+            value = http_date(value)
+        else:
+            value = str(value)
+        self.headers["Retry-After"] = value
+
+    def _set_property(name, doc=None):  # noqa: B902
+        def fget(self):
+            def on_update(header_set):
+                if not header_set and name in self.headers:
+                    del self.headers[name]
+                elif header_set:
+                    self.headers[name] = header_set.to_header()
+
+            return parse_set_header(self.headers.get(name), on_update)
+
+        def fset(self, value):
+            if not value:
+                del self.headers[name]
+            elif isinstance(value, string_types):
+                self.headers[name] = value
+            else:
+                self.headers[name] = dump_header(value)
+
+        return property(fget, fset, doc=doc)
+
+    vary = _set_property(
+        "Vary",
+        doc="""The Vary field value indicates the set of request-header
+        fields that fully determines, while the response is fresh,
+        whether a cache is permitted to use the response to reply to a
+        subsequent request without revalidation.""",
+    )
+    content_language = _set_property(
+        "Content-Language",
+        doc="""The Content-Language entity-header field describes the
+        natural language(s) of the intended audience for the enclosed
+        entity. Note that this might not be equivalent to all the
+        languages used within the entity-body.""",
+    )
+    allow = _set_property(
+        "Allow",
+        doc="""The Allow entity-header field lists the set of methods
+        supported by the resource identified by the Request-URI. The
+        purpose of this field is strictly to inform the recipient of
+        valid methods associated with the resource. An Allow header
+        field MUST be present in a 405 (Method Not Allowed)
+        response.""",
+    )
+
+    del _set_property
-- 
cgit v1.2.3