def diff(self, a, b): detail = {} for diff in dictdiffer.diff(a, b, expand=True): field = diff[1] # Array change. if isinstance(field, list): field = field[0] detail[field] = [ dictdiffer.dot_lookup(a, field), dictdiffer.dot_lookup(b, field), ] return detail
def _compare(self, client): if self._endpoint == 'directions': client_func = client.directions elif self._endpoint == 'isochrones': client_func = client.isochrones elif self._endpoint == 'matrix': client_func = client.distance_matrix else: raise ValueError("{} not a valid endpoint".format(self._endpoint)) # Make actual request and log errors which don't have skip config.yaml values try: resp = client_func(**self.params, validate=False) except Exception as e: error_name = e.__class__.__name__ if client.req.body: params = json.dumps(json.loads(client.req.body)) else: params = client.req.url if self.error_rules.get(error_name) not in ("skip", "raise"): logger.error( "Cycle {}:\n{} threw a {}: {}\nURL: {}\nParams: {}".format( self.cycle, client.base_url, e.__class__.__name__, e, client.req.url, params)) raise e # Compare lookup keys defined in config.yaml # Continue with next key if lookup key doesn't exist (ref. json vs. geojson) values = dict() for lookup in self._endpoint_dict['methods']['differ']: try: values[lookup] = dictdiffer.dot_lookup(resp, lookup) except (KeyError, IndexError): continue return values
def apply(newState): global state # Step 1: create new nodes prevState = state state = newState ddiff = diff(prevState, state) diffs.append(ddiff) for diffi in list(reversed(list(ddiff))): splits = diffi[1].split('.') if isinstance(diffi[1], str) else diffi[1] if diffi[1] == '': if diffi[0] == 'add': addAll(diffi[2]) elif diffi[0] == 'remove': for key,value in diffi[2]: curop = op("/project1/lambda" + key) if curop != None: curop.destroy() elif splits[1] == 'connections': concatname = [str(x) for x in diffi[1] if isinstance(x, str)] diffip = diffi[1] if isinstance(diffi[1], str) or diffi[1] == '' else ".".join(concatname) item = dot_lookup(state, diffip, parent=True) curop = op(getName(splits[0])) if hasattr(curop, 'inputConnectors'): for connector in curop.inputConnectors: connector.disconnect() for i, conn in enumerate(item['connections']): op(getName(conn)).outputConnectors[0].connect(curop.inputConnectors[i]) elif splits[1] == 'parameters': curop = op(getName(splits[0])) if diffi[0] == 'add': for k,v in diffi[2]: addParameter(curop, k, v) elif diffi[0] == 'change': addParameter(curop, splits[2], diffi[2][1]) elif diffi[0] == 'remove': for param in diffi[2]: print("remove") print(param[0]) if(param[0] == 'tx'): curop.par.tx = 0 elif param[0] == 'ty': curop.par.ty = 0 elif param[0] == 'rotate': curop.par.rotate = 0 elif str.startswith(param[0], "name"): curop.pars(param[0])[0].val = "" par = curop.pars(param[0])[0] print("val: " + str(par.val)) if par.val: print("def: " + str(par.default)) par.val = par.default elif splits[1] == 'text': op(getName(splits[0])).text = diffi[2][1] elif splits[1] == 'commands' and diffi[0] == 'add': runCommand(getName(splits[0]), diffi[2][0][1]['command'], diffi[2][0][1]['args'])
def test_list_lookup(self): source = {0: '0'} assert dot_lookup(source, [0]) == '0'
def test_list_lookup(self): source = {0: "0"} assert dot_lookup(source, [0]) == "0"
def _trabbr(self, *path, **kwargs): try: return dot_lookup(self.translations, list(path) + ['abbr']) except KeyError: return kwargs['default'] if 'default' in kwargs else path[-1]
def push(node, changes): dest = dictdiffer.dot_lookup(destination, node, parent=True) \ .setdefault(node, []) for val in changes: dest.append(val)
def change(node, changes): dest = dictdiffer.dot_lookup(destination, node, parent=True) last_node = node.split('.')[-1] _, value = changes dest[last_node] = value
def add(node, changes): for key, value in changes: dictdiffer.dot_lookup(destination, node)[key] = value
def process(self, stream, request): # Ignore failed requests, where a 'post_*' signal was not received. if len(stream) != 2: return head, tail = stream # Publish the most recent instance, except when the record was deleted. data = { 'create': tail, 'update': tail, 'delete': head, }[head.event] # Ignore sender? sender = data.sender.__module__ + '.' + data.sender.__qualname__ for pattern in self.ignore: if pattern.match(sender): return # Loading and serializing the last instance is deferred to as late as # possible, in order to capture all related changes, such as tag and # custom field updates. if data.model is None: data.model = serialize(request, data.sender, data.instance) message = collections.defaultdict( dict, { 'class': data.sender.__name__, 'event': data.event, 'model': data.model, }) # In order for the consumer to easily build a pynetbox record, include # the absolute URL. if data.event != 'delete': try: nested = serialize(request, data.sender, data.instance, 'Nested') if nested and 'url' in nested: message['@url'] = nested['url'] except: pass # Find differences between the first and last models. if data.event == 'update': for change in dictdiffer.diff(head.model, tail.model, expand=True): field = change[1] # Array change. if isinstance(field, list): field = field[0] message['detail'].update({ field: [ dictdiffer.dot_lookup(head.model, field), dictdiffer.dot_lookup(tail.model, field), ] }) return message
def dot_lookup(d, kp): try: v = dictdiffer.dot_lookup(d, list(kp)) except: v = None return v