Beispiel #1
0
class CollectionCollection(db.Model):
    """Represent a CollectionCollection record."""

    __tablename__ = 'collection_collection'
    id_dad = db.Column(db.MediumInteger(9, unsigned=True),
                       db.ForeignKey(Collection.id),
                       primary_key=True)
    id_son = db.Column(db.MediumInteger(9, unsigned=True),
                       db.ForeignKey(Collection.id),
                       primary_key=True)
    type = db.Column(db.Char(1), nullable=False, server_default='r')
    score = db.Column(db.TinyInteger(4, unsigned=True),
                      nullable=False,
                      server_default='0')
    son = db.relationship(
        Collection,
        primaryjoin=id_son == Collection.id,
        backref='dads',
        # FIX
        # collection_class=db.attribute_mapped_collection('score'),
        order_by=db.asc(score))
    dad = db.relationship(Collection,
                          primaryjoin=id_dad == Collection.id,
                          backref='sons',
                          order_by=db.asc(score))
Beispiel #2
0
def mycommunities_ctx():
    """Helper method for return ctx used by many views."""
    return {
        'mycommunities': Community.query.filter_by(
            id_user=current_user.get_id()
        ).order_by(db.asc(Community.title)).all()
    }
Beispiel #3
0
def mycommunities_ctx():
    """Helper method for return ctx used by many views."""
    return {
        'mycommunities':
        Community.query.filter_by(id_user=current_user.get_id()).order_by(
            db.asc(Community.title)).all()
    }
Beispiel #4
0
 def most_specific_dad(self):
     """Most specific dad."""
     return db.object_session(self).query(Collection).\
         join(Collection.sons).\
         filter(CollectionCollection.id_son == self.id).\
         order_by(db.asc(Collection.nbrecs)).\
         first()
Beispiel #5
0
def myprojects():
    myprojects = Project.get_user_projects(current_user).order_by(
        db.asc(Project.title)).all()
    ctx = {
        'myprojects': myprojects,
        'deleteform': DeleteProjectForm(),
    }
    return render_template(
        'projects/myview.html',
        **ctx
    )
Beispiel #6
0
class Collection(db.Model):
    """Represent a Collection record."""
    def __repr__(self):
        """Return class representation."""
        return 'Collection <id: {0.id}, name: {0.name}, dbquery: {0.query}, ' \
               'nbrecs: {0.nbrecs}>'.format(self)

    def __unicode__(self):
        """Unicode."""
        suffix = ' ({0})'.format(_('default')) if self.id == 1 else ''
        return u"{0.id}. {0.name}{1}".format(self, suffix)

    def __str__(self):
        """Str."""
        # TODO it's compatible with python 3?
        return unicode(self).encode('utf-8')

    __tablename__ = 'collection'
    id = db.Column(db.MediumInteger(9, unsigned=True), primary_key=True)
    name = db.Column(db.String(255), unique=True, index=True, nullable=False)
    dbquery = db.Column(db.Text().with_variant(db.Text(20), 'mysql'),
                        nullable=True)

    @property
    def nbrecs(self):
        """Number of records in the collection."""
        from .cache import get_collection_nbrecs
        return get_collection_nbrecs(self.name)

    @property
    def reclist(self):
        """Return hit set with record identifiers."""
        from .cache import get_collection_reclist
        return get_collection_reclist(self.name)

    @property
    def is_hosted(self):
        """Return True if collection is hosted elsewhere."""
        return self.dbquery.startswith('hostedcollection:') if self.dbquery \
            else False

    _names = db.relationship(
        lambda: Collectionname,
        backref='collection',
        collection_class=attribute_mapped_collection('ln_type'),
        cascade="all, delete, delete-orphan")

    names = association_proxy(
        '_names',
        'value',
        creator=lambda k, v: Collectionname(ln_type=k, value=v))
    _boxes = db.relationship(
        lambda: Collectionboxname,
        backref='collection',
        collection_class=attribute_mapped_collection('ln_type'),
        cascade="all, delete, delete-orphan")

    boxes = association_proxy(
        '_boxes',
        'value',
        creator=lambda k, v: Collectionboxname(ln_type=k, value=v))

    _formatoptions = association_proxy('formats', 'format')

    # @cache.memoize(make_name=lambda fname: fname + '::' + g.ln)
    def formatoptions(self):
        """Return list of format options."""
        if len(self._formatoptions):
            return [dict(f) for f in self._formatoptions]
        else:
            return [{
                'code': u'hb',
                'name': _("HTML %(format)s", format=_("brief")),
                'content_type': u'text/html'
            }]

    formatoptions = property(formatoptions)

    _examples_example = association_proxy('_examples', 'example')

    @property
    # @cache.memoize(make_name=lambda fname: fname + '::' + g.ln)
    def examples(self):
        """Return list of example queries."""
        return list(self._examples_example)

    @property
    def name_ln(self):
        """Name ln."""
        from invenio.legacy.search_engine import get_coll_i18nname
        return get_coll_i18nname(self.name,
                                 getattr(g, 'ln', cfg['CFG_SITE_LANG']))
        # Another possible implementation with cache memoize
        # @cache.memoize
        # try:
        #    return db.object_session(self).query(Collectionname).\
        #        with_parent(self).filter(db.and_(Collectionname.ln==g.ln,
        #            Collectionname.type=='ln')).first().value
        # except Exception:
        #    return self.name

    @property
    # @cache.memoize(make_name=lambda fname: fname + '::' + g.ln)
    def portalboxes_ln(self):
        """Get Portalboxes ln."""
        return db.object_session(self).query(CollectionPortalbox).\
            with_parent(self).\
            options(db.joinedload_all(CollectionPortalbox.portalbox)).\
            filter(CollectionPortalbox.ln == g.ln).\
            order_by(db.desc(CollectionPortalbox.score)).all()

    @property
    def most_specific_dad(self):
        """Most specific dad."""
        results = sorted(db.object_session(self).query(Collection).join(
            Collection.sons).filter(
                CollectionCollection.id_son == self.id).all(),
                         key=lambda c: c.nbrecs)
        return results[0] if len(results) else None

    @property
    # @cache.memoize(make_name=lambda fname: fname + '::' + g.ln)
    def is_restricted(self):
        """Return ``True`` if the collection is restricted."""
        from invenio.legacy.search_engine import collection_restricted_p
        return collection_restricted_p(self.name)

    @property
    def type(self):
        """Return relation type."""
        p = re.compile("\d+:.*")
        if self.dbquery is not None and \
                p.match(self.dbquery.lower()):
            return 'r'
        else:
            return 'v'

    _collection_children = db.relationship(
        lambda: CollectionCollection,
        collection_class=ordering_list('score'),
        primaryjoin=lambda: Collection.id == CollectionCollection.id_dad,
        foreign_keys=lambda: CollectionCollection.id_dad,
        order_by=lambda: db.asc(CollectionCollection.score))
    _collection_children_r = db.relationship(
        lambda: CollectionCollection,
        collection_class=ordering_list('score'),
        primaryjoin=lambda: db.and_(
            Collection.id == CollectionCollection.id_dad, CollectionCollection.
            type == 'r'),
        foreign_keys=lambda: CollectionCollection.id_dad,
        order_by=lambda: db.asc(CollectionCollection.score))
    _collection_children_v = db.relationship(
        lambda: CollectionCollection,
        collection_class=ordering_list('score'),
        primaryjoin=lambda: db.and_(
            Collection.id == CollectionCollection.id_dad, CollectionCollection.
            type == 'v'),
        foreign_keys=lambda: CollectionCollection.id_dad,
        order_by=lambda: db.asc(CollectionCollection.score))
    collection_parents = db.relationship(
        lambda: CollectionCollection,
        collection_class=ordering_list('score'),
        primaryjoin=lambda: Collection.id == CollectionCollection.id_son,
        foreign_keys=lambda: CollectionCollection.id_son,
        order_by=lambda: db.asc(CollectionCollection.score))
    collection_children = association_proxy('_collection_children', 'son')
    collection_children_r = association_proxy(
        '_collection_children_r',
        'son',
        creator=lambda son: CollectionCollection(id_son=son.id, type='r'))
    collection_children_v = association_proxy(
        '_collection_children_v',
        'son',
        creator=lambda son: CollectionCollection(id_son=son.id, type='v'))

    _externalcollections = db.relationship(
        lambda: CollectionExternalcollection,
        cascade="all, delete, delete-orphan")

    def _externalcollections_type(type_):
        return association_proxy(
            '_externalcollections_' + str(type_),
            'externalcollection',
            creator=lambda ext: CollectionExternalcollection(
                externalcollection=ext, type=type_))

    externalcollections_0 = _externalcollections_type(0)
    externalcollections_1 = _externalcollections_type(1)
    externalcollections_2 = _externalcollections_type(2)

    externalcollections = db.relationship(
        lambda: CollectionExternalcollection,
        collection_class=external_collection_mapper,
        cascade="all, delete, delete-orphan")

    # Search options
    def _make_field_fieldvalue(type_):
        return db.relationship(
            lambda: CollectionFieldFieldvalue,
            primaryjoin=lambda: db.and_(
                Collection.id == CollectionFieldFieldvalue.id_collection,
                CollectionFieldFieldvalue.type == type_),
            order_by=lambda: CollectionFieldFieldvalue.score)

    _search_within = _make_field_fieldvalue('sew')
    _search_options = _make_field_fieldvalue('seo')

    @property
    # @cache.memoize(make_name=lambda fname: fname + '::' + g.ln)
    def search_within(self):
        """Collect search within options."""
        default = [('', _('any field'))]
        found = [(o.field.code, o.field.name_ln) for o in self._search_within]
        if not found:
            found = [
                (f.name.replace(' ', ''), f.name_ln)
                for f in Field.query.filter(
                    Field.name.in_(cfg['CFG_WEBSEARCH_SEARCH_WITHIN'])).all()
            ]
        return default + sorted(found, key=itemgetter(1))

    @property
    # @cache.memoize(make_name=lambda fname: fname + '::' + g.ln)
    def search_options(self):
        """Return search options."""
        return self._search_options

    @cached_property
    def ancestors(self):
        """Get list of parent collection ids."""
        output = set([self])
        for c in self.dads:
            output |= c.dad.ancestors
        return output

    @cached_property
    def ancestors_ids(self):
        """Get list of parent collection ids."""
        output = intbitset([self.id])
        for c in self.dads:
            ancestors = c.dad.ancestors_ids
            if self.id in ancestors:
                raise
            output |= ancestors
        return output

    @cached_property
    def descendants_ids(self):
        """Get list of child collection ids."""
        output = intbitset([self.id])
        for c in self.sons:
            descendants = c.son.descendants_ids
            if self.id in descendants:
                raise
            output |= descendants
        return output

    # Gets the list of localized names as an array
    collection_names = db.relationship(
        lambda: Collectionname,
        primaryjoin=lambda: Collection.id == Collectionname.id_collection,
        foreign_keys=lambda: Collectionname.id_collection)

    def translation(self, lang):
        """Get the translation according to the language code."""
        try:
            return db.object_session(self).query(Collectionname).\
                with_parent(self).filter(db.and_(
                    Collectionname.ln == lang,
                    Collectionname.type == 'ln'
                )).first().value
        except Exception:
            return ""

    @property
    def sort_methods(self):
        """Get sort methods for collection.

        If not sort methods are defined for a collection the root collections
        sort methods are retuned. If not methods are defined for the root
        collection, all possible sort methods are returned.

        Note: Noth sorting methods and ranking methods are now defined via
        the sorter.
        """
        from invenio.modules.sorter.models import BsrMETHOD, \
            Collection_bsrMETHOD

        for coll_id in (self.id, 1):
            methods = Collection_bsrMETHOD.query.filter_by(
                id_collection=coll_id).order_by(
                    Collection_bsrMETHOD.score).options(
                        db.joinedload(Collection_bsrMETHOD.bsrMETHOD)).all()

            if len(methods) > 0:
                return map(lambda obj: obj.bsrMETHOD, methods)

        return BsrMETHOD.query.order_by(BsrMETHOD.name).all()

    def get_collectionbox_name(self, ln=None, box_type="r"):
        """Return collection-specific labelling subtrees.

        - 'Focus on': regular collection
        - 'Narrow by': virtual collection
        - 'Latest addition': boxes

        If translation for given language does not exist, use label
        for CFG_SITE_LANG. If no custom label is defined for
        CFG_SITE_LANG, return default label for the box.

        :param ln: the language of the label
        :param box_type: can be 'r' (=Narrow by), 'v' (=Focus on),
                         'l' (=Latest additions)
        """
        if ln is None:
            ln = g.ln
        collectionboxnamequery = db.object_session(self).query(
            Collectionboxname).with_parent(self)
        try:
            collectionboxname = collectionboxnamequery.filter(
                db.and_(
                    Collectionboxname.ln == ln,
                    Collectionboxname.type == box_type,
                )).one()
        except Exception:
            try:
                collectionboxname = collectionboxnamequery.filter(
                    db.and_(
                        Collectionboxname.ln == ln,
                        Collectionboxname.type == box_type,
                    )).one()
            except Exception:
                collectionboxname = None

        if collectionboxname is None:
            # load the right message language
            _ = gettext_set_language(ln)
            return _(Collectionboxname.TYPES.get(box_type, ''))
        else:
            return collectionboxname.value

    portal_boxes_ln = db.relationship(
        lambda: CollectionPortalbox,
        collection_class=ordering_list('score'),
        primaryjoin=lambda: Collection.id == CollectionPortalbox.id_collection,
        foreign_keys=lambda: CollectionPortalbox.id_collection,
        order_by=lambda: db.asc(CollectionPortalbox.score))

    def breadcrumbs(self, builder=None, ln=None):
        """Return breadcrumbs for collection."""
        ln = cfg.get('CFG_SITE_LANG') if ln is None else ln
        breadcrumbs = []
        # Get breadcrumbs for most specific dad if it exists.
        if self.most_specific_dad is not None:
            breadcrumbs = self.most_specific_dad.breadcrumbs(builder=builder,
                                                             ln=ln)

        if builder is not None:
            crumb = builder(self)
        else:
            crumb = dict(text=self.name_ln,
                         url=url_for('collections.collection', name=self.name))

        breadcrumbs.append(crumb)
        return breadcrumbs
Beispiel #7
0
 def most_specific_dad(self):
     return db.object_session(self).query(Collection).\
         join(Collection.sons).\
         filter(CollectionCollection.id_son == self.id).\
         order_by(db.asc(Collection.nbrecs)).\
         first()