Source

graphalchemy / graphalchemy / direct / elements.py

# -*- coding: utf-8 -*-
'''direct element models'''

from stuf.utils import lazy

from graphalchemy.core import octopus, join
from graphalchemy.mixins.elements import NodeMixin, ElementMixin

__all__ = ('Link', 'Node')
# settings
conf = octopus.G


class Thing(ElementMixin, octopus.process.Thing):

    '''graph object'''

    @staticmethod
    def _link():
        '''link class'''
        return Link


class Link(Thing):

    '''graph link object'''

    def __init__(self, element=None, link=None, this=None, that=None, **kw):
        '''
        init

        @param element: link element (default: None)
        @param link: link kind name (default: None)
        @param this: one node in a link (default: None)
        @param that: another node in a link (default: None)
        '''
        super(Link, self).__init__(element, **kw)
        # link kind name
        self.link = link
        # one end
        self.that = that if that is not None else self._node()(element.end)
        # the other end
        self.this = this if this is not None else self._node()(element.start)

    def __repr__(self):
        return '{0}: {1}'.format(self.kind, super(Link, self).__repr__())

    @lazy
    def end(self):
        '''ending node of link'''
        return self.that if self.direction == 'incoming' else self.this

    @lazy
    def kind(self):
        '''kind of link'''
        return self._lr.kind(self.source)

    @lazy
    def start(self):
        '''starting node of link'''
        return self.this if self.direction == 'incoming' else self.that

    @staticmethod
    def _node():
        '''node class'''
        return Node

    def deep_dump(self):
        '''deep dump link and both nodes'''
        return self.copy(
            end=self.end.deep_dump(),
            id=self.id,
            kind=self.kind,
            start=self.start.deep_dump(),
        )

    def dump(self):
        '''dump link and both nodes'''
        return self.copy(
            end=self.end.dump(),
            id=self.id,
            kind=self.kind,
            start=self.start.dump(),
        )


class Node(NodeMixin, Thing):

    '''graph node object'''

    # direct node collection
    _nodes = join(conf.direct.collector.node, conf.directs)