示例#1
0
 def _children_counts(children, session):
     return [(session.query(func.count(GroupEntry.id)).filter(
         GroupEntry.path.descendant_of(child.path)).filter(
             func.nlevel(GroupEntry.path) > len(child.path)).filter(
                 GroupEntry.type == GroupEntryType.game).first()
              if child.type == GroupEntryType.group else (0, ))
             for child in children]
    def get_teams(self, db: Session, *, parent_id: int) -> List[Organization]:
        """returns active sub-organizations (teams) given the parent"""
        # positble alternative: select * from organization o where o.path ~ 'planet.*{1}';

        parent = self.get(db, id=parent_id)

        if not parent:
            return []

        return (db.query(Organization).filter(
            and_(
                func.nlevel(
                    Organization.path) == (func.nlevel(str(parent.path)) + 1),
                Organization.path.descendant_of(parent.path),
                Organization.archived == False,
            )).all())
示例#3
0
    def get_info(uuid, session=None) -> Group:
        if uuid is None:
            current_user = UserManager.get_current_user()
            if current_user is not None:
                peak_nodes = session.query(GroupEntry).filter(
                    GroupEntry.owner == current_user.platformid).filter(
                        func.nlevel(GroupEntry.path) == 1).order_by(
                            GroupEntry.id).all()
                children_counts = SavedGroup._children_counts(
                    peak_nodes, session)
                return Group(None, [], [
                    GroupEntryJSON.create(child, descendants).__dict__
                    for child, (
                        descendants, ) in zip(peak_nodes, children_counts)
                ])
            else:
                raise NotLoggedIn()

        entry = session.query(GroupEntry).filter(
            GroupEntry.uuid == uuid).first()
        children = session.query(GroupEntry).filter(
            GroupEntry.path.descendant_of(entry.path)).order_by(
                GroupEntry.id).filter(
                    func.nlevel(GroupEntry.path) == len(entry.path) + 1).all()
        children_counts = SavedGroup._children_counts(children, session)
        ancestors = session.query(GroupEntry).filter(
            GroupEntry.path.ancestor_of(entry.path)).filter(
                func.nlevel(GroupEntry.path) < len(entry.path)).order_by(
                    func.nlevel(GroupEntry.path)).all()
        return Group(
            GroupEntryJSON.create(entry).__dict__, [
                GroupEntryJSON.create(ancestor).__dict__
                for ancestor in ancestors
            ], [
                GroupEntryJSON.create(child, descendants).__dict__
                for child, (descendants, ) in zip(children, children_counts)
            ])
 def get_root_nodes(self, db: Session) -> Optional[Organization]:
     return db.query(Organization).filter(
         func.nlevel(Organization.path) == 1).all()
示例#5
0
def subdirs(sess, query):
    LOG.debug('subfolders in %s' % query)

    if not query or query == 'root' or query == '/':
        return []
        # handled by from incremental_query
    else:
        if query.startswith('root'):
            query = query[5:]
        query_nodes = query.split('/')

    LOG.debug('Query nodes: %r' % query_nodes)

    # pop the query type off the beginning
    query_types = query_nodes.pop(0).lower()
    query_types = [x.strip() for x in query_types.split(',')]

    # handle flattened queries
    if query_nodes and query_nodes[-1] == "__flat__":
        return []

    stmt = sess.query(Node)

    if 'named_queries' in query_types and not query_nodes:
        # handled by incremental_query
        return []
    elif query_types[0] == 'named_queries':
        # handled by incremental_query
        return []

    num_params = expected_params(query_types)
    if not query_nodes or len(query_nodes) < num_params:
        # todo: query not complete: offer some virtual folders
        output = []
        return output

    parent_uri = '/'.join(query_nodes[num_params:])

    parent_path = uri_to_ltree(parent_uri)
    depth = uri_depth(parent_uri)

    stmt = sess.query(
        distinct(func.subpath(Node.path, 0, depth + 1).label("subpath")))

    stmt = stmt.filter(Node.path.op("<@")(parent_path))
    stmt = stmt.filter(func.nlevel(Node.path) > uri_depth(parent_uri) + 1)

    if len(query_types) == 1 and query_types[0] == 'all':
        return [DummyNode(x[0].rsplit('.')[-1]) for x in stmt]

    # apply all filters in sequence
    for query_type in query_types:
        if query_type == 'date':
            stmt = dated(sess, stmt, parent_uri, query_nodes)

        if query_type == 'rating':
            stmt = rated(stmt, parent_uri, query_nodes)

        if query_type == 'major_mimetype':
            stmt = major_mimetype(stmt, parent_uri, query_nodes)

        if query_type == 'mimetype':
            stmt = mimetype(stmt, parent_uri, query_nodes)

        if query_type == 'aspect_range':
            stmt = aspect_range(stmt, parent_uri, query_nodes)

        if query_type == 'aspect':
            stmt = aspect(stmt, parent_uri, query_nodes)

        if query_type == 'md5':
            stmt = has_md5(stmt, parent_uri, query_nodes)

        if query_type == 'in_path':
            stmt = in_path(stmt, query_nodes)

        if query_type == 'tag':
            stmt = tagged(sess, stmt, parent_uri, query_nodes)

        if query_type == 'tag_group':
            stmt = in_tag_group(sess, stmt, parent_uri, query_nodes)

    return [DummyNode(x[0].rsplit('.', 1)[-1]) for x in stmt]
示例#6
0
 def is_user(cls):
     return func.mod(func.nlevel(cls._path), 2) == 1
示例#7
0
class Node(Base, BasicMixin):
    __tablename__ = "node"
    parent_id = Column(Integer, ForeignKey("node.id"), index=True)
    parent = relationship("Node",
                          backref="children",
                          remote_side="Node.id",
                          lazy="joined")
    _path = Column(LtreeType, server_default="")
    visited_count = Column(Integer, default=1, index=True)
    utterances = relationship("Utterance",
                              secondary="node_utterance",
                              lazy="joined")
    node_utterances = relationship("NodeUtterance", lazy="joined")
    species = Column(String)
    active = Column(Boolean, default=True, index=True)
    path_length = column_property(func.nlevel(_path), deferred=False)

    @hybrid_property
    def is_anonymous(self):
        return any([x.amazon_anonymous for x in self.utterances])

    @hybrid_method
    def recalculate_path(self):
        def recur_parent(node):
            path = [node.id]
            if node.parent:
                return recur_parent(node.parent) + path
            return path

        return recur_parent(self)

    @hybrid_property
    def active_child_count(self):
        return len([x for x in self.children if x.active])

    @active_child_count.expression
    def active_child_count(cls):
        q = aliased(cls)
        return (select([cast(func.count("id"), Float)
                        ]).select_from(q).where(q.parent_id == cls.id).where(
                            q.active.is_(True)).label("child_count"))

    @hybrid_property
    def child_count(self):
        return len(self.children)

    @child_count.expression
    def child_count(cls):
        q = aliased(cls)
        return (select([
            cast(func.count("id"), Float)
        ]).select_from(q).where(q.parent_id == cls.id).label("child_count"))

    @staticmethod
    def calculate_score(rand, visits):
        return (rand * 0.2 * visits) + visits

    @property
    def path(self):
        if self._path:
            return [int(x) for x in str(self._path).split(".")]
        return []

    @path.setter
    def path(self, value):
        if value:
            if type(value) == list:
                self._path = Ltree(".".join(map(str, value)))
            else:
                self._path = Ltree(str(value))

    @hybrid_property
    def is_user(self):
        return len(self._path) % 2 == 1

    @is_user.expression
    def is_user(cls):
        return func.mod(func.nlevel(cls._path), 2) == 1

    @hybrid_property
    def score(self):
        visits = self.visited_count
        return Node.calculate_score(random.random(), visits)

    @score.expression
    def score(cls):
        number_of_visits = cast(cls.visited_count.label("number_of_visits"),
                                Float)
        return Node.calculate_score(func.random(), number_of_visits)

    @hybrid_property
    def is_incoherent(self):
        return any([
            x for x in self.node_utterances
            if x.incoherent_node_utterance_statuses
        ])
示例#8
0
def subdirs(sess, query):
    LOG.debug('subfolders in %s' % query)

    if not query or query == 'root' or query == '/':
        return []
        # handled by from incremental_query
    else:
        if query.startswith('root'):
            query = query[5:]
        query_nodes = query.split('/')

    LOG.debug('Query nodes: %r' % query_nodes)

    # pop the query type off the beginning
    query_types = query_nodes.pop(0).lower()
    query_types = [x.strip() for x in query_types.split(',')]

    # handle flattened queries
    if query_nodes and query_nodes[-1] == "__flat__":
        return []

    stmt = sess.query(Node)

    if 'named_queries' in query_types and not query_nodes:
        # handled by incremental_query
        return []
    elif query_types[0] == 'named_queries':
        # handled by incremental_query
        return []

    num_params = expected_params(query_types)
    if not query_nodes or len(query_nodes) < num_params:
        # todo: query not complete: offer some virtual folders
        output = []
        return output

    parent_uri = '/'.join(query_nodes[num_params:])

    parent_path = uri_to_ltree(parent_uri)
    depth = uri_depth(parent_uri)

    stmt = sess.query(
            distinct(func.subpath(Node.path, 0, depth+1).label("subpath"))
            )

    stmt = stmt.filter( Node.path.op("<@")(parent_path) )
    stmt = stmt.filter( func.nlevel(Node.path) > uri_depth(parent_uri)+1)

    if len(query_types) == 1 and query_types[0] == 'all':
        return [DummyNode(x[0].rsplit('.')[-1]) for x in stmt]

    # apply all filters in sequence
    for query_type in query_types:
        if query_type == 'date':
            stmt = dated(sess, stmt, parent_uri, query_nodes)

        if query_type == 'rating':
            stmt = rated(stmt, parent_uri, query_nodes)

        if query_type == 'major_mimetype':
            stmt = major_mimetype(stmt, parent_uri, query_nodes)

        if query_type == 'mimetype':
            stmt = mimetype(stmt, parent_uri, query_nodes)

        if query_type == 'aspect_range':
            stmt = aspect_range(stmt, parent_uri, query_nodes)

        if query_type == 'aspect':
            stmt = aspect(stmt, parent_uri, query_nodes)

        if query_type == 'md5':
            stmt = has_md5(stmt, parent_uri, query_nodes)

        if query_type == 'in_path':
            stmt = in_path(stmt, query_nodes)

        if query_type == 'tag':
            stmt = tagged(sess, stmt, parent_uri, query_nodes)

        if query_type == 'tag_group':
            stmt = in_tag_group(sess, stmt, parent_uri, query_nodes)

    return [DummyNode(x[0].rsplit('.', 1)[-1]) for x in stmt]
示例#9
0
    session.add(Node(big_cat, parent=big))
for small_wildcat in ("ocelot", "bobcat"):
    session.add(Node(small_wildcat, parent=wild))
for domestic_cat in ("persian", "bengal", "shorthair"):
    session.add(Node(domestic_cat, parent=domestic))

session.flush()

# To retrieve a whole subtree:
whole_subtree = session.query(Node).filter(
    Node.path.descendant_of(domestic.path)).all()
print('Whole subtree:', whole_subtree)
# [domestic, persian, bengal, shorthair]

# Get only the third layer of nodes:
third_layer = session.query(Node).filter(func.nlevel(Node.path) == 3).all()
print('Third layer:', third_layer)
# [wild, domestic, lion, tiger, jaguar]

# Get all the siblings of a node:
shorthair = session.query(Node).filter_by(name="shorthair").one()
siblings = session.query(Node).filter(
    # We can use Python's slice notation on ltree paths:
    Node.path.descendant_of(shorthair.path[:-1]),
    func.nlevel(Node.path) == len(shorthair.path),
    Node.id != shorthair.id,
).all()
print('Siblings of shorthair:', siblings)
# [persian, bengal]

# Using an LQuery to get immediate children of two parent nodes at different depths: