diff options
Diffstat (limited to 'src/server/model/graph.py')
| -rw-r--r-- | src/server/model/graph.py | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/server/model/graph.py b/src/server/model/graph.py new file mode 100644 index 00000000..f197921d --- /dev/null +++ b/src/server/model/graph.py @@ -0,0 +1,105 @@ +class Attr_Diff(dict): + """ + Represents a change to note attributes, where nodes can represent + either logical nodes or logical links, and attributes can be added, + changed or removed + + Example: + attr_diff = {'__type_node' : {n_id: {'__attr_write': {'attr_0': 0, + 'attr_1': 'a'}, + '__attr_remove': ['attr_2'] }} + '__type_link' : {l_id: ... } + } + """ + def __init__(self): + self['__type_node'] = {} + self['__type_link'] = {} + + def init_node_attr_diff(self, n_id): + ret = {'__attr_write': {}, + '__attr_remove': []} + self['__type_node'][n_id] = ret + return ret + + @staticmethod + def from_json_dict(json_dict): + ret = Attr_Diff() + for obj_type in ret.keys(): + obj_ad_set = json_dict.get(obj_type) + if None != obj_ad_set: + for o_id, ad in obj_ad_set.items(): + if None != ad.get('__attr_write'): + for k, v in ad['__attr_write'].items(): + ret.add_node_attr_write(o_id, k, v) + if None != ad.get('__attr_remove'): + for k in ad['__attr_remove']: + ret.add_node_attr_rm(o_id, k) + return ret + + @property + def type__node(self): + return self['__type_node'] + + @property + def type__link(self): + return self['__type_link'] + + def add_node_attr_write(self, n_id, attr_name, attr_val): + + assert 'id' != attr_name.lower(), 'Attr_Diff: attempt to write to \'id\' attribute' + + n_attr_diff = self['__type_node'].get(n_id) + if None == n_attr_diff: + n_attr_diff = self.init_node_attr_diff(n_id) + n_attr_diff['__attr_write'][attr_name] = attr_val + + def add_node_attr_rm(self, n_id, attr_name): + n_attr_diff = self['__type_node'].get(n_id) + if None == n_attr_diff: + n_attr_diff = self.init_node_attr_diff(n_id) + n_attr_diff['__attr_remove'].append(attr_name) + + def add_link_attr_write(self, l_id, attr_name, attr_val): + assert False, 'unimplemented' + + def add_link_attr_rm(self, l_id, attr_name): + assert False, 'unimplemented' + +class Topo_Diff(object): + """ + Represents a change to the graph topology + """ + def __init__(self, link_set_rm=[], + node_set_rm=[], + node_set_add=[], + link_set_add=[]): + + self.link_set_rm = link_set_rm + self.node_set_rm = node_set_rm + self.node_set_add = node_set_add + self.link_set_add = link_set_add + + def __str__(self): + return __name__ + ': ' + ', '.join('%s: %s' % (k, v) for k, v in self.__dict__.items()) + + def check_validity(self, topo_diff_dict): + """ + Topo_Diff may represent invalid operations, eg. adding a link while + removing it's end-point - this stub should check for that + """ + pass + + @staticmethod + def from_json_dict(json_dict): + """ + construct from dict - no node/link constructor set must be provided + """ + ret = Topo_Diff() + + # merge keys - this allows constructor argument omission (link_set_rm, + # node_set_rm, etc.) such as when constructing from POST JSON data + for k, _ in ret.__dict__.items(): + v = json_dict.get(k) + if None != v: + ret.__dict__[k] = v + return ret |
