def do_upgrade():
    """ Implement your upgrades here  """
    if not op.has_table('remoteACCOUNT'):
        op.create_table(
            'remoteACCOUNT',
            db.Column('id', db.Integer(display_width=15), nullable=False),
            db.Column('user_id', db.Integer(display_width=15), nullable=False),
            db.Column('client_id', db.String(length=255), nullable=False),
            db.Column('extra_data', db.JSON, nullable=True),
            db.ForeignKeyConstraint(['user_id'], ['user.id'], ),
            db.PrimaryKeyConstraint('id'),
            db.UniqueConstraint('user_id', 'client_id'),
            mysql_charset='utf8',
            mysql_engine='MyISAM'
        )
    else:
        warnings.warn("*** Creation of table 'remoteACCOUNT table skipped!'")

    if not op.has_table('remoteTOKEN'):
        op.create_table(
            'remoteTOKEN',
            db.Column('id_remote_account', db.Integer(display_width=15),
                    nullable=False),
            db.Column('token_type', db.String(length=40), nullable=False),
            db.Column('access_token', db.Text(), nullable=False),
            db.Column('secret', db.Text(), nullable=False),
            db.ForeignKeyConstraint(['id_remote_account'],
                                    ['remoteACCOUNT.id'], ),
            db.PrimaryKeyConstraint('id_remote_account', 'token_type'),
            mysql_charset='utf8',
            mysql_engine='MyISAM'
        )
    else:
        warnings.warn("*** Creation of table 'remoteTOKEN' skipped!'")
示例#2
0
文件: models.py 项目: osub3/invenio
class WebQuery(db.Model):
    """Represent a WebQuery record."""

    __tablename__ = 'query'
    id = db.Column(db.Integer(15, unsigned=True),
                   primary_key=True,
                   autoincrement=True)
    type = db.Column(db.Char(1), nullable=False, server_default='r')
    urlargs = db.Column(db.Text().with_variant(db.Text(100), 'mysql'),
                        nullable=False)
示例#3
0
class BibxxxMixin(utils.TableNameMixin):

    """Mixin for Bibxxx tables."""

    id = db.Column(db.MediumInteger(8, unsigned=True),
                   primary_key=True,
                   autoincrement=True)
    tag = db.Column(db.String(6), nullable=False, index=True,
                    server_default='')
    value = db.Column(
        db.Text().with_variant(db.Text(35), 'mysql'),
        nullable=False)
示例#4
0
class SbmGFILERESULT(db.Model):
    """Represents a SbmGFILERESULT record."""

    __tablename__ = 'sbmGFILERESULT'

    id = db.Column(db.Integer(),
                   nullable=False,
                   primary_key=True,
                   autoincrement=True)
    FORMAT = db.Column(db.Text().with_variant(db.Text(50), 'mysql'),
                       nullable=False)
    RESULT = db.Column(db.Text().with_variant(db.Text(50), 'mysql'),
                       nullable=False)
示例#5
0
class SbmFORMATEXTENSION(db.Model):
    """Represents a SbmFORMATEXTENSION record."""

    __tablename__ = 'sbmFORMATEXTENSION'

    id = db.Column(db.Integer(),
                   nullable=False,
                   primary_key=True,
                   autoincrement=True)
    FILE_FORMAT = db.Column(db.Text().with_variant(mysql.TEXT(50), 'mysql'),
                            nullable=False)
    FILE_EXTENSION = db.Column(db.Text().with_variant(mysql.TEXT(10), 'mysql'),
                               nullable=False)
示例#6
0
def do_upgrade():
    """Implement your upgrades here."""
    if not op.has_table('oauth2CLIENT'):
        op.create_table(
            'oauth2CLIENT',
            db.Column('name', db.String(length=40), nullable=True),
            db.Column('description', db.Text(), nullable=True),
            db.Column('website', URLType(), nullable=True),
            db.Column('user_id', db.Integer(15, unsigned=True), nullable=True),
            db.Column('client_id', db.String(length=255), nullable=False),
            db.Column('client_secret', db.String(length=255), nullable=False),
            db.Column('is_confidential', db.Boolean(), nullable=True),
            db.Column('is_internal', db.Boolean(), nullable=True),
            db.Column('_redirect_uris', db.Text(), nullable=True),
            db.Column('_default_scopes', db.Text(), nullable=True),
            db.ForeignKeyConstraint(['user_id'], ['user.id'], ),
            db.PrimaryKeyConstraint('client_id'),
            mysql_charset='utf8',
            mysql_engine='MyISAM'
        )
    else:
        warnings.warn("*** Creation of table 'oauth2CLIENT' skipped!")

    if not op.has_table('oauth2TOKEN'):
        op.create_table(
            'oauth2TOKEN',
            db.Column('id', db.Integer(15, unsigned=True), autoincrement=True,
                      nullable=False),
            db.Column('client_id', db.String(length=40), nullable=False),
            db.Column('user_id', db.Integer(15, unsigned=True), nullable=True),
            db.Column('token_type', db.String(length=255), nullable=True),
            db.Column('access_token', db.String(length=255), nullable=True),
            db.Column('refresh_token', db.String(length=255), nullable=True),
            db.Column('expires', db.DateTime(), nullable=True),
            db.Column('_scopes', db.Text(), nullable=True),
            db.Column('is_personal', db.Boolean(), nullable=True),
            db.Column('is_internal', db.Boolean(), nullable=True),
            db.ForeignKeyConstraint(
                ['client_id'], ['oauth2CLIENT.client_id'],),
            db.ForeignKeyConstraint(['user_id'], ['user.id'], ),
            db.PrimaryKeyConstraint('id'),
            db.UniqueConstraint('access_token'),
            db.UniqueConstraint('refresh_token'),
            mysql_charset='utf8',
            mysql_engine='MyISAM'
        )
    else:
        warnings.warn("*** Creation of table 'oauth2TOKEN' skipped!")
示例#7
0
class PidLog(db.Model):

    """Audit log of actions happening to persistent identifiers.

    This model is primarily used through PersistentIdentifier.log and rarely
    created manually.
    """

    __tablename__ = 'pidLOG'
    __table_args__ = (
        db.Index('idx_action', 'action'),
    )

    id = db.Column(db.Integer(15, unsigned=True), primary_key=True)
    """Id of persistent identifier entry."""

    id_pid = db.Column(
        db.Integer(15, unsigned=True), db.ForeignKey(PersistentIdentifier.id),
        nullable=True,
    )
    """PID."""

    timestamp = db.Column(db.DateTime(), nullable=False, default=datetime.now)
    """Creation datetime of entry."""

    action = db.Column(db.String(10), nullable=False)
    """Action identifier."""

    message = db.Column(db.Text(), nullable=False)
    """Log message."""

    # Relationship
    pid = db.relationship("PersistentIdentifier", backref="logs")
示例#8
0
class Page(db.Model):
    """Represents a page."""
    __tablename__ = 'pages'

    id = db.Column(db.Integer(15, unsigned=True),
                   nullable=False,
                   primary_key=True,
                   autoincrement=True)
    """Page identifier."""

    url = db.Column(db.String(100), unique=True, nullable=False)
    """Page url."""

    title = db.Column(db.String(200), nullable=True)
    """Page title."""

    content = db.Column(db.Text().with_variant(db.Text(length=2**32 - 2),
                                               'mysql'),
                        nullable=True)
    """Page content. Default is pages/templates/default.html"""

    description = db.Column(db.String(200), nullable=True)
    """Page description."""

    template_name = db.Column(db.String(70), nullable=True)
    """Page template name. Default is cfg["PAGES_DEFAULT_TEMPLATE"]."""

    created = db.Column(db.DateTime(), nullable=False, default=datetime.now)
    """Page creation date."""

    last_modified = db.Column(db.DateTime(),
                              nullable=False,
                              default=datetime.now,
                              onupdate=datetime.now)
    """Page last modification date."""
    def __repr__(self):
        """Page representation.

        Used on Page admin view in inline model.

        :returns: unambiguous page representation.
        """
        return "URL: %s, title: %s" % (self.url, self.title)
示例#9
0
class WtgTAGRecord(db.Model, Serializable):

    """Connection between Tag and Record."""

    __tablename__ = 'wtgTAG_bibrec'
    __public__ = set(['id_tag', 'id_bibrec', 'date_added'])

    # tagTAG.id
    id_tag = db.Column(db.Integer(15, unsigned=True),
                       db.ForeignKey(WtgTAG.id),
                       nullable=False,
                       primary_key=True)

    # Bibrec.id
    id_bibrec = db.Column(db.Integer(15, unsigned=True),
                          db.ForeignKey(Bibrec.id),
                          nullable=False,
                          primary_key=True)

    # Annotation
    annotation = db.Column(
        db.Text(convert_unicode=True),
        default='')

    # Creation date
    date_added = db.Column(db.DateTime,
                           default=datetime.now)

    # Relationships
    tag = db.relationship(WtgTAG,
                          backref=db.backref('records_association',
                                             cascade='all'))

    tag_query = db.relationship(WtgTAG,
                                backref=db.backref('records_association_query',
                                                   cascade='all',
                                                   lazy='dynamic'))

    bibrec = db.relationship(Bibrec,
                             backref=db.backref('tags_association',
                                                cascade='all'))

    bibrec_query = db.relationship(Bibrec,
                                   backref=db.backref('tags_association_query',
                                                      cascade='all',
                                                      lazy='dynamic'))

    def __init__(self, bibrec=None, **kwargs):
        """TODO."""
        super(WtgTAGRecord, self).__init__(**kwargs)

        if bibrec is not None:
            self.bibrec = bibrec
示例#10
0
class Page(db.Model):
    """Represents a page."""

    __tablename__ = 'pages'

    id = db.Column(db.Integer(15, unsigned=True),
                   nullable=False,
                   primary_key=True,
                   autoincrement=True)
    url = db.Column(db.String(100), unique=True, nullable=False)
    title = db.Column(db.String(200), nullable=True)
    content = db.Column(db.Text().with_variant(db.Text(length=2**32 - 2),
                                               'mysql'),
                        nullable=True)
    # Default is pages/templates/default.html
    template_name = db.Column(db.String(70), nullable=True)
    created = db.Column(db.DateTime(), nullable=False, default=datetime.now)
    last_modified = db.Column(db.DateTime(),
                              nullable=False,
                              default=datetime.now,
                              onupdate=datetime.now)
示例#11
0
文件: model.py 项目: cjhak/b2share
class Bib98x(db.Model):
    """Represents a Bib98x record."""
    def __init__(self):
        pass

    __tablename__ = 'bib98x'
    id = db.Column(db.MediumInteger(8, unsigned=True),
                   primary_key=True,
                   autoincrement=True)
    tag = db.Column(db.String(6),
                    nullable=False,
                    index=True,
                    server_default='')
    value = db.Column(db.Text(35), nullable=False, index=True)
def do_upgrade():
    """ Implement your upgrades here  """
    m = db.MetaData(bind=db.engine)
    m.reflect()
    t = db.Table(
        'userCOLLECTION',
        m,
        db.Column('id',
                  db.String(length=100),
                  primary_key=True,
                  nullable=False),
        db.Column('id_user',
                  db.Integer(15, unsigned=True),
                  db.ForeignKey('user.id'),
                  nullable=False),
        db.Column('id_collection',
                  db.MediumInteger(9, unsigned=True),
                  db.ForeignKey('collection.id'),
                  nullable=True),
        db.Column('id_collection_provisional',
                  db.MediumInteger(9, unsigned=True),
                  db.ForeignKey('collection.id'),
                  nullable=True),
        db.Column('id_oairepository',
                  db.MediumInteger(9, unsigned=True),
                  db.ForeignKey('oaiREPOSITORY.id'),
                  nullable=True),
        db.Column('title', db.String(length=255), nullable=False),
        db.Column('description', db.Text(), nullable=False),
        db.Column('page', db.Text(), nullable=False),
        db.Column('curation_policy', db.Text(), nullable=False),
        db.Column('has_logo', db.Boolean(), nullable=False),
        db.Column('created', db.DateTime(), nullable=False),
        db.Column('last_modified', db.DateTime(), nullable=False),
        mysql_engine='MyISAM',
    )
    t.create()
示例#13
0
def do_upgrade():
    op.drop_table(u'wtgTAG_usergroup')

    op.add_column(
        'wtgTAG',
        db.Column('group_access_rights',
                  mysql.INTEGER(display_width=2),
                  nullable=False))

    op.add_column(
        'wtgTAG',
        db.Column('id_usergroup',
                  mysql.INTEGER(display_width=15),
                  server_default='0',
                  nullable=True))
    op.add_column(
        'wtgTAG_bibrec',
        db.Column('annotation', db.Text(convert_unicode=True), nullable=True))
示例#14
0
class UserProfile(db.Model):
    __tablename__ = 'UserProfile'

    """ Fields """
    user_id = db.Column(db.Integer(255, unsigned=True), db.ForeignKey(User.id),
                        nullable=False, primary_key=True,
                        )

    name = db.Column(db.String(length=255),
                     nullable=True, default='',
                     info=dict(
                         label=_("Name"),
                         description=_(''),
                         )
                     )

    institution = db.Column(db.String(length=255),
                            nullable=True, default='',
                            info=dict(
                                label=_("Institution"),
                                description=_(''),
                                )
                            )

    email = db.Column(db.String(length=255),
                      nullable=True, default='',
                      info=dict(
                          label=_("Contact e-mail"),
                          description=_(''),
                          )
                      )

    social_profiles = db.Column(db.String(length=255),
                                nullable=True, default='',
                                info=dict(
                                    label=_("Social networks"),
                                    description=_(''),
                                    )
                                )

    ei_user = db.Column(db.String(length=255),
                        nullable=True, default='',
                        info=dict(
                            label=_("User name"),
                            description=_(''),
                            )
                        )

    ei_pass = db.Column(db.String(length=255),
                        nullable=True, default='',
                        info=dict(
                            label=_("Password"),
                            description=_(''),
                            )
                        )

    user_proxy = db.Column(db.Text(length=10000),
                           nullable=True, default='',)

    csr_priv_key = db.Column(db.Text(length=10000),
                             nullable=True, default='')

    ssh_public_key = db.Column(db.Text(length=2000),
                               nullable=True, default='',
                               info=dict(
                                   label=_("SSH public key"),
                                   description=_('Paste your SSH public key, '
                                                 'it\'s important to copy the '
                                                 'key exactly without adding '
                                                 'newlines or whitespace.'),
                                   )
                               )

    user_db = db.Column(db.String(length=255),
                               nullable=True, default='',
                               info=dict(
                                   label=_("User DB"),
                                   description=_(''),
                                   )
                               )

    pass_db = db.Column(db.String(length=255),
                               nullable=True, default='',
                               info=dict(
                                   label=_("Password DB"),
                                   description=_(''),
                                   )
                               )

    token_onedata = db.Column(db.String(length=255),
                               nullable=True, default='',
                               info=dict(
                                   label=_("OneData token"),
                                   description=_(''),
                                   )
                               )

    created = db.Column(db.DateTime, nullable=False, default=datetime.now)
    modified = db.Column(db.DateTime, nullable=False, default=datetime.now,
                         onupdate=datetime.now)

    """ Relationships """

    user = db.relationship(
        User, backref=db.backref("UserProfile", uselist=False,
                                 cascade="all, delete-orphan"))

    @classmethod
    def create(cls):
        try:
            obj = cls(
                user_id=current_user.get_id(),
            )
            db.session.add(obj)
            db.session.commit()
            # PROFILE CREATE SIGNAL
            return obj
        except IntegrityError as e:
            db.session.rollback()
            raise e
        except Exception as e:
            raise e

    @classmethod
    def get(cls):
        try:
            return cls.query.filter_by(user_id=current_user.get_id()).one()
        except NoResultFound:
            return None

    @classmethod
    def get_or_create(cls):
        instance = cls.get()
        if instance:
            return instance
        else:
            return cls.create()

    def update(self, **data):
        for value in data:
            setattr(self, value, data[value])
        try:
            db.session.commit()
            return self
        except Exception as e:
            raise e
示例#15
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
示例#16
0
class RemoteToken(db.Model):
    """Storage for the access tokens for linked accounts."""

    __tablename__ = 'remoteTOKEN'

    #
    # Fields
    #
    id_remote_account = db.Column(db.Integer(15, unsigned=True),
                                  db.ForeignKey(RemoteAccount.id),
                                  nullable=False,
                                  primary_key=True)
    """Foreign key to account."""

    token_type = db.Column(db.String(40),
                           default='',
                           nullable=False,
                           primary_key=True)
    """Type of token."""

    access_token = db.Column(TextEncryptedType(type_in=db.Text,
                                               key=secret_key),
                             nullable=False)
    """Access token to remote application."""

    secret = db.Column(db.Text(), default='', nullable=False)
    """Used only by OAuth 1."""
    def token(self):
        """Get token as expected by Flask-OAuthlib."""
        return (self.access_token, self.secret)

    def update_token(self, token, secret):
        """Update token with new values."""
        if self.access_token != token or self.secret != secret:
            self.access_token = token
            self.secret = secret
            db.session.commit()

    @classmethod
    def get(cls, user_id, client_id, token_type='', access_token=None):
        """Get RemoteToken for user."""
        args = [
            RemoteAccount.id == RemoteToken.id_remote_account,
            RemoteAccount.user_id == user_id,
            RemoteAccount.client_id == client_id,
            RemoteToken.token_type == token_type,
        ]

        if access_token:
            args.append(RemoteToken.access_token == access_token)

        return cls.query.options(
            db.joinedload('remote_account')).filter(*args).first()

    @classmethod
    def get_by_token(cls, client_id, access_token, token_type=''):
        """Get RemoteAccount object for token."""
        return cls.query.options(db.joinedload('remote_account')).filter(
            RemoteAccount.id == RemoteToken.id_remote_account,
            RemoteAccount.client_id == client_id,
            RemoteToken.token_type == token_type,
            RemoteToken.access_token == access_token,
        ).first()

    @classmethod
    def create(cls,
               user_id,
               client_id,
               token,
               secret,
               token_type='',
               extra_data=None):
        """Create a new access token.

        Creates RemoteAccount as well if it does not exists.
        """
        account = RemoteAccount.get(user_id, client_id)

        if account is None:
            account = RemoteAccount(
                user_id=user_id,
                client_id=client_id,
                extra_data=extra_data or dict(),
            )
            db.session.add(account)

        token = cls(
            token_type=token_type,
            remote_account=account,
            access_token=token,
            secret=secret,
        )
        db.session.add(token)
        db.session.commit()
        return token
示例#17
0
def do_upgrade():
    op.create_table('accreqREQUEST',
                    db.Column('id',
                              db.Integer(display_width=15),
                              nullable=False),
                    db.Column('status', db.String(length=1), nullable=False),
                    db.Column('receiver_user_id',
                              db.Integer(display_width=15),
                              nullable=False),
                    db.Column('sender_user_id',
                              db.Integer(display_width=15),
                              nullable=True),
                    db.Column('sender_full_name',
                              db.String(length=255),
                              nullable=False),
                    db.Column('sender_email',
                              db.String(length=255),
                              nullable=False),
                    db.Column('recid',
                              db.Integer(display_width=15),
                              nullable=False),
                    db.Column('created', db.DateTime(), nullable=False),
                    db.Column('modified', db.DateTime(), nullable=False),
                    db.Column('justification', db.Text(), nullable=False),
                    db.Column('message', db.Text(), nullable=False),
                    db.Column('link_id',
                              db.Integer(display_width=15),
                              nullable=True),
                    db.ForeignKeyConstraint(
                        ['receiver_user_id'],
                        [u'user.id'],
                    ),
                    db.ForeignKeyConstraint(
                        ['sender_user_id'],
                        [u'user.id'],
                    ),
                    db.ForeignKeyConstraint(
                        ['link_id'],
                        [u'accreqLINK.id'],
                    ),
                    db.PrimaryKeyConstraint('id'),
                    mysql_charset='utf8',
                    mysql_engine='MyISAM')
    op.create_index(op.f('ix_accreqREQUEST_created'),
                    'accreqREQUEST', ['created'],
                    unique=False)
    op.create_index(op.f('ix_accreqREQUEST_recid'),
                    'accreqREQUEST', ['recid'],
                    unique=False)
    op.create_index(op.f('ix_accreqREQUEST_status'),
                    'accreqREQUEST', ['status'],
                    unique=False)

    op.create_table('accreqLINK',
                    db.Column('id',
                              db.Integer(display_width=15),
                              nullable=False),
                    db.Column('token', db.Text(), nullable=False),
                    db.Column('owner_user_id',
                              db.Integer(display_width=15),
                              nullable=False),
                    db.Column('created', db.DateTime(), nullable=False),
                    db.Column('expires_at', db.DateTime(), nullable=True),
                    db.Column('revoked_at', db.DateTime(), nullable=True),
                    db.Column('title', db.String(length=255), nullable=False),
                    db.Column('description', db.Text(), nullable=False),
                    db.ForeignKeyConstraint(
                        ['owner_user_id'],
                        [u'user.id'],
                    ),
                    db.PrimaryKeyConstraint('id'),
                    mysql_charset='utf8',
                    mysql_engine='MyISAM')
    op.create_index(op.f('ix_accreqLINK_created'),
                    'accreqLINK', ['created'],
                    unique=False)
    op.create_index(op.f('ix_accreqLINK_revoked_at'),
                    'accreqLINK', ['revoked_at'],
                    unique=False)
示例#18
0
class Client(db.Model):
    """A client is the app which want to use the resource of a user.

    It is suggested that the client is registered by a user on your site, but
    it is not required.

    The client should contain at least these information:

        client_id: A random string
        client_secret: A random string
        client_type: A string represents if it is confidential
        redirect_uris: A list of redirect uris
        default_redirect_uri: One of the redirect uris
        default_scopes: Default scopes of the client

    But it could be better, if you implemented:

        allowed_grant_types: A list of grant types
        allowed_response_types: A list of response types
        validate_scopes: A function to validate scopes
    """

    __tablename__ = 'oauth2CLIENT'

    name = db.Column(
        db.String(40),
        info=dict(label=_('Name'),
                  description=_('Name of application (displayed to users).'),
                  validators=[validators.DataRequired()]))
    """Human readable name of the application."""

    description = db.Column(db.Text(),
                            default=u'',
                            info=dict(
                                label=_('Description'),
                                description=_(
                                    'Optional. Description of the application'
                                    ' (displayed to users).'),
                            ))
    """Human readable description."""

    website = db.Column(
        URLType(),
        info=dict(
            label=_('Website URL'),
            description=_('URL of your application (displayed to users).'),
        ),
        default=u'',
    )

    user_id = db.Column(db.ForeignKey('user.id'))
    """Creator of the client application."""

    client_id = db.Column(db.String(255), primary_key=True)
    """Client application ID."""

    client_secret = db.Column(db.String(255),
                              unique=True,
                              index=True,
                              nullable=False)
    """Client application secret."""

    is_confidential = db.Column(db.Boolean, default=True)
    """Determine if client application is public or not."""

    is_internal = db.Column(db.Boolean, default=False)
    """Determins if client application is an internal application."""

    _redirect_uris = db.Column(db.Text)
    """A newline-separated list of redirect URIs. First is the default URI."""

    _default_scopes = db.Column(db.Text)
    """A space-separated list of default scopes of the client.

    The value of the scope parameter is expressed as a list of space-delimited,
    case-sensitive strings.
    """

    user = db.relationship('User')
    """Relationship to user."""
    @property
    def allowed_grant_types(self):
        """Return allowed grant types."""
        return current_app.config['OAUTH2_ALLOWED_GRANT_TYPES']

    @property
    def allowed_response_types(self):
        """Return allowed response types."""
        return current_app.config['OAUTH2_ALLOWED_RESPONSE_TYPES']

    # def validate_scopes(self, scopes):
    #     return self._validate_scopes

    @property
    def client_type(self):
        """Return client type."""
        if self.is_confidential:
            return 'confidential'
        return 'public'

    @property
    def redirect_uris(self):
        """Return redirect uris."""
        if self._redirect_uris:
            return self._redirect_uris.splitlines()
        return []

    @redirect_uris.setter
    def redirect_uris(self, value):
        """Validate and store redirect URIs for client."""
        if isinstance(value, six.text_type):
            value = value.split("\n")

        value = [v.strip() for v in value]

        for v in value:
            validate_redirect_uri(v)

        self._redirect_uris = "\n".join(value) or ""

    @property
    def default_redirect_uri(self):
        """Return default redirect uri."""
        try:
            return self.redirect_uris[0]
        except IndexError:
            pass

    @property
    def default_scopes(self):
        """List of default scopes for client."""
        if self._default_scopes:
            return self._default_scopes.split(" ")
        return []

    @default_scopes.setter
    def default_scopes(self, scopes):
        """Set default scopes for client."""
        validate_scopes(scopes)
        self._default_scopes = " ".join(set(scopes)) if scopes else ""

    def validate_scopes(self, scopes):
        """Validate if client is allowed to access scopes."""
        try:
            validate_scopes(scopes)
            return True
        except ScopeDoesNotExists:
            return False

    def gen_salt(self):
        """Generate salt."""
        self.reset_client_id()
        self.reset_client_secret()

    def reset_client_id(self):
        """Reset client id."""
        self.client_id = gen_salt(
            current_app.config.get('OAUTH2_CLIENT_ID_SALT_LEN'))

    def reset_client_secret(self):
        """Reset client secret."""
        self.client_secret = gen_salt(
            current_app.config.get('OAUTH2_CLIENT_SECRET_SALT_LEN'))
示例#19
0
class KnwKBRVAL(db.Model):
    """Represent a KnwKBRVAL record."""

    __tablename__ = 'knwKBRVAL'
    m_key = db.Column(db.String(255),
                      nullable=False,
                      primary_key=True,
                      index=True)
    m_value = db.Column(db.Text().with_variant(mysql.TEXT(30), 'mysql'),
                        nullable=False)
    id_knwKB = db.Column(db.MediumInteger(8, unsigned=True),
                         db.ForeignKey(KnwKB.id),
                         nullable=False,
                         server_default='0',
                         primary_key=True)
    kb = db.relationship(
        KnwKB,
        backref=db.backref(
            'kbrvals',
            cascade="all, delete-orphan",
            collection_class=attribute_mapped_collection("m_key")))

    @staticmethod
    def query_kb_mappings(kbid, sortby="to", key="", value="", match_type="s"):
        """Return a list of all mappings from the given kb, ordered by key.

        If key given, give only those with left side (mapFrom) = key.
        If value given, give only those with right side (mapTo) = value.

        :param kb_name: knowledge base name. if "", return all
        :param sortby: the sorting criteria ('from' or 'to')
        :param key: return only entries where key matches this
        :param value: return only entries where value matches this
        :param match_type: s=substring, e=exact, sw=startswith
        """
        # query
        query = KnwKBRVAL.query.filter(KnwKBRVAL.id_knwKB == kbid)
        # filter
        if len(key) > 0:
            if match_type == "s":
                key = "%" + key + "%"
            elif match_type == "sw":
                key = key + "%"
        else:
            key = '%'
        if len(value) > 0:
            if match_type == "s":
                value = "%" + value + "%"
            elif match_type == "sw":
                value = value + "%"
        else:
            value = '%'
        query = query.filter(KnwKBRVAL.m_key.like(key),
                             KnwKBRVAL.m_value.like(value))
        # order by
        if sortby == "from":
            query = query.order_by(KnwKBRVAL.m_key)
        else:
            query = query.order_by(KnwKBRVAL.m_value)
        return query

    def to_dict(self):
        """Return a dict representation of KnwKBRVAL."""
        # FIXME remove 'id' dependency from invenio modules
        return {
            'id': self.m_key + "_" + str(self.id_knwKB),
            'key': self.m_key,
            'value': self.m_value,
            'kbid': self.kb.id if self.kb else None,
            'kbname': self.kb.name if self.kb else None
        }
示例#20
0
class Project(db.Model):
    """
    Represents a project
    """
    __tablename__ = 'project'

    id = db.Column(db.Integer(15, unsigned=True), primary_key=True)
    """Project id"""

    title = db.Column(db.String(length=255), nullable=False, default='')
    """ Project title """

    description = db.Column(db.Text(), nullable=False, default='')
    """ Project short description """

    creation_date = db.Column(db.DateTime(),
                              nullable=False,
                              default=datetime.now)
    """ creation date of the project"""

    modification_date = db.Column(db.DateTime(),
                                  nullable=False,
                                  default=datetime.now)
    """ date of last modification"""

    # collection
    id_collection = db.Column(db.Integer(15, unsigned=True),
                              db.ForeignKey(Collection.id),
                              nullable=True,
                              default=None)
    collection = db.relationship(Collection,
                                 uselist=False,
                                 backref='project',
                                 foreign_keys=[id_collection])

    # owner
    id_user = db.Column(db.Integer(15, unsigned=True),
                        db.ForeignKey(User.id),
                        nullable=False)
    owner = db.relationship(User, backref='projects', foreign_keys=[id_user])

    eresable = db.Column(db.Boolean, nullable=False, default=True)

    # group
    id_group = db.Column(db.Integer(15, unsigned=True),
                         db.ForeignKey(Group.id),
                         nullable=True,
                         default=None)
    group = db.relationship(Group, backref='projects', foreign_keys=[id_group])

    #
    # Collection management
    #
    def get_collection_name(self):
        return '%s-%s' % (cfg['PROJECTS_COLLECTION_PREFIX'], self.id)

    def get_collection_dbquery(self):
        return '%s:%s' % ("980__a", self.get_collection_name())

    def get_project_records(self, record_types=[], public=None, curated=None):
        """ Return all records of this project"""
        from invenio.legacy.search_engine import search_pattern_parenthesised
        from invenio.modules.records.models import Record
        q = ['980__:%s' % self.get_collection_name()]
        if record_types:
            qtypes = ['980__:%s' % t for t in record_types]
            if len(qtypes) > 1:
                q.append('(%s)' % ' OR '.join(qtypes))
            else:
                q.extend(qtypes)
        if public is not None:
            q.append('983__b:%s' % public)
        if curated is not None:
            q.append('983__a:%s' % curated)
        p = (' AND '.join(q))
        recids = search_pattern_parenthesised(p=p)
        records = Record.query.filter(Record.id.in_(recids))
        return records

    def save_collectionname(self, collection, title):
        if collection.id:
            c_name = Collectionname.query.filter_by(
                id_collection=collection.id, ln=CFG_SITE_LANG,
                type='ln').first()
            if c_name:
                update_changed_fields(c_name, dict(value=title))
                return c_name

        c_name = Collectionname(
            collection=collection,
            ln=CFG_SITE_LANG,
            type='ln',
            value=title,
        )
        db.session.add(c_name)
        return c_name

    def save_collectioncollection(self, collection):
        """Create or update CollectionCollection object."""
        dad = Collection.query.filter_by(
            name=cfg['PROJECTS_PARENT_NAME']).first()

        if collection.id:
            c_tree = CollectionCollection.query.filter_by(
                id_dad=dad.id, id_son=collection.id).first()
            if c_tree:
                update_changed_fields(
                    c_tree,
                    dict(type=cfg['PROJECTS_COLLECTION_TYPE'],
                         score=cfg['PROJECTS_COLLECTION_SCORE']))
                return c_tree

        c_tree = CollectionCollection(
            dad=dad,
            son=collection,
            type=cfg['PROJECTS_COLLECTION_TYPE'],
            score=cfg['PROJECTS_COLLECTION_SCORE'],
        )
        db.session.add(c_tree)
        return c_tree

    def save_collectionformat(self, collection):
        """Create or update CollectionFormat object."""
        fmt = Format.query.filter_by(code=cfg['PROJECTS_OUTPUTFORMAT']).first()

        if collection.id:
            c_fmt = CollectionFormat.query.filter_by(
                id_collection=collection.id).first()
            if c_fmt:
                update_changed_fields(c_fmt, dict(id_format=fmt.id, score=1))
                return c_fmt

        c_fmt = CollectionFormat(
            collection=collection,
            id_format=fmt.id,
        )
        db.session.add(c_fmt)
        return c_fmt

    def save_acl(self, c):
        # Role - use Community id, because role name is limited to 32 chars.
        role_name = 'project_role_%s' % self.id
        role = AccROLE.query.filter_by(name=role_name).first()
        if not role:
            rule = 'allow group "%s"\ndeny any' % self.get_group_name()
            role = AccROLE(name=role_name,
                           description='Owner of project %s' % self.title,
                           firerole_def_ser=serialize(
                               compile_role_definition(rule)),
                           firerole_def_src=rule)
            db.session.add(role)

        # Argument
        fields = dict(keyword='collection', value=c.name)
        arg = AccARGUMENT.query.filter_by(**fields).first()
        if not arg:
            arg = AccARGUMENT(**fields)
            db.session.add(arg)

        # Action
        action = AccACTION.query.filter_by(name='viewrestrcoll').first()

        # User role
        alluserroles = UserAccROLE.query.filter_by(role=role).all()
        userrole = None
        if alluserroles:
            # Remove any user which is not the owner
            for ur in alluserroles:
                if ur.id_user == self.id_user:
                    db.session.delete(ur)
                else:
                    userrole = ur

        if not userrole:
            userrole = UserAccROLE(id_user=self.id_user, role=role)
            db.session.add(userrole)

        # Authorization
        auth = AccAuthorization.query.filter_by(role=role,
                                                action=action,
                                                argument=arg).first()
        if not auth:
            auth = AccAuthorization(role=role,
                                    action=action,
                                    argument=arg,
                                    argumentlistid=1)

    def save_collection(self):
        collection_name = self.get_collection_name()
        c = Collection.query.filter_by(name=collection_name).first()
        fields = dict(name=collection_name,
                      dbquery=self.get_collection_dbquery())
        if c:
            update_changed_fields(c, fields)
        else:
            c = Collection(**fields)
            db.session.add(c)
            db.session.commit()
        self.collection = c
        self.save_collectionname(c, self.title)
        self.save_collectioncollection(c)
        self.save_collectionformat(c)
        self.save_acl(c)
        db.session.commit()

    def delete_collection(self):
        if self.collection:
            CollectionFormat.query.filter_by(
                id_collection=self.collection.id).delete()
            Collectionname.query.filter_by(
                id_collection=self.collection.id).delete()
            CollectionCollection.query.filter_by(
                id_son=self.collection.id).delete()
            db.session.delete(self.collection)
            db.session.commit()

    def get_group_name(self):
        return 'project-group-%d' % self.id

    def save_group(self):
        g = self.group
        if not g:
            g = Group.create(self.get_group_name(),
                             description='Group for project %s' % self.id,
                             privacy_policy=PrivacyPolicy.MEMBERS,
                             subscription_policy=SubscriptionPolicy.APPROVAL,
                             is_managed=False,
                             admins=[self.owner])
            g.add_member(self.owner)
            self.group = g
            db.session.commit()

    def is_user_allowed(self, user=None):
        if not user:
            from flask_login import current_user
            user = current_user
        uid = user.get_id()
        groups = user.get('group', [])
        return self.id_user == uid or self.group.name in groups

    def is_empty(self):
        if self.eresable:
            # Ensure project has not records.
            from invenio.legacy.search_engine import search_pattern
            q = '980__:%s' % self.get_collection_name()
            recids = search_pattern(p=q)
            if len(recids) != 0:
                self.eresable = False
                db.session.commit()
                return False
            else:
                return True
        return False

    @classmethod
    def get_project(cls, id):
        try:
            return cls.query.get(int(id))
        except ValueError:
            return None

    @classmethod
    def filter_projects(cls, p, so):
        """Search for projects.

        Helper function which takes from database only those projects which
        match search criteria. Uses parameter 'so' to set projects in the
        correct order.

        Parameter 'page' is introduced to restrict results and return only
        slice of them for the current page. If page == 0 function will return
        all projects that match the pattern.
        """
        query = cls.query
        if p:
            query = query.filter(
                db.or_(
                    cls.id.like("%" + p + "%"),
                    cls.title.like("%" + p + "%"),
                    cls.description.like("%" + p + "%"),
                ))
        if so in cfg['PROJECTS_SORTING_OPTIONS']:
            order = so == 'title' and db.asc or db.desc
            query = query.order_by(order(getattr(cls, so)))
        return query

    @classmethod
    def get_user_projects(cls, user):
        gids = [g.id for g in Group.query_by_uid(user.get_id())]
        return Project.query.filter(Project.id_group.in_(gids))
示例#21
0
class Community(db.Model):
    """Represents a Community.

    A layer around Invenio's collections and portalboxes.
    """

    __tablename__ = 'community'

    #
    # Fields
    #
    id = db.Column(db.String(100), primary_key=True)
    """
    Community identifier used to generate the real collection_identifier
    """

    id_user = db.Column(db.Integer(15, unsigned=True),
                        db.ForeignKey(User.id),
                        nullable=False)
    """ Owner of the community. """

    id_collection = db.Column(db.Integer(15, unsigned=True),
                              db.ForeignKey(Collection.id),
                              nullable=True,
                              default=None)
    """ Invenio collection generated from this community"""

    id_collection_provisional = db.Column(db.Integer(15, unsigned=True),
                                          db.ForeignKey(Collection.id),
                                          nullable=True,
                                          default=None)
    """ Invenio provisional collection generated from this community"""

    id_oairepository = db.Column(db.MediumInteger(9, unsigned=True),
                                 db.ForeignKey(OaiREPOSITORY.id),
                                 nullable=True,
                                 default=None)
    """ OAI Repository set specification """

    title = db.Column(db.String(length=255), nullable=False, default='')
    """ Title of community."""

    description = db.Column(db.Text(), nullable=False, default='')
    """ Short description of community, displayed in portal boxes. """

    page = db.Column(db.Text(), nullable=False, default='')
    """ Long description of community, displayed on an individual page. """

    curation_policy = db.Column(db.Text(), nullable=False, default='')
    """ Curation policy """

    logo_ext = db.Column(db.String(length=5))
    """Logo extension."""

    created = db.Column(db.DateTime(), nullable=False, default=datetime.now)
    """ Creation datetime """

    last_modified = db.Column(db.DateTime(),
                              nullable=False,
                              default=datetime.now,
                              onupdate=datetime.now)
    """ Last modification datetime """

    last_record_accepted = db.Column(db.DateTime(),
                                     nullable=False,
                                     default=datetime(2000, 1, 1, 0, 0, 0))
    """ Last record acceptance datetime"""

    ranking = db.Column(db.Integer(9), nullable=False, default=0)
    """ Ranking of community. Updated by ranking deamon"""

    fixed_points = db.Column(db.Integer(9), nullable=False, default=0)
    """ Points which will be always added to overall score of community"""
    #
    # Relation ships
    #
    owner = db.relationship(User,
                            backref='communities',
                            foreign_keys=[id_user])
    """ Relation to the owner (User) of the community"""

    collection = db.relationship(Collection,
                                 uselist=False,
                                 backref='community',
                                 foreign_keys=[id_collection])
    """ Relationship to collection. """

    collection_provisional = db.relationship(
        Collection,
        uselist=False,
        backref='community_provisional',
        foreign_keys=[id_collection_provisional])
    """Relationship to restricted collection containing uncurated records."""

    oai_set = db.relationship(OaiREPOSITORY,
                              uselist=False,
                              backref='community',
                              foreign_keys=[id_oairepository])
    """Relation to the owner (User) of the community."""

    #
    # Properties
    #
    @property
    def logo_url(self):
        """Get URL to collection logo."""
        if self.logo_ext:
            return url_for('static',
                           filename='media/communities' + '/' + self.id +
                           self.logo_ext)
        else:
            return None

    @property
    def oai_url(self):
        """Get link to OAI-PMH API for this community collection."""
        return "/oai2d?verb=ListRecords&metadataPrefix=oai_dc&set=%s" % (
            self.get_collection_name(), )

    @property
    def community_url(self):
        """Get URL to this community collection."""
        return "/collection/%s" % self.get_collection_name()

    @property
    def community_provisional_url(self):
        """Get URL to this provisional community collection."""
        return "/search?cc=%s" % self.get_collection_name(provisional=True)

    @property
    def upload_url(self):
        """Get direct upload URL."""
        return url_for('webdeposit.index', c=self.id)

    @classmethod
    def from_recid(cls, recid, provisional=False):
        """Get user communities specified in recid."""
        from invenio.legacy.search_engine import get_record
        rec = get_record(recid)
        prefix = "%s-" % (cfg['COMMUNITIES_ID_PREFIX_PROVISIONAL']
                          if provisional else cfg['COMMUNITIES_ID_PREFIX'])

        colls = rec.get('980', [])
        usercomm = []
        for c in colls:
            try:
                # We are only interested in subfield 'a'
                code, val = c[0][0]
                if code == 'a' and val.startswith(prefix):
                    val = val[len(prefix):]
                    u = cls.query.filter_by(id=val).first()
                    if u:
                        usercomm.append(u)
            except IndexError:
                pass
        return usercomm

    @classmethod
    def filter_communities(cls, p, so):
        """Search for communities.

        Helper function which takes from database only those communities which
        match search criteria. Uses parameter 'so' to set communities in the
        correct order.

        Parameter 'page' is introduced to restrict results and return only
        slice of them for the current page. If page == 0 function will return
        all communities that match the pattern.
        """
        query = cls.query
        if p:
            query = query.filter(
                db.or_(
                    cls.id.like("%" + p + "%"),
                    cls.title.like("%" + p + "%"),
                    cls.description.like("%" + p + "%"),
                ))
        if so in cfg['COMMUNITIES_SORTING_OPTIONS']:
            order = so == 'title' and db.asc or db.desc
            query = query.order_by(order(getattr(cls, so)))
        else:
            query = query.order_by(db.desc(cls.ranking))
        return query

    #
    # Utility methods
    #
    def get_collection_name(self, provisional=False):
        """Get a unique collection name identifier."""
        if provisional:
            return "%s-%s" % (cfg['COMMUNITIES_ID_PREFIX_PROVISIONAL'],
                              self.id)
        else:
            return "%s-%s" % (cfg['COMMUNITIES_ID_PREFIX'], self.id)

    def get_title(self, provisional=False):
        """Get collection title."""
        if provisional:
            return "Provisional: %s" % self.title
        else:
            return self.title

    def get_collection_dbquery(self, provisional=False):
        """Get collection query."""
        return "%s:%s" % self.get_query(provisional=provisional)

    def get_query(self, provisional=False):
        """Get tuple (field,value) for search engine query."""
        return ("980__a", self.get_collection_name(provisional=provisional))

    def render_portalbox_bodies(self, templates):
        """Get a list of rendered portal boxes for this user collection."""
        ctx = {
            'community': self,
        }

        return map(lambda t: render_template_to_string(t, **ctx), templates)

    #
    # Curation methods
    #
    def _modify_record(self,
                       recid,
                       test_func,
                       replace_func,
                       include_func,
                       append_colls=[],
                       replace_colls=[]):
        """Generate record a MARCXML file.

        @param test_func: Function to test if a collection id should be changed
        @param replace_func: Function to replace the collection id.
        @param include_func: Function to test if collection should be included
        """
        from invenio.legacy.search_engine import get_record
        rec = get_record(recid)
        newcolls = []
        dirty = False

        try:
            colls = rec['980']
            if replace_colls:
                for c in replace_colls:
                    newcolls.append([('a', c)])
                    dirty = True
            else:
                for c in colls:
                    try:
                        # We are only interested in subfield 'a'
                        code, val = c[0][0]
                        if test_func(code, val):
                            c[0][0] = replace_func(code, val)
                            dirty = True
                        if include_func(code, val):
                            newcolls.append(c[0])
                        else:
                            dirty = True
                    except IndexError:
                        pass
                for c in append_colls:
                    newcolls.append([('a', c)])
                    dirty = True
        except KeyError:
            return False

        if not dirty:
            return False

        rec = {}
        record_add_field(rec, '001', controlfield_value=str(recid))

        for subfields in newcolls:
            record_add_field(rec, '980', subfields=subfields)

        return rec

    def _upload_record(self, rec, pretend=False):
        """Bibupload one record."""
        from invenio.legacy.bibupload.utils import bibupload_record
        if rec is False:
            return None
        if not pretend:
            bibupload_record(
                record=rec,
                file_prefix='community',
                mode='-c',
                opts=[],
                alias="community",
            )
        return rec

    def _upload_collection(self, coll):
        """Bibupload many records."""
        from invenio.legacy.bibupload.utils import bibupload_record
        bibupload_record(
            collection=coll,
            file_prefix='community',
            mode='-c',
            opts=[],
            alias="community",
        )
        return True

    def accept_record(self, recid, pretend=False):
        """Accept a record for inclusion in a community.

        @param recid: Record ID
        """
        expected_id = self.get_collection_name(provisional=True)
        new_id = self.get_collection_name(provisional=False)

        append_colls, replace_colls = signalresult2list(
            pre_curation.send(self,
                              action='accept',
                              recid=recid,
                              pretend=pretend))

        def test_func(code, val):
            return code == 'a' and val == expected_id

        def replace_func(code, val):
            return (code, new_id)

        def include_func(code, val):
            return True

        rec = self._upload_record(self._modify_record(
            recid,
            test_func,
            replace_func,
            include_func,
            append_colls=append_colls,
            replace_colls=replace_colls),
                                  pretend=pretend)

        self.last_record_accepted = datetime.now()
        db.session.commit()
        post_curation.send(self,
                           action='accept',
                           recid=recid,
                           record=rec,
                           pretend=pretend)
        return rec

    def reject_record(self, recid, pretend=False):
        """Reject a record for inclusion in a community.

        @param recid: Record ID
        """
        expected_id = self.get_collection_name(provisional=True)
        new_id = self.get_collection_name(provisional=False)

        append_colls, replace_colls = signalresult2list(
            pre_curation.send(self,
                              action='reject',
                              recid=recid,
                              pretend=pretend))

        def test_func(code, val):
            return False

        def replace_func(code, val):
            return (code, val)

        def include_func(code, val):
            return not (code == 'a' and (val == expected_id or val == new_id))

        rec = self._upload_record(self._modify_record(
            recid,
            test_func,
            replace_func,
            include_func,
            append_colls=append_colls,
            replace_colls=replace_colls),
                                  pretend=pretend)

        post_curation.send(self,
                           action='reject',
                           recid=recid,
                           record=rec,
                           pretend=pretend)
        return rec

    #
    # Data persistence methods
    #
    def save_collectionname(self, collection, title):
        """Create or update Collectionname object."""
        if collection.id:
            c_name = Collectionname.query.filter_by(
                id_collection=collection.id, ln=CFG_SITE_LANG,
                type='ln').first()
            if c_name:
                update_changed_fields(c_name, dict(value=title))
                return c_name

        c_name = Collectionname(
            collection=collection,
            ln=CFG_SITE_LANG,
            type='ln',
            value=title,
        )
        db.session.add(c_name)
        return c_name

    def save_collectiondetailedrecordpagetabs(self, collection):
        """Create or update Collectiondetailedrecordpagetabs object."""
        if collection.id:
            c_tabs = Collectiondetailedrecordpagetabs.query.filter_by(
                id_collection=collection.id).first()
            if c_tabs:
                update_changed_fields(c_tabs,
                                      dict(tabs=cfg['COMMUNITIES_TABS']))
                return c_tabs

        c_tabs = Collectiondetailedrecordpagetabs(
            collection=collection,
            tabs=cfg['COMMUNITIES_TABS'],
        )
        db.session.add(c_tabs)
        return c_tabs

    def save_collectioncollection(self, collection, parent_name):
        """Create or update CollectionCollection object."""
        dad = Collection.query.filter_by(name=parent_name).first()

        if collection.id:
            c_tree = CollectionCollection.query.filter_by(
                id_dad=dad.id, id_son=collection.id).first()
            if c_tree:
                update_changed_fields(
                    c_tree,
                    dict(type=cfg['COMMUNITIES_COLLECTION_TYPE'],
                         score=cfg['COMMUNITIES_COLLECTION_SCORE']))
                return c_tree

        c_tree = CollectionCollection(
            dad=dad,
            son=collection,
            type=cfg['COMMUNITIES_COLLECTION_TYPE'],
            score=cfg['COMMUNITIES_COLLECTION_SCORE'],
        )
        db.session.add(c_tree)
        return c_tree

    def save_collectionformat(self, collection, fmt_str):
        """Create or update CollectionFormat object."""
        fmt = Format.query.filter_by(code=fmt_str).first()

        if collection.id:
            c_fmt = CollectionFormat.query.filter_by(
                id_collection=collection.id).first()
            if c_fmt:
                update_changed_fields(c_fmt, dict(id_format=fmt.id, score=1))
                return c_fmt

        c_fmt = CollectionFormat(
            collection=collection,
            id_format=fmt.id,
        )
        db.session.add(c_fmt)
        return c_fmt

    def save_collectionportalboxes(self, collection, templates):
        """Create or update Portalbox and CollectionPortalbox objects."""
        # Setup portal boxes
        bodies = self.render_portalbox_bodies(templates)
        bodies.reverse()  # Highest score is on the top, so we reverse the list

        objects = []
        if collection.id:
            c_pboxes = CollectionPortalbox.query.filter_by(
                id_collection=collection.id,
                ln=CFG_SITE_LANG,
            ).all()
            if len(c_pboxes) == len(bodies):
                for score, elem in enumerate(zip(c_pboxes, bodies)):
                    c_pbox, body = elem
                    pbox = c_pbox.portalbox
                    update_changed_fields(pbox, dict(body=body))
                    update_changed_fields(
                        c_pbox,
                        dict(score=score,
                             position=cfg['COMMUNITIES_PORTALBOX_POSITION']))
                    objects.append(c_pbox)
                return objects
            else:
                # Either templates where modified or collection portalboxes
                # where modified outside of the UserCollection. In either case,
                # remove existing portalboxes and add new ones.
                for c_pbox in c_pboxes:
                    db.session.delete(c_pbox.portalbox)
                    db.session.delete(c_pbox)

        for score, body in enumerate(bodies):
            p = Portalbox(title='', body=body)
            c_pbox = CollectionPortalbox()
            update_changed_fields(
                c_pbox,
                dict(
                    collection=collection,
                    portalbox=p,
                    ln=CFG_SITE_LANG,
                    position=cfg['COMMUNITIES_PORTALBOX_POSITION'],
                    score=score,
                ))
            db.session.add_all([p, c_pbox])
            objects.append(c_pbox)
        return objects

    def save_oairepository_set(self, provisional=False):
        """Create or update OAI Repository set."""
        collection_name = self.get_collection_name(provisional=provisional)
        (f1, p1) = self.get_query(provisional=provisional)
        fields = dict(setName='%s set' % collection_name,
                      setSpec=collection_name,
                      setDescription=self.description,
                      p1=p1,
                      f1=f1,
                      m1='e',
                      p2='',
                      f2='',
                      m2='',
                      p3='',
                      f3='',
                      m3='',
                      setDefinition='')

        if self.oai_set:
            update_changed_fields(self.oai_set, fields)
        else:
            self.oai_set = OaiREPOSITORY(**fields)
            db.session.add(self.oai_set)

    def save_acl(self, collection_id, collection_name):
        """Create or update authorization.

        Needed for user to view provisional collection.
        """
        # Role - use Community id, because role name is limited to 32 chars.
        role_name = 'coll_%s' % collection_id
        role = AccROLE.query.filter_by(name=role_name).first()
        if not role:
            role = AccROLE(
                name=role_name,
                description='Curators of Community {collection}'.format(
                    collection=collection_name))
            db.session.add(role)

        # Argument
        fields = dict(keyword='collection', value=collection_name)
        arg = AccARGUMENT.query.filter_by(**fields).first()
        if not arg:
            arg = AccARGUMENT(**fields)
            db.session.add(arg)

        # Action
        action = AccACTION.query.filter_by(name='viewrestrcoll').first()

        # User role
        alluserroles = UserAccROLE.query.filter_by(role=role).all()
        userrole = None
        if alluserroles:
            # Remove any user which is not the owner
            for ur in alluserroles:
                if ur.id_user == self.id_user:
                    db.session.delete(ur)
                else:
                    userrole = ur

        if not userrole:
            userrole = UserAccROLE(id_user=self.id_user, role=role)
            db.session.add(userrole)

        # Authorization
        auth = AccAuthorization.query.filter_by(role=role,
                                                action=action,
                                                argument=arg).first()
        if not auth:
            auth = AccAuthorization(role=role,
                                    action=action,
                                    argument=arg,
                                    argumentlistid=1)

    def save_collection(self, provisional=False):
        """Create or update a new collection.

        Including name, tabs, collection tree, collection output formats,
        portalboxes and OAI repository set.
        """
        # Setup collection
        collection_name = self.get_collection_name(provisional=provisional)
        c = Collection.query.filter_by(name=collection_name).first()
        fields = dict(
            name=collection_name,
            dbquery=self.get_collection_dbquery(provisional=provisional))

        if c:
            before_save_collection.send(self,
                                        is_new=True,
                                        provisional=provisional)
            update_changed_fields(c, fields)
        else:
            before_save_collection.send(self,
                                        is_new=False,
                                        provisional=provisional)
            c = Collection(**fields)
            db.session.add(c)
            db.session.commit()
        setattr(self,
                'collection_provisional' if provisional else 'collection', c)

        # Setup OAI Repository
        if provisional:
            self.save_acl(c.id, collection_name)
        else:
            self.save_oairepository_set(provisional=provisional)

        # Setup title, tabs and collection tree
        self.save_collectionname(c, self.get_title(provisional=provisional))
        self.save_collectiondetailedrecordpagetabs(c)
        self.save_collectioncollection(
            c, cfg['COMMUNITIES_PARENT_NAME_PROVISIONAL']
            if provisional else cfg['COMMUNITIES_PARENT_NAME'])

        # Setup collection format is needed
        if not provisional and cfg['COMMUNITIES_OUTPUTFORMAT']:
            self.save_collectionformat(c, cfg['COMMUNITIES_OUTPUTFORMAT'])
        elif provisional and cfg['COMMUNITIES_OUTPUTFORMAT_PROVISIONAL']:
            self.save_collectionformat(
                c, cfg['COMMUNITIES_OUTPUTFORMAT_PROVISIONAL'])

        # Setup portal boxes
        self.save_collectionportalboxes(
            c, cfg['COMMUNITIES_PORTALBOXES_PROVISIONAL']
            if provisional else cfg['COMMUNITIES_PORTALBOXES'])
        db.session.commit()
        after_save_collection.send(self, collection=c, provisional=provisional)

    def save_collections(self):
        """Create restricted and unrestricted collections."""
        before_save_collections.send(self)
        self.save_collection(provisional=False)
        self.save_collection(provisional=True)
        after_save_collections.send(self)

    def delete_record_collection_identifiers(self):
        """Remove collection identifiers from all records."""
        from invenio.legacy.search_engine import search_pattern
        provisional_id = self.get_collection_name(provisional=True)
        normal_id = self.get_collection_name(provisional=False)

        def test_func(code, val):
            return False

        def replace_func(code, val):
            return (code, val)

        def include_func(code, val):
            return not (code == 'a' and
                        (val == provisional_id or val == normal_id))

        coll = []
        for r in search_pattern(p="980__a:%s OR 980__a:%s" %
                                (normal_id, provisional_id)):
            coll.append(
                self._modify_record(r, test_func, replace_func, include_func))

        self._upload_collection(coll)

    def delete_collection(self, provisional=False):
        """Delete all objects related to a single collection."""
        # Most of the logic in this method ought to be moved to a
        # Collection.delete() method.
        c = getattr(self,
                    "collection_provisional" if provisional else "collection")
        collection_name = self.get_collection_name(provisional=provisional)

        before_delete_collection.send(self,
                                      collection=c,
                                      provisional=provisional)

        if c:
            # Delete portal boxes
            for c_pbox in c.portalboxes:
                if c_pbox.portalbox:
                    db.session.delete(c_pbox.portalbox)
                db.session.delete(c_pbox)
            db.session.commit()
            # Delete output formats:
            CollectionFormat.query.filter_by(id_collection=c.id).delete()

            # Delete title, tabs, collection tree
            Collectionname.query.filter_by(id_collection=c.id).delete()
            CollectionCollection.query.filter_by(id_son=c.id).delete()
            Collectiondetailedrecordpagetabs.query.filter_by(
                id_collection=c.id).delete()

        if provisional:
            # Delete ACLs
            AccARGUMENT.query.filter_by(keyword='collection',
                                        value=collection_name).delete()
            role = AccROLE.query.filter_by(name='coll_%s' % c.id).first()
            if role:
                UserAccROLE.query.filter_by(role=role).delete()
                AccAuthorization.query.filter_by(role=role).delete()
                db.session.delete(role)
        else:
            # Delete OAI repository
            if self.oai_set:
                db.session.delete(self.oai_set)

        # Delete collection
        if c:
            db.session.delete(c)
        db.session.commit()
        after_delete_collection.send(self, provisional=provisional)

    def delete_collections(self):
        """Delete collection and all associated objects."""
        before_delete_collections.send(self)
        self.delete_record_collection_identifiers()
        self.delete_collection(provisional=False)
        self.delete_collection(provisional=True)
        after_delete_collections.send(self)

    def __str__(self):
        """Return a string representation of an object."""
        return self.id
示例#22
0
class SbmGFILERESULT(db.Model):
    """Represents a SbmGFILERESULT record."""

    __tablename__ = 'sbmGFILERESULT'
    FORMAT = db.Column(db.Text(50), nullable=False, primary_key=True)
    RESULT = db.Column(db.Text(50), nullable=False, primary_key=True)
示例#23
0
class SbmFORMATEXTENSION(db.Model):
    """Represents a SbmFORMATEXTENSION record."""

    __tablename__ = 'sbmFORMATEXTENSION'
    FILE_FORMAT = db.Column(db.Text(50), nullable=False, primary_key=True)
    FILE_EXTENSION = db.Column(db.Text(10), nullable=False, primary_key=True)
示例#24
0
文件: model.py 项目: cjhak/b2share
class SubmissionMetadata(db.Model):
    """DataCite-based metadata class. Format description is here:
    http://schema.datacite.org/meta/kernel-2.2/doc/DataCite-MetadataKernel_v2.2.pdf
    """
    __tablename__ = 'submission_metadata'
    domain = 'Generic'
    icon = 'icon-question-sign'
    kind = 'domain'
    field_args = {}
    publisher_default = current_app.config.get('CFG_SITE_URL')
    publication_date_now = date.today()
    language_default = 'en'

    id = db.Column(db.Integer, primary_key=True)
    description = db.Column(db.Text(), nullable=False)
    creator = db.Column(db.String(256))
    title = db.Column(db.String(256), nullable=False)
    open_access = db.Column(db.Boolean(), default=True)
    embargo_till = db.Column(db.String(128))

    licence = db.Column(db.String(128))  # note we set licences in __init__
    publisher = db.Column(db.String(128), default=publisher_default)
    publication_date = db.Column('publication_year',
                                 db.Date(),
                                 default=publication_date_now)
    keywords = db.Column(db.String(256))  # split on ,
    discipline = db.Column(db.String(256))

    # optional
    contributors = db.Column(db.String(256))
    # language = db.Column(db.Enum(*babel.core.LOCALE_ALIASES.keys()))
    language = db.Column(db.String(128), default=language_default)
    resource_type = db.Column(
        db.String(256))  # XXX should be extracted to a separate class
    alternate_identifier = db.Column(db.String(256))
    version = db.Column(db.String(128))
    contact_email = db.Column(db.String(256))

    basic_fields = [
        'title',
        'description',
        'creator',
        'open_access',
        'embargo_till',
        'licence',
        'publication_date',
        'keywords',
        'contact_email',
        'discipline',
    ]
    optional_fields = [
        'contributors',
        'resource_type',
        'alternate_identifier',
        'version',
        'publisher',
        'language',
    ]

    # using joined table inheritance for the specific domains
    submission_type = db.Column(db.String(50))
    __mapper_args__ = {
        'polymorphic_identity': 'generic',
        'polymorphic_on': submission_type
    }

    def __repr__(self):
        return '<SubmissionMetadata %s>' % self.id

    def __init__(self):
        self.fieldsets = [(FieldSet("Generic",
                                    basic_fields=self.basic_fields,
                                    optional_fields=self.optional_fields))]
        self.field_args['title'] = {
            'placeholder':
            "Title of the resource",
            'description':
            'The title of the uploaded resource - a name '
            'that indicates the content to be expected.'
        }
        self.field_args['description'] = {
            'description':
            'A more elaborate description of the resource. '
            'Focus on a description of content making it '
            'easy for others to find it and to interpret '
            'its relevance quickly.'
        }
        self.field_args['publisher'] = {
            'value':
            self.publisher_default,
            'description':
            'The entity responsible for making the resource '
            'available, either a person, an organization, or '
            'a service.'
        }
        self.field_args['publication_date'] = {
            'hidden': True,
            'value': self.publication_date_now
            # 'description':
            # 'This is the date that the resource was uploaded and thus '
            # 'being available broadly. Also this date can be extracted '
            # 'automatically.'
        }
        self.field_args['version'] = {
            'placeholder': 'e.g. v1.02',
            'description': 'Denote the version of the resource.'
        }
        self.field_args['licence'] = {
            'description':
            'Specify the license under which this data set '
            'is available to the users (e.g. GPL, Apache v2 '
            'or Commercial). Please use the License Selector '
            'for help and additional information.'
        }
        self.field_args['keywords'] = {
            'placeholder':
            "keyword1, keyword2, ...",
            'cardinality':
            'n',
            'description':
            'A comma separated list of keywords that '
            'characterize the content.'
        }
        self.field_args['open_access'] = {
            'description':
            'Indicate whether the resource is open or '
            'access is restricted. In case of restricted '
            'access the uploaded files will not be public, '
            'however the metadata will be.'
        }
        self.field_args['embargo_till'] = {
            #'placeholder': 'Embargo end date',
            'description':
            'Submitted files are hidden under embargo and will '
            'become accessible the day the embargo ends'
        }
        self.field_args['contributors'] = {
            'placeholder':
            'contributor',
            'cardinality':
            'n',
            'description':
            'A semicolon separated list of all other '
            'contributors. Mention all other persons that '
            'were relevant in the creation of the resource.'
        }
        self.field_args['language'] = {
            'value': self.language_default,
            'description':
            'The name of the language the document is written in.'
        }
        self.field_args['resource_type'] = {
            'data_provide':
            'select',
            'cardinality':
            'n',
            'data_source':
            ['Text', 'Image', 'Video', 'Audio', 'Time-Series', 'Other'],
            'description':
            'Select the type of the resource.'
        }
        self.field_args['alternate_identifier'] = {
            'placeholder':
            'Other reference, such as URI, ISBN, etc.',
            'description':
            'Any kind of other reference such as a URN, URI '
            'or an ISBN number.'
        }
        self.field_args['creator'] = {
            'placeholder': 'author',
            'cardinality': 'n',
            'description': 'The author(s) of the resource.'
        }
        self.field_args['contact_email'] = {
            'placeholder': 'contact email',
            'description': 'Contact email information for this record'
        }
        self.field_args['discipline'] = {
            'data_provide': 'select',
            'cardinality': 'n',
            'data_source':
            [(d[2], ' / '.join(d)) for d in generate_disciplines()],
            'description': 'Select the discipline of the resource.'
        }