]>
jfr.im git - dlqueue.git/blob - venv/lib/python3.11/site-packages/werkzeug/datastructures/range.py
1 from __future__
import annotations
5 """Very simple object that represents the `If-Range` header in parsed
6 form. It will either have neither a etag or date or one of either but
12 def __init__(self
, etag
=None, date
=None):
13 #: The etag parsed and unquoted. Ranges always operate on strong
14 #: etags so the weakness information is not necessary.
16 #: The date in parsed format or `None`.
20 """Converts the object back into an HTTP header."""
21 if self
.date
is not None:
22 return http
.http_date(self
.date
)
23 if self
.etag
is not None:
24 return http
.quote_etag(self
.etag
)
28 return self
.to_header()
31 return f
"<{type(self).__name__} {str(self)!r}>"
35 """Represents a ``Range`` header. All methods only support only
36 bytes as the unit. Stores a list of ranges if given, but the methods
37 only work if only one range is provided.
39 :raise ValueError: If the ranges provided are invalid.
41 .. versionchanged:: 0.15
42 The ranges passed in are validated.
47 def __init__(self
, units
, ranges
):
48 #: The units of this range. Usually "bytes".
50 #: A list of ``(begin, end)`` tuples for the range header provided.
51 #: The ranges are non-inclusive.
54 for start
, end
in ranges
:
55 if start
is None or (end
is not None and (start
< 0 or start
>= end
)):
56 raise ValueError(f
"{(start, end)} is not a valid range.")
58 def range_for_length(self
, length
):
59 """If the range is for bytes, the length is not None and there is
60 exactly one range and it is satisfiable it returns a ``(start, stop)``
61 tuple, otherwise `None`.
63 if self
.units
!= "bytes" or length
is None or len(self
.ranges
) != 1:
65 start
, end
= self
.ranges
[0]
70 if http
.is_byte_range_valid(start
, end
, length
):
71 return start
, min(end
, length
)
74 def make_content_range(self
, length
):
75 """Creates a :class:`~werkzeug.datastructures.ContentRange` object
76 from the current range and given content length.
78 rng
= self
.range_for_length(length
)
80 return ContentRange(self
.units
, rng
[0], rng
[1], length
)
84 """Converts the object back into an HTTP header."""
86 for begin
, end
in self
.ranges
:
88 ranges
.append(f
"{begin}-" if begin
>= 0 else str(begin
))
90 ranges
.append(f
"{begin}-{end - 1}")
91 return f
"{self.units}={','.join(ranges)}"
93 def to_content_range_header(self
, length
):
94 """Converts the object into `Content-Range` HTTP header,
97 range = self
.range_for_length(length
)
99 return f
"{self.units} {range[0]}-{range[1] - 1}/{length}"
103 return self
.to_header()
106 return f
"<{type(self).__name__} {str(self)!r}>"
109 def _callback_property(name
):
111 return getattr(self
, name
)
113 def fset(self
, value
):
114 setattr(self
, name
, value
)
115 if self
.on_update
is not None:
118 return property(fget
, fset
)
122 """Represents the content range header.
124 .. versionadded:: 0.7
127 def __init__(self
, units
, start
, stop
, length
=None, on_update
=None):
128 assert http
.is_byte_range_valid(start
, stop
, length
), "Bad range provided"
129 self
.on_update
= on_update
130 self
.set(start
, stop
, length
, units
)
132 #: The units to use, usually "bytes"
133 units
= _callback_property("_units")
134 #: The start point of the range or `None`.
135 start
= _callback_property("_start")
136 #: The stop point of the range (non-inclusive) or `None`. Can only be
137 #: `None` if also start is `None`.
138 stop
= _callback_property("_stop")
139 #: The length of the range or `None`.
140 length
= _callback_property("_length")
142 def set(self
, start
, stop
, length
=None, units
="bytes"):
143 """Simple method to update the ranges."""
144 assert http
.is_byte_range_valid(start
, stop
, length
), "Bad range provided"
148 self
._length
= length
149 if self
.on_update
is not None:
153 """Sets the units to `None` which indicates that the header should
156 self
.set(None, None, units
=None)
159 if self
.units
is None:
161 if self
.length
is None:
165 if self
.start
is None:
166 return f
"{self.units} */{length}"
167 return f
"{self.units} {self.start}-{self.stop - 1}/{length}"
170 return self
.units
is not None
173 return self
.to_header()
176 return f
"<{type(self).__name__} {str(self)!r}>"
179 # circular dependencies