minor changes

This commit is contained in:
Izalia Mae 2021-11-07 19:38:13 -05:00
parent 0dd58fc06e
commit 701dcdbf94
3 changed files with 63 additions and 25 deletions

View file

@ -1,5 +1,7 @@
import json import json
from urllib.parse import unquote_plus, quote
from .path import Path from .path import Path
@ -66,6 +68,13 @@ class DotDict(dict):
return data return data
@classmethod
def new_from_query_string(cls, query):
data = cls()
data.from_query(query)
return data
def copy(self): def copy(self):
return DotDict(self) return DotDict(self)
@ -75,6 +84,21 @@ class DotDict(dict):
self.__setitem__(k, v) self.__setitem__(k, v)
def from_query(self, query):
if not query:
return
for qline in unquote_plus(query).split('&'):
try: key, value = qline.split('=')
except: key, value = qline, None
self[key] = value
def to_query(self):
return quote('&'.join(f'{k}={v}' for k,v in self.items()))
def to_json(self, indent=None, **kwargs): def to_json(self, indent=None, **kwargs):
if 'cls' not in kwargs: if 'cls' not in kwargs:
kwargs['cls'] = JsonEncoder kwargs['cls'] = JsonEncoder

View file

@ -161,11 +161,7 @@ class Request:
except: self.path = path except: self.path = path
if self.raw_query: if self.raw_query:
for qline in unquote_plus(self.raw_query).split('&'): self.query.from_query(self.raw_query)
try: key, value = qline.split('=')
except: key, value = qline, None
self.query[key] = value
else: else:
try: key, value = line.split(': ', 1) try: key, value = line.split(': ', 1)

View file

@ -42,12 +42,12 @@ datetime_formats = {
} }
def boolean(v, return_value=False): def boolean(value, return_value=False):
''' '''
Convert a str, bool, int or None object into a boolean. Convert a str, bool, int or None object into a boolean.
Arguments: Arguments:
v (str, bool, int, None): The value to be checked value (str, bool, int, None): The value to be checked
return_value (bool): If True, return v instead of True if it can't be converted return_value (bool): If True, return v instead of True if it can't be converted
Return: Return:
@ -55,19 +55,19 @@ def boolean(v, return_value=False):
''' '''
if type(v) not in [str, bool, int, type(None)]: if type(value) not in [str, bool, int, type(None)]:
raise ValueError(f'Value is not a string, boolean, int, or nonetype: {value}') raise ValueError(f'Value is not a string, boolean, int, or nonetype: {value}')
value = v.lower() if isinstance(v, str) else v v = value.lower() if isinstance(value, str) else value
if value in [1, True, 'on', 'y', 'yes', 'true', 'enable']: if v in [1, True, 'on', 'y', 'yes', 'true', 'enable']:
return True return True
if value in [0, False, None, 'off', 'n', 'no', 'false', 'disable', '']: if v in [0, False, None, 'off', 'n', 'no', 'false', 'disable', '']:
return False return False
if return_value: if return_value:
return v return value
return True return True
@ -137,16 +137,16 @@ def get_ip():
return ip return ip
def hasher(string, alg='blake2s'): def hasher(data, alg='blake2s'):
''' '''
Hash a string and return the digest in hex format as a string Hash a string or bytes object and return the digest in hex format as a string
Arguments: Arguments:
string (str, bytes): A string or bytes object to be hashed data (str, bytes): A string or bytes object to be hashed
alg (str): The name of algorithm to use for hashing. Check hashlib.__always_supported for valid hash algs alg (str): The name of algorithm to use for hashing. Check hashlib.__always_supported for valid hash algs
Return: Return:
str: The hashed string in hex format as a string str: The hashed data in hex format as a string
''' '''
if alg not in hashlib.algorithms_available: if alg not in hashlib.algorithms_available:
@ -155,10 +155,10 @@ def hasher(string, alg='blake2s'):
if alg in ['sha1', 'md4', 'md5', 'md5-sha1']: if alg in ['sha1', 'md4', 'md5', 'md5-sha1']:
logging.verbose('Warning: Using an insecure hashing algorithm. sha256 or sha512 is recommended') logging.verbose('Warning: Using an insecure hashing algorithm. sha256 or sha512 is recommended')
string = string.encode('UTF-8') if type(string) != bytes else string data = data.encode('UTF-8') if type(string) != bytes else data
newhash = hashlib.new(alg) newhash = hashlib.new(alg)
newhash.update(string) newhash.update(data)
return newhash.hexdigest() return newhash.hexdigest()
@ -343,7 +343,7 @@ def remove(string: str, junk: list):
return string return string
def signal_handler(func=None, *args, original_args=False, **kwargs): def signal_handler(func, *args, original_args=False, **kwargs):
if func: if func:
if original_args: if original_args:
handler = lambda signum, frame: func(signum, frame, *args, **kwargs) handler = lambda signum, frame: func(signum, frame, *args, **kwargs)
@ -473,12 +473,14 @@ class DateString(str):
tz_utc = timezone.utc tz_utc = timezone.utc
tz_local = datetime.now(tz_utc).astimezone().tzinfo tz_local = datetime.now(tz_utc).astimezone().tzinfo
dt = None dt = None
format = None
def __init__(self, string, format): def __init__(self, string, format):
assert format in datetime_formats assert format in datetime_formats
self.dt = datetime.strptime(string, datetime_formats[format]).replace(tzinfo=self.tz_utc) self.dt = datetime.strptime(string, datetime_formats[format]).replace(tzinfo=self.tz_utc)
self.format = format
def __new__(cls, string, format): def __new__(cls, string, format):
@ -518,15 +520,16 @@ class DateString(str):
@property @property
def utc(self): def utc(self):
return self.dt.astimezone(self.tz_utc) return DateString.from_datetime(self.dt.astimezone(self.tz_utc), self.format)
@property @property
def local(self): def local(self):
return self.dt.astimezone(self.tz_local) return DateString.from_datetime(self.dt.astimezone(self.tz_local), self.format)
def dump_to_string(self, format): def dump_to_string(self, format=None):
if not format: format = self.format
assert format in datetime_formats assert format in datetime_formats
return self.dt.strftime(datetime_formats[format]) return self.dt.strftime(datetime_formats[format])
@ -542,11 +545,26 @@ class Url(str):
def __init__(self, url): def __init__(self, url):
parsed = urlparse(url) parsed = urlparse(url)
self.__parsed = parsed
self.proto = parsed.scheme self.proto = parsed.scheme
self.host = parsed.netloc self.host = parsed.netloc
self.port = self.protocols.get(self.proto) if not parsed.port else None
self.path = parsed.path self.path = parsed.path
self.query = parsed.query self.query_string = parsed.query
self.query = DotDict.new_from_query_string(parsed.query)
self.username = parsed.username self.username = parsed.username
self.password = parsed.password self.password = parsed.password
self.port = self.protocols.get(self.proto) if not parsed.port else None self.anchor = parsed.fragment
@property
def dict(self):
return DotDict(
proto = self.proto,
host = self.host,
port = self.port,
path = self.path,
query_string = self.query_string,
query = self.query,
username = self.username,
password = self.password
)