Source

graphalchemy / graphalchemy / models / collectors.py

Full commit
# -*- coding: utf-8 -*-
'''graph model collectors'''

from stuf.utils import lazy

from graphalchemy.core import octopus, join
from graphalchemy.mixins.collectors import NodesMixin

__all__ = ('In', 'Nodes', 'Out')

# settings
conf = octopus.G


class Nodes(NodesMixin):

    '''collection of model nodes'''

    # node collection
    _collection = join(conf.model.collection.node, conf.models)

    @lazy
    def forks(self):
        '''list of nodes forked from this node'''
        fork_link = self._this.C.get('fork_link')
        if fork_link is not None:
            return self._collection(
                self._this, self._model, link_end='start', link=fork_link,
            )

    @lazy
    def versions(self):
        '''list of nodes versioned from this node'''
        version_link = self._this.C.get('version_link')
        if version_link is not None:
            return self._collection(
                self._this, self._model, link_end='start', link=version_link,
            )


class Direction(octopus.context.Thing):

    '''direction definition'''

    # model finder
    _finder = join(conf.model.finder.node, conf.models)
    # node collection
    _nodes = join(conf.model.collection.node, conf.models)

    def __init__(self, model=None, kind=''):
        '''
        init

        @param model: model with direction (default: None)
        @param link: link name
        '''
        super(Direction, self).__init__()
        self.kind = kind
        self.model = model

    def __get__(self, this, that):
        if this is None:
            return self._finder(self.model)
        return self._nodes(this, **self.config)

    @lazy
    def config(self):
        '''configuration for collection'''
        self.model = self._finder(self.model)
        return dict(
            direction=self.direction,
            kind=self.kind,
            link_end=self.link_end,
            model=self.model,
            name=self.model.C.name,
        )


class In(Direction):

    '''incoming direction definition'''

    direction = 'outgoing'
    link_end = 'start'


class Out(Direction):

    '''outgoing direction definition'''

    direction = 'incoming'
    link_end = 'end'