mirror of
https://github.com/webrecorder/pywb.git
synced 2025-03-15 00:03:28 +01:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7b0f8b5860 | ||
|
b44c93bf6e | ||
|
97fffe3a34 | ||
|
6205646b9b | ||
|
23891be2f1 | ||
|
b190dddee9 |
@ -13,7 +13,7 @@ Web Archiving Tools for All
|
|||||||
|
|
||||||
`View the full pywb documentation <https://pywb.readthedocs.org>`_
|
`View the full pywb documentation <https://pywb.readthedocs.org>`_
|
||||||
|
|
||||||
**pywb** is a Python (2 and 3) web archiving toolkit for replaying web archives large and small as accurately as possible.
|
**pywb** is a Python 3 web archiving toolkit for replaying web archives large and small as accurately as possible.
|
||||||
The toolkit now also includes new features for creating high-fidelity web archives.
|
The toolkit now also includes new features for creating high-fidelity web archives.
|
||||||
|
|
||||||
This toolset forms the foundation of Webrecorder project, but also provides a generic web archiving toolkit
|
This toolset forms the foundation of Webrecorder project, but also provides a generic web archiving toolkit
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
__version__ = '2.8.0'
|
__version__ = '2.8.3'
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print(__version__)
|
print(__version__)
|
||||||
|
@ -11,6 +11,7 @@ from io import BytesIO
|
|||||||
import base64
|
import base64
|
||||||
import cgi
|
import cgi
|
||||||
import json
|
import json
|
||||||
|
import math
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
@ -328,6 +329,21 @@ class MethodQueryCanonicalizer(object):
|
|||||||
_parser(v, name)
|
_parser(v, name)
|
||||||
|
|
||||||
elif name:
|
elif name:
|
||||||
|
if isinstance(json_obj, bool) and json_obj:
|
||||||
|
data[get_key(name)] = "true"
|
||||||
|
elif isinstance(json_obj, bool):
|
||||||
|
data[get_key(name)] = "false"
|
||||||
|
elif json_obj is None:
|
||||||
|
data[get_key(name)] = "null"
|
||||||
|
elif isinstance(json_obj, float):
|
||||||
|
# Treat floats like JavaScript's Number.prototype.toString(),
|
||||||
|
# drop decimal if float represents a whole number.
|
||||||
|
fraction, _ = math.modf(json_obj)
|
||||||
|
if fraction == 0.0:
|
||||||
|
data[get_key(name)] = str(int(json_obj))
|
||||||
|
else:
|
||||||
|
data[get_key(name)] = str(json_obj)
|
||||||
|
else:
|
||||||
data[get_key(name)] = str(json_obj)
|
data[get_key(name)] = str(json_obj)
|
||||||
|
|
||||||
_parser(json.loads(string))
|
_parser(json.loads(string))
|
||||||
|
@ -82,44 +82,49 @@ Foo: Bar\r\n\
|
|||||||
class TestPostQueryExtract(object):
|
class TestPostQueryExtract(object):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup_class(cls):
|
def setup_class(cls):
|
||||||
cls.post_data = b'foo=bar&dir=%2Fbaz'
|
cls.post_data = b'foo=bar&dir=%2Fbaz&do=true&re=false&re=null'
|
||||||
cls.binary_post_data = b'\x816l`L\xa04P\x0e\xe0r\x02\xb5\x89\x19\x00fP\xdb\x0e\xb0\x02,'
|
cls.binary_post_data = b'\x816l`L\xa04P\x0e\xe0r\x02\xb5\x89\x19\x00fP\xdb\x0e\xb0\x02,'
|
||||||
|
|
||||||
def test_post_extract_1(self):
|
def test_post_extract_1(self):
|
||||||
mq = MethodQueryCanonicalizer('POST', 'application/x-www-form-urlencoded',
|
mq = MethodQueryCanonicalizer('POST', 'application/x-www-form-urlencoded',
|
||||||
len(self.post_data), BytesIO(self.post_data))
|
len(self.post_data), BytesIO(self.post_data))
|
||||||
|
|
||||||
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&foo=bar&dir=/baz'
|
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&foo=bar&dir=/baz&do=true&re=false&re=null'
|
||||||
|
|
||||||
assert mq.append_query('http://example.com/?123=ABC') == 'http://example.com/?123=ABC&__wb_method=POST&foo=bar&dir=/baz'
|
assert mq.append_query('http://example.com/?123=ABC') == 'http://example.com/?123=ABC&__wb_method=POST&foo=bar&dir=/baz&do=true&re=false&re=null'
|
||||||
|
|
||||||
def test_post_extract_json(self):
|
def test_post_extract_json(self):
|
||||||
post_data = b'{"a": "b", "c": {"a": 2}, "d": "e"}'
|
post_data = b'{"a": "b", "c": {"a": 2}, "d": "e", "f": true, "g": [false, null]}'
|
||||||
mq = MethodQueryCanonicalizer('POST', 'application/json',
|
mq = MethodQueryCanonicalizer('POST', 'application/json',
|
||||||
len(post_data), BytesIO(post_data))
|
len(post_data), BytesIO(post_data))
|
||||||
|
|
||||||
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&a=b&a.2_=2&d=e'
|
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&a=b&a.2_=2&d=e&f=true&g=false&g.2_=null'
|
||||||
|
|
||||||
|
post_data = b'{"type": "event", "id": 44.0, "float": 35.7, "values": [true, false, null], "source": {"type": "component", "id": "a+b&c= d", "values": [3, 4]}}'
|
||||||
|
mq = MethodQueryCanonicalizer('POST', 'application/json',
|
||||||
|
len(post_data), BytesIO(post_data))
|
||||||
|
|
||||||
|
assert mq.append_query('http://example.com/events') == 'http://example.com/events?__wb_method=POST&type=event&id=44&float=35.7&values=true&values.2_=false&values.3_=null&type.2_=component&id.2_=a%2Bb%26c%3D+d&values.4_=3&values.5_=4'
|
||||||
|
|
||||||
def test_put_extract_method(self):
|
def test_put_extract_method(self):
|
||||||
mq = MethodQueryCanonicalizer('PUT', 'application/x-www-form-urlencoded',
|
mq = MethodQueryCanonicalizer('PUT', 'application/x-www-form-urlencoded',
|
||||||
len(self.post_data), BytesIO(self.post_data))
|
len(self.post_data), BytesIO(self.post_data))
|
||||||
|
|
||||||
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=PUT&foo=bar&dir=/baz'
|
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=PUT&foo=bar&dir=/baz&do=true&re=false&re=null'
|
||||||
|
|
||||||
def test_post_extract_non_form_data_1(self):
|
def test_post_extract_non_form_data_1(self):
|
||||||
mq = MethodQueryCanonicalizer('POST', 'application/octet-stream',
|
mq = MethodQueryCanonicalizer('POST', 'application/octet-stream',
|
||||||
len(self.post_data), BytesIO(self.post_data))
|
len(self.post_data), BytesIO(self.post_data))
|
||||||
|
|
||||||
#base64 encoded data
|
#base64 encoded data
|
||||||
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&__wb_post_data=Zm9vPWJhciZkaXI9JTJGYmF6'
|
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&__wb_post_data=Zm9vPWJhciZkaXI9JTJGYmF6JmRvPXRydWUmcmU9ZmFsc2UmcmU9bnVsbA=='
|
||||||
|
|
||||||
def test_post_extract_non_form_data_2(self):
|
def test_post_extract_non_form_data_2(self):
|
||||||
mq = MethodQueryCanonicalizer('POST', 'text/plain',
|
mq = MethodQueryCanonicalizer('POST', 'text/plain',
|
||||||
len(self.post_data), BytesIO(self.post_data))
|
len(self.post_data), BytesIO(self.post_data))
|
||||||
|
|
||||||
#base64 encoded data
|
#base64 encoded data
|
||||||
assert mq.append_query('http://example.com/pathbar?id=123') == 'http://example.com/pathbar?id=123&__wb_method=POST&__wb_post_data=Zm9vPWJhciZkaXI9JTJGYmF6'
|
assert mq.append_query('http://example.com/pathbar?id=123') == 'http://example.com/pathbar?id=123&__wb_method=POST&__wb_post_data=Zm9vPWJhciZkaXI9JTJGYmF6JmRvPXRydWUmcmU9ZmFsc2UmcmU9bnVsbA=='
|
||||||
|
|
||||||
def test_post_extract_length_invalid_ignore(self):
|
def test_post_extract_length_invalid_ignore(self):
|
||||||
mq = MethodQueryCanonicalizer('POST', 'application/x-www-form-urlencoded',
|
mq = MethodQueryCanonicalizer('POST', 'application/x-www-form-urlencoded',
|
||||||
@ -136,13 +141,13 @@ class TestPostQueryExtract(object):
|
|||||||
mq = MethodQueryCanonicalizer('POST', 'application/x-www-form-urlencoded',
|
mq = MethodQueryCanonicalizer('POST', 'application/x-www-form-urlencoded',
|
||||||
len(self.post_data) - 4, BytesIO(self.post_data))
|
len(self.post_data) - 4, BytesIO(self.post_data))
|
||||||
|
|
||||||
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&foo=bar&dir=%2'
|
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&foo=bar&dir=/baz&do=true&re=false&re='
|
||||||
|
|
||||||
def test_post_extract_length_too_long(self):
|
def test_post_extract_length_too_long(self):
|
||||||
mq = MethodQueryCanonicalizer('POST', 'application/x-www-form-urlencoded',
|
mq = MethodQueryCanonicalizer('POST', 'application/x-www-form-urlencoded',
|
||||||
len(self.post_data) + 4, BytesIO(self.post_data))
|
len(self.post_data) + 4, BytesIO(self.post_data))
|
||||||
|
|
||||||
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&foo=bar&dir=/baz'
|
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&foo=bar&dir=/baz&do=true&re=false&re=null'
|
||||||
|
|
||||||
def test_post_extract_malformed_form_data(self):
|
def test_post_extract_malformed_form_data(self):
|
||||||
mq = MethodQueryCanonicalizer('POST', 'application/x-www-form-urlencoded',
|
mq = MethodQueryCanonicalizer('POST', 'application/x-www-form-urlencoded',
|
||||||
@ -155,7 +160,7 @@ class TestPostQueryExtract(object):
|
|||||||
mq = MethodQueryCanonicalizer('POST', 'multipart/form-data',
|
mq = MethodQueryCanonicalizer('POST', 'multipart/form-data',
|
||||||
len(self.post_data), BytesIO(self.post_data))
|
len(self.post_data), BytesIO(self.post_data))
|
||||||
|
|
||||||
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&__wb_post_data=Zm9vPWJhciZkaXI9JTJGYmF6'
|
assert mq.append_query('http://example.com/') == 'http://example.com/?__wb_method=POST&__wb_post_data=Zm9vPWJhciZkaXI9JTJGYmF6JmRvPXRydWUmcmU9ZmFsc2UmcmU9bnVsbA=='
|
||||||
|
|
||||||
|
|
||||||
def test_options(self):
|
def test_options(self):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
six
|
six
|
||||||
warcio>=1.7.1
|
warcio>=1.7.1
|
||||||
requests
|
requests
|
||||||
redis
|
redis==2.10.6
|
||||||
jinja2>=3.1.2
|
jinja2>=3.1.2
|
||||||
surt>=0.3.1
|
surt>=0.3.1
|
||||||
brotlipy
|
brotlipy
|
||||||
@ -18,3 +18,4 @@ tldextract
|
|||||||
python-dateutil
|
python-dateutil
|
||||||
markupsafe>=2.1.1
|
markupsafe>=2.1.1
|
||||||
ua_parser
|
ua_parser
|
||||||
|
py3AMF
|
||||||
|
4
setup.py
4
setup.py
@ -62,10 +62,6 @@ def generate_git_hash_py(pkg, filename='git_hash.py'):
|
|||||||
def load_requirements(filename):
|
def load_requirements(filename):
|
||||||
with open(filename, 'rt') as fh:
|
with open(filename, 'rt') as fh:
|
||||||
requirements = fh.read().rstrip().split('\n')
|
requirements = fh.read().rstrip().split('\n')
|
||||||
if sys.version_info > (3, 0):
|
|
||||||
requirements.append("py3AMF")
|
|
||||||
else:
|
|
||||||
requirements.append("pyAMF")
|
|
||||||
return requirements
|
return requirements
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user