class Document(Persistent): @property def handler(self): return _handler_index[id(self)] def __init__(self): self.notes = BTree() self.subscribers = PersistentList() self.notes[0] = Note(self, 0, {'desc': 'ROOT'}) def create_note(self, props={}, cls=Note, parent_id=0, id=None): if id is None: if self.notes: id = max(self.list_note_ids()) + 1 else: id = 0 if id in self.notes: raise ValueError('Note id "%s" already in use' % id) note = cls(self, id, props) self.notes[id] = note self.notes[parent_id]._children.append(note.id) return note def get_note(self, note_id): return self.notes[note_id] def list_note_ids(self): return self.notes.iterkeys() def list_notes(self): return self.notes.itervalues() def del_note(self, note_id): for child_note_id in self.get_note(note_id)._children: self.del_note(child_note_id) self._cleanup_child_links(note_id) del self.notes[note_id] def subscribe(self, subscriber): self.subscribers.append(subscriber) def _cleanup_child_links(self, note_id): for note in self.list_notes(): if note_id in note._children: note._children.remove(note_id) def dump_notes(self): def generate(): for note in self.list_notes(): note_data = { 'props': dict(note._props), 'children': list(note._children), } yield note.id, note_data return json.dumps(dict(generate())) # TODO: deprecate these methods def abort(self): self.handler.abort() def commit(self): self.handler.commit() def close(self): self.handler.close()
class PersistentOrderedDict(Persistent): ''' This class implements the same interface as the `collections.OrderedDict` class from the standard library, but uses `persistent` data types for Durus support. ''' def __init__(self, items=None): self.key_index = PersistentList() self.data = PersistentDict() if items: for k, v in items: self[k] = v def keys(self): return self.key_index[:] def __setitem__(self, k, v): if k not in self.data: self.key_index.append(k) self.data[k] = v def items(self): return [(k, v) for k, v in self.iteritems()] def iteritems(self): for k in self.key_index: yield k, self.data[k] def values(self): return [v for k, v in self.iteritems()] def get(self, key): return self.data.get(key) def __delitem__(self, key): del self.data[key] i = self.key_index.index(key) del self.key_index[i] def __getitem__(self, key): return self.data[key] def move_to_end(self, key, last=True): assert(key in self) items = [] for k, v in self.items(): if k != key: items.append((k, v)) del self[k] if last: items.append((key, self[key])) del self[key] for k, v in items: self[k] = v def __contains__(self, key): return key in self.data def __len__(self): return len(self.key_index)
def test_nonzero(self): p = PersistentList() assert not p self.root['a'] = p self.connection.commit() p.append(1) assert p assert p._p_is_unsaved()
def nonzero(self): p = PersistentList() assert not p self.root['a'] = p self.connection.commit() p.append(1) assert p assert p._p_is_unsaved()
def test_cmp(self): p = PersistentList(interval(10)) p2 = PersistentList(interval(10)) assert p == p2 assert p == list(p2) assert p <= p2 assert p >= p2 assert not p < p2 assert not p > p2 p.append(3) assert p != p2
def cmp(self): p = PersistentList(interval(10)) p2 = PersistentList(interval(10)) assert p == p2 assert p == list(p2) assert p <= p2 assert p >= p2 assert not p < p2 assert not p > p2 p.append(3) assert p != p2
class Network(OwnedPersistent): _netnode_template = """| +---------------------------------------------+ |--| %-20.20s (%-20.20s) | | +---------------------------------------------+""" # don't touch this def __init__(self, subnet=None, subnetname=None): super(Network, self).__init__() self.name = None self.mask = None self._subnets = PersistentList() self.nodes = PersistentDict() # actually, Interface objects self._gatways = PersistentList() if subnet: self.add_subnet(subnet, subnetname) def __str__(self): s = ["-"*70] sbl = [] sn = [] for subnet, name in self._subnets: sbl.append("%20s" % (subnet,)) sn.append("%20s" % (name,)) s.append(" | ".join(sbl)) s.append(" | ".join(sn)) s.append("-"*70) for node in self.nodes.values(): s.append(self._netnode_template % (node.owner.name, node.owner.__class__.__name__)) return "\n".join(s) def __repr__(self): try: addr, name = self._subnets[0] return "%s(%r, %r)" % (self.__class__.__name__, addr, name) except IndexError: return "%s()" % (self.__class__.__name__) def __getitem__(self, idx): return self._subnets[idx] def __iter__(self): return iter(self._subnets) def add_interface(self, interface): self.nodes[interface.hostname] = interface interface.network = self def del_interface(self, interface): del self.nodes[interface.hostname] interface.network = None def get_interfaces(self): return self.nodes.copy() def get_node(self, hostname): intf = self.nodes[str(hostname)] return intf.owner def add_node(self, netdev): for intf in netdev.interfaces.values(): for subnet, name in self._subnets: if intf.address in subnet: self.nodes[intf.name] = intf intf.network = self return def add_subnet(self, addr, name=None): sn = ipv4.IPv4(addr) sn.host = 0 name = name or sn.cidr() if not self._subnets: # first subnet sets the name and mask self.name = name self.mask = sn.mask self._subnets.append((sn, name)) self._p_note_change() return sn def remove_subnet(self, name): for i, (sn, netname) in enumerate(self._subnets[:]): if netname == name: del self._subnets[i] def get_subnets(self): return list(self._subnets) subnets = property(get_subnets) def __contains__(self, address): if isinstance(address, str): address = ipv4.IPv4(address) for subnet, name in self._subnets: if address in subnet: return True return False
class Network(OwnedPersistent): _netnode_template = """| +---------------------------------------------+ |--| %-20.20s (%-20.20s) | | +---------------------------------------------+""" # don't touch this def __init__(self, subnet=None, subnetname=None): super(Network, self).__init__() self.name = None self.mask = None self._subnets = PersistentList() self.nodes = PersistentDict() # actually, Interface objects self._gatways = PersistentList() if subnet: self.add_subnet(subnet, subnetname) def __str__(self): s = ["-" * 70] sbl = [] sn = [] for subnet, name in self._subnets: sbl.append("%20s" % (subnet, )) sn.append("%20s" % (name, )) s.append(" | ".join(sbl)) s.append(" | ".join(sn)) s.append("-" * 70) for node in self.nodes.values(): s.append(self._netnode_template % (node.owner.name, node.owner.__class__.__name__)) return "\n".join(s) def __repr__(self): try: addr, name = self._subnets[0] return "%s(%r, %r)" % (self.__class__.__name__, addr, name) except IndexError: return "%s()" % (self.__class__.__name__) def __getitem__(self, idx): return self._subnets[idx] def __iter__(self): return iter(self._subnets) def add_interface(self, interface): self.nodes[interface.hostname] = interface interface.network = self def del_interface(self, interface): del self.nodes[interface.hostname] interface.network = None def get_interfaces(self): return self.nodes.copy() def get_node(self, hostname): intf = self.nodes[str(hostname)] return intf.owner def add_node(self, netdev): for intf in netdev.interfaces.values(): for subnet, name in self._subnets: if intf.address in subnet: self.nodes[intf.name] = intf intf.network = self return def add_subnet(self, addr, name=None): sn = ipv4.IPv4(addr) sn.host = 0 name = name or sn.cidr() if not self._subnets: # first subnet sets the name and mask self.name = name self.mask = sn.mask self._subnets.append((sn, name)) self._p_note_change() return sn def remove_subnet(self, name): for i, (sn, netname) in enumerate(self._subnets[:]): if netname == name: del self._subnets[i] def get_subnets(self): return list(self._subnets) subnets = property(get_subnets) def __contains__(self, address): if isinstance(address, str): address = ipv4.IPv4(address) for subnet, name in self._subnets: if address in subnet: return True return False