Beispiel #1
0
def update_user_inbox_for_reminders(uid):
    """
    Updates user's inbox with any reminders that should have arrived
    @param uid: user id
    @return: integer number of new expired reminders
    """
    now = convert_datestruct_to_datetext(localtime())
    reminder_status = CFG_WEBMESSAGE_STATUS_CODE['REMINDER']
    new_status = CFG_WEBMESSAGE_STATUS_CODE['NEW']
    expired_reminders = db.session.query(UserMsgMESSAGE.id_msgMESSAGE).\
        join(UserMsgMESSAGE.message).\
        filter(db.and_(
        UserMsgMESSAGE.id_user_to==uid,
        UserMsgMESSAGE.status.like(reminder_status),
        MsgMESSAGE.received_date<=datetime.now()
        #MsgMESSAGE.received_date<=db.func.current_timestamp()
        )).all()

    if len(expired_reminders):
        filter = db.and_(
            UserMsgMESSAGE.id_user_to == uid,
            UserMsgMESSAGE.id_msgMESSAGE.in_([i for i, in expired_reminders]))

        res = UserMsgMESSAGE.query.filter(filter).\
            update({UserMsgMESSAGE.status: new_status}, synchronize_session='fetch')
        return res
Beispiel #2
0
 def expand(self, id_user):
     """Expands comment beloging to user."""
     CmtCOLLAPSED.query.filter(
         db.and_(CmtCOLLAPSED.id_bibrec == self.id_bibrec,
                 CmtCOLLAPSED.id_cmtRECORDCOMMENT == self.id,
                 CmtCOLLAPSED.id_user == id_user)).delete(
                     synchronize_session=False)
 def _collection_type(type):
     return db.relationship(
         Collection,
         primaryjoin=lambda: db.and_(
             CollectionExternalcollection.id_collection == Collection.id,
             CollectionExternalcollection.type == type),
         backref='_externalcollections_' + str(type))
Beispiel #4
0
class CmtSUBSCRIPTION(db.Model):
    """Represents a CmtSUBSCRIPTION record."""
    __tablename__ = 'cmtSUBSCRIPTION'

    id_bibrec = db.Column(db.MediumInteger(8, unsigned=True),
                          db.ForeignKey(Bibrec.id),
                          nullable=False,
                          primary_key=True)
    id_user = db.Column(db.Integer(15, unsigned=True),
                        db.ForeignKey(User.id),
                        nullable=False,
                        primary_key=True)
    creation_time = db.Column(db.DateTime,
                              nullable=False,
                              server_default='1900-01-01 00:00:00')

    bibrec = db.relationship(Bibrec)
    user = db.relationship(User, backref='comment_subscriptions')
    user_commented_records = db.relationship(
        Bibrec,
        backref='user_comment_subscritions',
        primaryjoin=lambda: db.and_(
            CmtSUBSCRIPTION.id_bibrec == Bibrec.id, CmtSUBSCRIPTION.id_user ==
            current_user.get_id()),
        viewonly=True)
 def translation(self, lang):
     try:
         return db.object_session(self).query(Collectionname).\
             with_parent(self).filter(db.and_(Collectionname.ln == lang,
                 Collectionname.type == 'ln')).first().value
     except:
         return ""
Beispiel #6
0
def delete_all_messages(uid):
    """
    Delete all messages of a user (except reminders)
    @param uid: user id
    @return: the number of messages deleted
    """
    reminder_status = CFG_WEBMESSAGE_STATUS_CODE['REMINDER']
    msg_ids = map(lambda (x, ): x,
              db.session.query(UserMsgMESSAGE.id_msgMESSAGE).\
              filter(db.and_(UserMsgMESSAGE.id_user_to==uid,
                             UserMsgMESSAGE.status!=reminder_status)).all())
    nb_messages = UserMsgMESSAGE.query.\
                  filter(db.and_(UserMsgMESSAGE.id_user_to==uid,
                                 UserMsgMESSAGE.status!=reminder_status)).\
                  delete(synchronize_session=False)
    if len(msg_ids) > 0:
        check_if_need_to_delete_message_permanently(msg_ids)
    return nb_messages
 def title(self):
     try:
         return db.object_session(self).query(LnkENTRYURLTITLE).\
             filter(db.and_(
                 LnkENTRYURLTITLE.url==self.origin_url,
                 LnkENTRYURLTITLE.title<>"",
                 LnkENTRYURLTITLE.broken==0)).first().title
     except:
         return self.origin_url
Beispiel #8
0
def get_all_drafts(user_id):
    drafts = dict(
        db.session.query(
            Workflow.name, db.func.count(db.func.distinct(
                WebDepositDraft.uuid))).join(WebDepositDraft.workflow).filter(
                    db.and_(Workflow.user_id == user_id, Workflow.status !=
                            CFG_WORKFLOW_STATUS.FINISHED)).group_by(
                                Workflow.name).all())

    return drafts
Beispiel #9
0
    def can_perform_action(self, action=None):
        cond = CmtACTIONHISTORY.id_user == self.uid \
            if self.uid > 0 else \
            CmtACTIONHISTORY.client_host == socket.inet_aton(request.remote_addr)

        if action in CFG_WEBCOMMENT_ACTION_CODE:
            cond = db.and_(
                cond, CmtACTIONHISTORY.action_code ==
                CFG_WEBCOMMENT_ACTION_CODE[action])

        return CmtACTIONHISTORY.query.filter(
            CmtACTIONHISTORY.id_cmtRECORDCOMMENT == self.id, cond).\
            count() == 0
Beispiel #10
0
def reset_rec_cache(output_format, get_record, split_by=1000):
    """It either stores or does not store the output_format.

    If CFG_BIBUPLOAD_SERIALIZE_RECORD_STRUCTURE is changed, this function
    will adapt the database to either store or not store the output_format."""

    import sys
    try:
        import cPickle as pickle
    except:
        import pickle
    from itertools import islice
    from invenio.config import CFG_BIBUPLOAD_SERIALIZE_RECORD_STRUCTURE
    from invenio.intbitset import intbitset
    from invenio.bibsched import server_pid, pidfile
    from invenio.sqlalchemyutils import db
    from invenio.bibedit_model import Bibrec, Bibfmt
    pid = server_pid(ping_the_process=False)
    if pid:
        print >> sys.stderr, "ERROR: bibsched seems to run with pid %d, according to %s." % (pid, pidfile)
        print >> sys.stderr, "       Please stop bibsched before running this procedure."
        sys.exit(1)
    if CFG_BIBUPLOAD_SERIALIZE_RECORD_STRUCTURE:
        print ">>> Searching records which need %s cache resetting; this may take a while..." % (output_format, )
        all_recids = intbitset(db.session.query(Bibrec.id).all())
        #TODO: prevent doing all records?
        recids = all_recids
        print ">>> Generating %s cache..." % (output_format, )
        tot = len(recids)
        count = 0
        it = iter(recids)
        while True:
            rec_group = tuple(islice(it, split_by))
            if not len(rec_group):
                break
            Bibfmt.query.filter(db.and_(
                Bibfmt.id_bibrec.in_(rec_group),
                Bibfmt.format == output_format)).delete(synchronize_session=False)
            db.session.commit()
            #TODO: Update the cache or wait for the first access
            map(get_record, rec_group)
            count += len(rec_group)
            print "    ... done records %s/%s" % (count, tot)
            if len(rec_group) < split_by or count >= tot:
                break

        print ">>> %s cache generated successfully." % (output_format, )
    else:
        print ">>> Cleaning %s cache..." % (output_format, )
        Bibfmt.query.filter(Bibfmt.format == output_format).delete(synchronize_session=False)
        db.session.commit()
Beispiel #11
0
def menu():
    uid = current_user.get_id()

    dbquery.update_user_inbox_for_reminders(uid)
    # join: msgMESSAGE -> user_msgMESSAGE, msgMESSAGE -> users
    # filter: all messages from user AND filter form
    # order: sorted by one of the table column
    messages = db.session.query(MsgMESSAGE, UserMsgMESSAGE).\
        join(MsgMESSAGE.user_from, MsgMESSAGE.sent_to_users).\
        filter(db.and_(dbquery.filter_all_messages_from_user(uid))).\
        order_by(db.desc(MsgMESSAGE.received_date)).limit(5)

    #return dict(messages=messages.all())
    return render_template('webmessage_menu.html', messages=messages.all())
Beispiel #12
0
    def __str__(self):
        uid = current_user.get_id()
        dbquery.update_user_inbox_for_reminders(uid)
        unread = db.session.query(db.func.count(UserMsgMESSAGE.id_msgMESSAGE)).\
            filter(db.and_(
                UserMsgMESSAGE.id_user_to == uid,
                UserMsgMESSAGE.status == CFG_WEBMESSAGE_STATUS_CODE['NEW']
            )).scalar()

        out = '<div data-menu="click" data-menu-source="' + url_for('webmessage.menu') + '">'
        out += '<i class="icon-envelope icon-white"></i>'
        if unread:
            out += ' <span class="badge badge-important">%d</span>' % unread
        out += "</div>"
        return out
Beispiel #13
0
def index(sort=False, filter=None):
    uid = current_user.get_id()

    dbquery.update_user_inbox_for_reminders(uid)
    # join: msgMESSAGE -> user_msgMESSAGE, msgMESSAGE -> users
    # filter: all messages from user AND filter form
    # order: sorted by one of the table column
    messages = db.session.query(MsgMESSAGE, UserMsgMESSAGE).\
        join(MsgMESSAGE.user_from, MsgMESSAGE.sent_to_users).\
        filter(db.and_(dbquery.filter_all_messages_from_user(uid), (filter))).\
        order_by(sort)

    return dict(messages=messages.all(),
                nb_messages=dbquery.count_nb_messages(uid),
                no_quota=is_no_quota_user(uid))
            def decorated_function(*args, **kwargs):
                if not model or not columns:
                    return f(*args, **kwargs)
                where = []
                for column, op in columns.iteritems():
                    try:
                        values = request.values.getlist(column)
                        if not values:
                            continue
                        column_keys = column.split('.')
                        if hasattr(model, column_keys[0]):
                            cond = reduce(
                                lambda x, y: getattr(x.property.table.columns,
                                                     y), column_keys[1:],
                                getattr(model, column_keys[0]))
                            current_app.logger.info("Filtering by: %s = %s" % \
                                                    (cond, values))

                            # Multi-values support
                            if len(values) > 0:
                                # Ignore empty values when using start with,
                                # contains or similar.
                                # FIXME: add per field configuration
                                values = [
                                    value for value in values
                                    if len(value) > 0 or filter_empty
                                ]
                                if op == operators.eq:
                                    where.append(db.in_(values))
                                else:
                                    or_list = []
                                    for value in values:
                                        or_list.append(op(cond, value))
                                    where.append(db.or_(*or_list))
                            else:
                                where.append(op(cond, value))
                    except:
                        flash(_("Invalid filtering key '%s'.") % column)
                if form is not None:
                    filter_form = form(request.values)

                    @register_template_context_processor
                    def inject_filter_form():
                        return dict(filter_form=filter_form)

                # Generate ClauseElement for filtered columns.
                kwargs['filter'] = db.and_(*where)
                return f(*args, **kwargs)
    def widget(self):
        uid = current_user.get_id()
        unread = db.session.query(db.func.count(UserMsgMESSAGE.id_msgMESSAGE)).\
            filter(db.and_(
                UserMsgMESSAGE.id_user_to == uid,
                UserMsgMESSAGE.status == CFG_WEBMESSAGE_STATUS_CODE['NEW']
            )).scalar()

        total = db.session.query(db.func.count(UserMsgMESSAGE.id_msgMESSAGE)).\
            filter(
                UserMsgMESSAGE.id_user_to == uid
            ).scalar()

        template = """
{{  _("You have %d new messages out of %d messages.") | format(unread, total) }}
"""
        return render_template_to_string(template,
                                         _from_string=True,
                                         unread=unread,
                                         total=total)
Beispiel #16
0
def unsubscribe(recid=None):
    uid = current_user.get_id()
    if recid is None:
        recid = request.values.getlist('recid', type=int)
    else:
        recid = [recid]
    current_app.logger.info(recid)
    try:
        db.session.query(CmtSUBSCRIPTION).filter(
            db.and_(CmtSUBSCRIPTION.id_bibrec.in_(recid),
                    CmtSUBSCRIPTION.id_user == uid)).delete(
                        synchronize_session=False)
        db.session.commit()
        flash(_('You have been successfully unsubscribed'), 'success')
    except:
        flash(_('You are already unsubscribed'), 'error')
    if len(recid) == 1:
        return redirect(url_for('.comments', recid=recid[0]))
    else:
        return redirect(url_for('.subscriptions'))
 def sent_to_group_names(self, value):
     old_group_names = self.group_names
     self._sent_to_group_names = value
     groups_to_add = set(self.group_names) - set(old_group_names)
     groups_to_del = set(old_group_names) - set(self.group_names)
     if len(groups_to_del):
         to_del = set([u.nickname for u in User.query.\
             join(User.usergroups).filter(
             Usergroup.name.in_(groups_to_del)).\
             all()])-set(self.user_nicks)
         is_to_del = lambda u: u.nickname in to_del
         remove_old = filter(is_to_del, self.recipients)
         for u in remove_old:
             self.recipients.remove(u)
     if len(groups_to_add):
         for u in User.query.join(User.usergroups).filter(
                 db.and_(Usergroup.name.in_(groups_to_add),
                         db.not_(User.nickname.in_(
                             self.user_nicks)))).all():
             if u not in self.recipients:
                 self.recipients.append(u)
Beispiel #18
0
def reviews(recid):
    from invenio.access_control_config import VIEWRESTRCOLL
    from invenio.access_control_mailcookie import \
        mail_cookie_create_authorize_action
    from invenio.webcomment import check_user_can_view_comments
    auth_code, auth_msg = check_user_can_view_comments(current_user, recid)
    if auth_code and current_user.is_guest:
        cookie = mail_cookie_create_authorize_action(
            VIEWRESTRCOLL, {'collection': g.collection})
        url_args = {'action': cookie, 'ln': g.ln, 'referer': request.referrer}
        flash(_("Authorization failure"), 'error')
        return redirect(url_for('webaccount.login', **url_args))
    elif auth_code:
        flash(auth_msg, 'error')
        abort(401)

    comments = CmtRECORDCOMMENT.query.filter(
        db.and_(CmtRECORDCOMMENT.id_bibrec == recid,
                CmtRECORDCOMMENT.in_reply_to_id_cmtRECORDCOMMENT == 0,
                CmtRECORDCOMMENT.star_score > 0)).all()
    return render_template('webcomment_reviews.html', comments=comments)
Beispiel #19
0
def draft_field_get_all(user_id, deposition_type):
    """ Returns a list with values of the field_names specified
        containing all the latest drafts
        of deposition of type=deposition_type
    """

    ## Select drafts with max step from each uuid.
    subquery = \
        db.session.query(WebDepositDraft.uuid,
                         db.func.max(WebDepositDraft.step)). \
        join(WebDepositDraft.workflow).\
        filter(db.and_(Workflow.status != CFG_WORKFLOW_STATUS.FINISHED,
                       Workflow.user_id == user_id,
                       Workflow.name == deposition_type,
                       Workflow.module_name == 'webdeposit')). \
        group_by(WebDepositDraft.uuid)

    drafts = \
        WebDepositDraft.query. \
        filter(db.tuple_(WebDepositDraft.uuid, WebDepositDraft.step).
               in_(subquery)). \
        order_by(db.desc(WebDepositDraft.timestamp)). \
        all()
    return drafts
def index(recid):
    uid = current_user.get_id()
    linkbacks = LnkENTRY.query.filter(
        db.and_(LnkENTRY.id_bibrec == recid,
                LnkENTRY.status == CFG_WEBLINKBACK_STATUS['APPROVED'])).all()
    return render_template('weblinkback_index.html', linkbacks=linkbacks)
 def get_export_formats(cls):
     return cls.query.filter(db.and_(Format.visibility == 1)).order_by(
         Format.name).all()
Beispiel #22
0
 def is_collapsed(self, id_user):
     """Returns true if the comment is collapsed by user."""
     return CmtCOLLAPSED.query.filter(
         db.and_(CmtCOLLAPSED.id_bibrec == self.id_bibrec,
                 CmtCOLLAPSED.id_cmtRECORDCOMMENT == self.id,
                 CmtCOLLAPSED.id_user == id_user)).count() > 0
Beispiel #23
0
def filter_by_user_status(uid, user_status, login_method='INTERNAL'):
    return db.and_(UserUsergroup.id_user == uid,
                   UserUsergroup.user_status == user_status,
                   Usergroup.login_method == login_method)
Beispiel #24
0
def get_export_formats():
    return Format.query.filter(db.and_(
        Format.content_type != 'text/html',
        Format.visibility == 1)
    ).order_by(Format.name).all()
Beispiel #25
0
 def get(self, name):
     s = Session.query.filter(
         db.and_(
             Session.session_key == name,
             Session.session_expiry >= db.func.current_timestamp())).one()
     return s.session_object
 def get_export_formats(cls):
     return cls.query.filter(
         db.and_(Format.content_type != 'text/html',
                 Format.visibility == 1)).order_by(Format.name).all()
class Collection(db.Model):
    """Represents a Collection record."""
    def __repr__(self):
        return "%s(%s)" % (self.__class__.__name__, self.id)

    __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(20), nullable=True, index=True)
    nbrecs = db.Column(db.Integer(10, unsigned=True), server_default='0')
    #FIXME read only!!!
    reclist = db.Column(
        db.PickleType(pickler=IntbitsetPickle(), comparator=IntbitsetCmp))
    _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))

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

    #@cache.memoize(make_name=lambda fname: fname + '::' + g.ln)
    def formatoptions(self):
        if len(self._formatoptions):
            return [dict(f) for f in self._formatoptions]
        else:
            return [{
                'code': 'hb',
                'name': "HTML %s" % g._("brief"),
                'content_type': '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(self._examples_example)

    @property
    def name_ln(self):
        from invenio.search_engine import get_coll_i18nname
        return get_coll_i18nname(self.name, g.ln).decode('utf-8')
        # 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:
        #    return self.name

    @property
    #@cache.memoize(make_name=lambda fname: fname + '::' + g.ln)
    def portalboxes_ln(self):
        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):
        return db.object_session(self).query(Collection).\
            join(Collection.sons).\
            filter(CollectionCollection.id_son == self.id).\
            order_by(db.asc(Collection.nbrecs)).\
            first()

    @property
    #@cache.memoize(make_name=lambda fname: fname + '::' + g.ln)
    def is_restricted(self):
        from invenio.search_engine import collection_restricted_p
        return collection_restricted_p(self.name)

    @property
    def type(self):
        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=OrderedList,
        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=OrderedList,
        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=OrderedList,
        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=OrderedList,
        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,
        #            backref='collection',
        cascade="all, delete, delete-orphan")

    #
    #    externalcollections = association_proxy(
    #        '_externalcollections',
    #        'externalcollection')

    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,
        #backref='collection',
        collection_class=external_collection_mapper,
        cascade="all, delete, delete-orphan")

    # Search options
    _make_field_fieldvalue = lambda type: 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.
        """
        from invenio.search_engine_config import CFG_WEBSEARCH_SEARCH_WITHIN
        default = [('', g._('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_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 self._search_options

    @property
    #@cache.memoize(make_name=lambda fname: fname + '::' + g.ln)
    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

    @property
    #@cache.memoize(make_name=lambda fname: fname + '::' + g.ln)
    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)

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

    portal_boxes_ln = db.relationship(
            lambda: CollectionPortalbox,
            #collection_class=OrderedList,
            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))

    #@db.hybrid_property
    #def externalcollections(self):
    #    return self._externalcollections

    #@externalcollections.setter
    #def externalcollections(self, data):
    #    if isinstance(data, dict):
    #        for k, vals in data.iteritems():
    #            for v in list(vals):
    #                self._externalcollections[k] = v
    #    else:
    #        self._externalcollections = data

    def breadcrumbs(self, builder=None, ln=CFG_SITE_LANG):
        """Retunds breadcrumbs for collection."""
        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 = (self.name_ln, 'search.collection', dict(name=self.name))
        breadcrumbs.append(crumb)
        return breadcrumbs