-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/dev'
- Loading branch information
Showing
5 changed files
with
128 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,27 @@ | ||
import re | ||
|
||
build_regex = re.compile(r'^(?P<filename>[\w@~-]+)(?P<extension>.*)$') | ||
|
||
check_regex = re.compile( | ||
r'^(?P<filename>.*)[.]v[\w-]+m[0-9a-fA-F]+(?P<extension>(?:(?:(?<![.])[.])?[\w])+)$' | ||
) | ||
cache_regex = re.compile(r"^v[\w-]+m[0-9a-fA-F]+$") | ||
|
||
|
||
def build_fingerprint(path, version, hash_value): | ||
res = build_regex.match(path) | ||
path_parts = path.split("/") | ||
filename, extension = path_parts[-1].split(".", 1) | ||
|
||
return '{}.v{}m{}{}'.format( | ||
res.group('filename'), | ||
str(version).replace('.', '_'), | ||
return "{}.v{}m{}.{}".format( | ||
"/".join(path_parts[:-1] + [filename]), | ||
str(version).replace(".", "_"), | ||
hash_value, | ||
res.group('extension'), | ||
extension, | ||
) | ||
|
||
|
||
def check_fingerprint(path): | ||
path_parts = path.split("/") | ||
name_parts = path_parts[-1].split(".") | ||
|
||
# Check if the resource has a fingerprint | ||
res = check_regex.match(path) | ||
|
||
# Resolve real resource name from fingerprinted resource path | ||
return ( | ||
res.group('filename') + res.group('extension') | ||
if res is not None | ||
else path, | ||
res is not None, | ||
) | ||
if len(name_parts) > 2 and cache_regex.match(name_parts[1]): | ||
original_name = ".".join([name_parts[0]] + name_parts[2:]) | ||
return "/".join(path_parts[:-1] + [original_name]), True | ||
|
||
return path, False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
__version__ = '1.5.0' | ||
__version__ = '1.5.1' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,122 @@ | ||
|
||
from dash.fingerprint import build_fingerprint, check_fingerprint | ||
|
||
version = 1 | ||
hash_value = 1 | ||
|
||
valid_resources = [ | ||
{'path': '[email protected]', 'fingerprint': '[email protected]'}, | ||
{'path': '[email protected]', 'fingerprint': '[email protected]_1_1m1234567890abcdef.8.6.min.js', 'version': '1.1.1', 'hash': '1234567890abcdef' }, | ||
{'path': '[email protected]', 'fingerprint': '[email protected]_1_1-alpha_1m1234567890abcdef.8.6.min.js', 'version': '1.1.1-alpha.1', 'hash': '1234567890abcdef' }, | ||
{'path': 'dash.plotly.js', 'fingerprint': 'dash.v1m1.plotly.js'}, | ||
{'path': 'dash.plotly.j_s', 'fingerprint': 'dash.v1m1.plotly.j_s'}, | ||
{'path': 'dash.plotly.css', 'fingerprint': 'dash.v1m1.plotly.css'}, | ||
{'path': 'dash.plotly.xxx.yyy.zzz', 'fingerprint': 'dash.v1m1.plotly.xxx.yyy.zzz'}, | ||
{'path': 'dash~plotly.js', 'fingerprint': 'dash~plotly.v1m1.js'} | ||
{"path": "[email protected]", "fingerprint": "[email protected]"}, | ||
{ | ||
"path": "[email protected]", | ||
"fingerprint": "[email protected]_1_1m1234567890abcdef.8.6.min.js", | ||
"version": "1.1.1", | ||
"hash": "1234567890abcdef", | ||
}, | ||
{ | ||
"path": "[email protected]", | ||
"fingerprint": "[email protected]_1_1-alpha_1m1234567890abcdef.8.6.min.js", | ||
"version": "1.1.1-alpha.1", | ||
"hash": "1234567890abcdef", | ||
}, | ||
{"path": "dash.plotly.js", "fingerprint": "dash.v1m1.plotly.js"}, | ||
{"path": "dash.plotly.j_s", "fingerprint": "dash.v1m1.plotly.j_s"}, | ||
{"path": "dash.plotly.css", "fingerprint": "dash.v1m1.plotly.css"}, | ||
{"path": "dash.plotly.xxx.yyy.zzz", "fingerprint": "dash.v1m1.plotly.xxx.yyy.zzz"}, | ||
{"path": "dash~plotly.js", "fingerprint": "dash~plotly.v1m1.js"}, | ||
{"path": "nested/folder/file.js", "fingerprint": "nested/folder/file.v1m1.js"}, | ||
{ | ||
# kind of pathological, but we have what looks like a version string | ||
# in a different place - still works | ||
"path": "nested.v2m2/folder/file.js", | ||
"fingerprint": "nested.v2m2/folder/file.v1m1.js" | ||
}, | ||
{ | ||
# even works if it gets doubled up in the right place | ||
"path": "nested/folder/file.v2m2.js", | ||
"fingerprint": "nested/folder/file.v1m1.v2m2.js" | ||
}, | ||
{ | ||
"path": "nested.dotted/folder.structure/file.name.css", | ||
"fingerprint": "nested.dotted/folder.structure/file.v1m1.name.css", | ||
}, | ||
{ | ||
"path": "dash..plotly.js", | ||
"fingerprint": "dash.v1_1_1m1234567890..plotly.js", | ||
"version": "1.1.1", | ||
"hash": "1234567890", | ||
}, | ||
{ | ||
"path": "dash.", | ||
"fingerprint": "dash.v1_1_1m1234567890.", | ||
"version": "1.1.1", | ||
"hash": "1234567890", | ||
}, | ||
{ | ||
"path": "dash..", | ||
"fingerprint": "dash.v1_1_1m1234567890..", | ||
"version": "1.1.1", | ||
"hash": "1234567890", | ||
}, | ||
{ | ||
"path": "dash.js.", | ||
"fingerprint": "dash.v1_1_1m1234567890.js.", | ||
"version": "1.1.1", | ||
"hash": "1234567890", | ||
}, | ||
{ | ||
"path": "dash.j-s", | ||
"fingerprint": "dash.v1_1_1m1234567890.j-s", | ||
"version": "1.1.1", | ||
"hash": "1234567890", | ||
}, | ||
] | ||
|
||
valid_fingerprints = [ | ||
'[email protected]_1_2m1571771240.8.6.min.js', | ||
'dash.plotly.v1_1_1m1234567890.js', | ||
'dash.plotly.v1_1_1m1234567890.j_s', | ||
'dash.plotly.v1_1_1m1234567890.css', | ||
'dash.plotly.v1_1_1m1234567890.xxx.yyy.zzz', | ||
'dash.plotly.v1_1_1-alpha1m1234567890.js', | ||
'dash.plotly.v1_1_1-alpha_3m1234567890.js', | ||
'dash.plotly.v1_1_1m1234567890123.js', | ||
'dash.plotly.v1_1_1m4bc3.js', | ||
'dash~plotly.v1m1.js' | ||
"[email protected]_1_2m1571771240.8.6.min.js", | ||
"dash.v1_1_1m1234567890.plotly.js", | ||
"dash.v1_1_1m1234567890.plotly.j_s", | ||
"dash.v1_1_1m1234567890.plotly.css", | ||
"dash.v1_1_1m1234567890.plotly.xxx.yyy.zzz", | ||
"dash.v1_1_1-alpha1m1234567890.plotly.js", | ||
"dash.v1_1_1-alpha_3m1234567890.plotly.js", | ||
"dash.v1_1_1m1234567890123.plotly.js", | ||
"dash.v1_1_1m4bc3.plotly.js", | ||
"dash~plotly.v1m1.js", | ||
"nested/folder/file.v1m1.js", | ||
"nested.dotted/folder.structure/file.v1m1.name.css", | ||
# this one has a pattern that looks like the version string in the wrong place | ||
# AND one in the right place. | ||
"nested.v2m2/folder/file.v1m1.js", | ||
"nested.v2m2.dotted/folder.structure/file.v1m1.name.css", | ||
] | ||
|
||
invalid_fingerprints = [ | ||
'dash.plotly.v1_1_1m1234567890..js', | ||
'dash.plotly.v1_1_1m1234567890.', | ||
'dash.plotly.v1_1_1m1234567890..', | ||
'dash.plotly.v1_1_1m1234567890.js.', | ||
'dash.plotly.v1_1_1m1234567890.j-s' | ||
"dash.plotly.v1_1_1m1234567890.js", | ||
"folder/dash.plotly.v1_1_1m1234567890.js", | ||
"nested.v1m1/folder/file.js", | ||
"nested.v1m1.dotted/folder.structure/file.name.css", | ||
] | ||
|
||
|
||
def test_fingerprint(): | ||
for resource in valid_resources: | ||
# The fingerprint matches expectations | ||
fingerprint = build_fingerprint(resource.get('path'), resource.get('version', version), resource.get('hash', hash_value)) | ||
assert fingerprint == resource.get('fingerprint') | ||
fingerprint = build_fingerprint( | ||
resource.get("path"), | ||
resource.get("version", version), | ||
resource.get("hash", hash_value), | ||
) | ||
assert fingerprint == resource.get("fingerprint") | ||
|
||
(original_path, has_fingerprint) = check_fingerprint(fingerprint) | ||
# The inverse operation returns that the fingerprint was valid and the original path | ||
# The inverse operation returns that the fingerprint was valid | ||
# and the original path | ||
assert has_fingerprint | ||
assert original_path == resource.get('path') | ||
assert original_path == resource.get("path") | ||
|
||
for resource in valid_fingerprints: | ||
(_, has_fingerprint) = check_fingerprint(resource) | ||
assert has_fingerprint | ||
assert has_fingerprint, resource | ||
|
||
for resource in invalid_fingerprints: | ||
(_, has_fingerprint) = check_fingerprint(resource) | ||
assert not has_fingerprint | ||
assert not has_fingerprint, resource |