2020-11-25 08:58:01 +00:00
|
|
|
import hashlib
|
|
|
|
import sys
|
|
|
|
from typing import Optional
|
|
|
|
|
2020-03-12 15:04:31 +00:00
|
|
|
from six.moves.urllib.parse import quote, urlparse, urlunparse
|
2019-06-10 17:00:28 +00:00
|
|
|
import six
|
|
|
|
import fnmatch
|
|
|
|
|
2020-11-25 08:58:01 +00:00
|
|
|
from ..debugging.log import LoggerRoot
|
|
|
|
|
2019-06-10 17:00:28 +00:00
|
|
|
|
|
|
|
def get_config_object_matcher(**patterns):
|
|
|
|
unsupported = {k: v for k, v in patterns.items() if not isinstance(v, six.string_types)}
|
|
|
|
if unsupported:
|
|
|
|
raise ValueError('Unsupported object matcher (expecting string): %s'
|
|
|
|
% ', '.join('%s=%s' % (k, v) for k, v in unsupported.items()))
|
|
|
|
|
2020-05-22 09:00:07 +00:00
|
|
|
# optimize simple patters
|
|
|
|
starts_with = {k: v.rstrip('*') for k, v in patterns.items() if '*' not in v.rstrip('*') and '?' not in v}
|
|
|
|
patterns = {k: v for k, v in patterns.items() if v not in starts_with}
|
|
|
|
|
2019-06-10 17:00:28 +00:00
|
|
|
def _matcher(**kwargs):
|
|
|
|
for key, value in kwargs.items():
|
|
|
|
if not value:
|
|
|
|
continue
|
2020-05-22 09:00:07 +00:00
|
|
|
start = starts_with.get(key)
|
|
|
|
if start:
|
|
|
|
if value.startswith(start):
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
pat = patterns.get(key)
|
|
|
|
if pat and fnmatch.fnmatch(value, pat):
|
|
|
|
return True
|
|
|
|
|
2019-06-10 17:00:28 +00:00
|
|
|
return _matcher
|
2020-03-12 15:04:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
def quote_url(url):
|
|
|
|
parsed = urlparse(url)
|
|
|
|
if parsed.scheme not in ('http', 'https'):
|
|
|
|
return url
|
|
|
|
parsed = parsed._replace(path=quote(parsed.path))
|
|
|
|
return urlunparse(parsed)
|
2020-10-15 20:16:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
def encode_string_to_filename(text):
|
|
|
|
return quote(text, safe=" ")
|
2020-11-25 08:58:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
def sha256sum(filename, skip_header=0, block_size=65536):
|
|
|
|
# type: (str, int, int) -> (Optional[str], Optional[str])
|
|
|
|
# create sha2 of the file, notice we skip the header of the file (32 bytes)
|
|
|
|
# because sometimes that is the only change
|
|
|
|
h = hashlib.sha256()
|
|
|
|
file_hash = hashlib.sha256()
|
|
|
|
b = bytearray(block_size)
|
|
|
|
mv = memoryview(b)
|
|
|
|
try:
|
|
|
|
with open(filename, 'rb', buffering=0) as f:
|
|
|
|
# skip header
|
|
|
|
if skip_header:
|
|
|
|
file_hash.update(f.read(skip_header))
|
|
|
|
# noinspection PyUnresolvedReferences
|
|
|
|
for n in iter(lambda: f.readinto(mv), 0):
|
|
|
|
h.update(mv[:n])
|
|
|
|
if skip_header:
|
|
|
|
file_hash.update(mv[:n])
|
|
|
|
except Exception as e:
|
|
|
|
LoggerRoot.get_base_logger().warning(str(e))
|
|
|
|
return None, None
|
|
|
|
|
|
|
|
return h.hexdigest(), file_hash.hexdigest() if skip_header else None
|
|
|
|
|
|
|
|
|
|
|
|
def is_windows():
|
|
|
|
"""
|
|
|
|
:return: True if currently running on windows OS
|
|
|
|
"""
|
|
|
|
return sys.platform == 'win32'
|