feat: list traversal improvements with safeTraverse()
translateLinks() also now strips any params (if present) by default
This commit is contained in:
@@ -84,26 +84,64 @@ def getHeaders(caller="proxy"):
|
||||
|
||||
return headers
|
||||
|
||||
def translateLinks(link):
|
||||
def translateLinks(link: str, remove_params: bool = True):
|
||||
|
||||
link = link.replace("https://i.ytimg.com/", config['general']['public_facing_url'])
|
||||
link = link.replace("https://yt3.ggpht.com/", config['general']['public_facing_url'] + "ggpht/")
|
||||
link = link.replace("https://yt3.googleusercontent.com/", config['general']['public_facing_url'] + "guc/")
|
||||
|
||||
# try to remove tracking params
|
||||
if remove_params and "?" in link:
|
||||
link = link[:link.find("?")]
|
||||
|
||||
return link
|
||||
|
||||
def getUptime():
|
||||
return int(time.time()) - starttime
|
||||
|
||||
def safeTraverse(obj: dict, path: list, default=None, quiet: bool = False):
|
||||
"""
|
||||
Traverse dynamic objects with fallback to default values
|
||||
|
||||
This function can take an Ellipsis as part of traversal path,
|
||||
meaning that it will return the object from the list
|
||||
that contains the next key. This has been introduced
|
||||
so that no matter which object in a list holds the relevant
|
||||
model, it will find it (meaning no assumptions are necessary).
|
||||
Kepp in mind that only one ellipsis at a time is supported,
|
||||
thus ["some_key", ..., ..., "some_other_key"] won't work.
|
||||
|
||||
:param obj: Traversed object
|
||||
:type obj: dict
|
||||
:param path: Path which shall be traversed
|
||||
:type path: list
|
||||
:param default: Default value returned on failure
|
||||
:type default: any, None by default
|
||||
:param quiet: Quiet flag
|
||||
:type quiet: bool
|
||||
"""
|
||||
result = obj
|
||||
try:
|
||||
for x in path:
|
||||
#print(f"traversing {result} with respect to {x}")
|
||||
result = result[x]
|
||||
# for every item in path and its position
|
||||
for pos, iterable_key in enumerate(path):
|
||||
# if the key is not an ellipsis, traverse it
|
||||
if iterable_key is not Ellipsis:
|
||||
result = result[iterable_key]
|
||||
# if it is an ellipsis, and there is another key beside it
|
||||
elif pos < len(path) - 1:
|
||||
# then iterate through all of the list contents
|
||||
for list_content in result:
|
||||
# in search of the next traversal key
|
||||
if path[pos + 1] in list_content:
|
||||
result = list_content
|
||||
# show an error message if ellipsis is used incorrectly
|
||||
else:
|
||||
print("error(safeTraverse): Traversal path can't end with an Ellipsis!")
|
||||
raise TypeError()
|
||||
# handle exceptions
|
||||
except (KeyError, TypeError, IndexError):
|
||||
result = default
|
||||
if not quiet: print(f"error reading: {' -> '.join(path)} - returning: {default}")
|
||||
if not quiet: print(f"error reading: {' -> '.join([str(x) for x in path])} - returning: {default}")
|
||||
finally:
|
||||
return result
|
||||
|
||||
|
||||
Reference in New Issue
Block a user