1import functools 2from .obj_dic import DotDict 3 4 5allowed_fields = [ 6 "description", 7 "nres", 8 "code", 9 "chars", 10 "lines", 11 "words", 12 "md5", 13 "l", 14 "h", 15 "w", 16 "c", 17 "history", 18 "plugins", 19 "url", 20 "content", 21 "history.url", 22 "history.method", 23 "history.scheme", 24 "history.host", 25 "history.content", 26 "history.raw_content" "history.is_path", 27 "history.pstrip", 28 "history.cookies", 29 "history.headers", 30 "history.params", 31 "r", 32 "r.reqtime", 33 "r.url", 34 "r.method", 35 "r.scheme", 36 "r.host", 37 "r.content", 38 "r.raw_content" "r.is_path", 39 "r.pstrip", 40 "r.cookies.", 41 "r.headers.", 42 "r.params.", 43] 44 45 46def _check_allowed_field(attr): 47 if [field for field in allowed_fields if attr.startswith(field)]: 48 return True 49 return False 50 51 52def _get_alias(attr): 53 attr_alias = { 54 "l": "lines", 55 "h": "chars", 56 "w": "words", 57 "c": "code", 58 "r": "history", 59 } 60 61 if attr in attr_alias: 62 return attr_alias[attr] 63 64 return attr 65 66 67def rsetattr(obj, attr, new_val, operation): 68 # if not _check_allowed_field(attr): 69 # raise AttributeError("Unknown field {}".format(attr)) 70 71 pre, _, post = attr.rpartition(".") 72 73 pre_post = None 74 if len(attr.split(".")) > 3: 75 pre_post = post 76 pre, _, post = pre.rpartition(".") 77 78 post = _get_alias(post) 79 80 try: 81 obj_to_set = rgetattr(obj, pre) if pre else obj 82 prev_val = rgetattr(obj, attr) 83 if pre_post is not None: 84 prev_val = DotDict({pre_post: prev_val}) 85 86 if operation is not None: 87 val = operation(prev_val, new_val) 88 else: 89 if isinstance(prev_val, DotDict): 90 val = {k: new_val for k, v in prev_val.items()} 91 else: 92 val = new_val 93 94 return setattr(obj_to_set, post, val) 95 except AttributeError: 96 raise AttributeError( 97 "rsetattr: Can't set '{}' attribute of {}.".format( 98 post, obj_to_set.__class__ 99 ) 100 ) 101 102 103def rgetattr(obj, attr, *args): 104 def _getattr(obj, attr): 105 attr = _get_alias(attr) 106 try: 107 return getattr(obj, attr, *args) 108 except AttributeError: 109 raise AttributeError( 110 "rgetattr: Can't get '{}' attribute from '{}'.".format( 111 attr, obj.__class__ 112 ) 113 ) 114 115 # if not _check_allowed_field(attr): 116 # raise AttributeError("Unknown field {}".format(attr)) 117 118 return functools.reduce(_getattr, [obj] + attr.split(".")) 119