Exemplo n.º 1
0
class UserFollowers(db.Model):
    """
    User bidirectional following relationships
    """
    __tablename__ = 'user_followers'
    __table_args__ = (db.PrimaryKeyConstraint('user_id', 'follower_id'), )

    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    follower_id = db.Column(db.Integer,
                            db.ForeignKey('user.id'),
                            nullable=False)
    issued_time = db.Column(db.DateTime(), default=func.now())
Exemplo n.º 2
0
class UserStarStory(db.Model):
    """
    User staring on stories
    """
    __tablename__ = 'user_star_story'
    __table_args__ = (db.PrimaryKeyConstraint('user_id', 'story_id'), )

    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True)
    story_id = db.Column(db.String(128),
                         db.ForeignKey('story.id'),
                         nullable=True)
    stared_time = db.Column(db.DateTime(), default=func.now())
Exemplo n.º 3
0
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(200), nullable=False)
    access_token_nonce = db.Column(db.String(8),
                                   nullable=False,
                                   default=generate_access_token_nonce)

    @classmethod
    def get_by_id(cls, user_id):
        return cls.query.filter_by(id=user_id).first()

    @classmethod
    def get_by_email(cls, email):
        return cls.query.filter_by(email=email).first()
Exemplo n.º 4
0
class Publisher(db.Model):
    """
    Publisher database, One-to-Many
    """
    __tablename__ = 'publisher'

    id = db.Column(db.String(128),
                   primary_key=True,
                   default=lambda: uuid.uuid4().hex)
    name = db.Column(db.String(128), nullable=False, unique=True)
    department = db.Column(db.String(128))
    web = db.Column(db.String(1024))
    email = db.Column(db.String(128))
    role = db.Column(db.String(64))
    created = db.Column(db.DateTime(), default=func.now())
    updated = db.Column(db.DateTime(), onupdate=func.now())
    organization_id = db.Column(db.Integer, db.ForeignKey('organization.id'))
    organization = db.relationship('Organization', backref='publishers')

    @classmethod
    def get(cls, publisher_id=None, publisher_name=None, **kwargs):
        if publisher_id is not None:
            publisher = cls.query.filter_by(id=publisher_id).first()
            if publisher is None:
                raise ObjectDoesNotExist('Publisher "%s" does not exists' %
                                         publisher_id)
            return publisher

        if publisher_name is not None:
            publisher = cls.query.filter_by(name=publisher_name).first()
            if publisher is None:
                raise ObjectDoesNotExist('Publisher "%s" does not exists' %
                                         publisher_name)
            return publisher

        if len(kwargs) > 0:
            return cls.query.filter_by(**kwargs).all()

        return None

    @classmethod
    def create(cls, **params):
        """Add a new publisher
        """
        new_publisher = Publisher(**params)
        db.session.add(new_publisher)
        return new_publisher
Exemplo n.º 5
0
class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True, nullable=False)

    user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
    user = db.relationship(User)

    @classmethod
    def get_all(cls):
        return cls.query.all()

    @classmethod
    def get_by_id(cls, category_id):
        return cls.query.filter_by(id=category_id).first()

    @classmethod
    def get_by_name(cls, category_name):
        return cls.query.filter_by(name=category_name).first()

    def save_to_db(self):
        db_session.add(self)
        db_session.commit()
Exemplo n.º 6
0
class Item(db.Model):
    __table_args__ = (db.UniqueConstraint("category_id", "name"), )

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)
    description = db.Column(db.String(250))

    user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
    user = db.relationship(User)

    category_id = db.Column(db.Integer, db.ForeignKey("category.id"))
    category = db.relationship(Category)

    @classmethod
    def get_all_by_category_id(cls, category_id):
        return cls.query.filter_by(category_id=category_id).all()

    @classmethod
    def get_by_id(cls, item_id):
        return cls.query.filter_by(id=item_id).first()

    @classmethod
    def get_by_name(cls, category_id, item_name):
        return cls.query.filter_by(category_id=category_id,
                                   name=item_name).first()

    @classmethod
    def get_latests(cls):
        return cls.query.order_by(cls.id.desc()).limit(5).all()

    def delete(self):
        db_session.delete(self)
        db_session.commit()

    def save_to_db(self):
        db_session.add(self)
        db_session.commit()
Exemplo n.º 7
0
class OAuth2Token(db.Model):
    """
    OAuth2 Access Tokens storage model.
    """

    __tablename__ = 'oauth2_token'

    id = db.Column(db.Integer, primary_key=True)
    client_id = db.Column(
        db.String(length=40),
        db.ForeignKey('oauth2_client.client_id'),
        index=True,
        nullable=False,
    )
    client = db.relationship('OAuth2Client')

    user_id = db.Column(db.ForeignKey('user.id', ondelete='CASCADE'),
                        index=True,
                        nullable=False)
    user = db.relationship('User')

    class TokenTypes(str, enum.Enum):
        # currently only bearer is supported
        Bearer = 'Bearer'

    token_type = db.Column(db.Enum(TokenTypes), nullable=False)

    access_token = db.Column(db.String(length=255),
                             unique=True,
                             nullable=False)
    refresh_token = db.Column(db.String(length=255),
                              unique=True,
                              nullable=True)
    expires = db.Column(db.DateTime, nullable=False)
    scopes = db.Column(ScalarListType(separator=' '), nullable=False)

    @classmethod
    def find(cls, access_token=None, refresh_token=None):
        if access_token:
            return cls.query.filter_by(access_token=access_token).first()
        elif refresh_token:
            return cls.query.filter_by(refresh_token=refresh_token).first()

    def delete(self):
        with db.session.begin():
            db.session.delete(self)
Exemplo n.º 8
0
class Reference(db.Model):
    """
    Reference database, Many-to-One
    """
    __tablename__ = 'reference'

    id = db.Column(db.String(128),
                   primary_key=True,
                   default=lambda: uuid.uuid4().hex)
    dataset_id = db.Column(db.String(128),
                           db.ForeignKey('dataset.id'),
                           nullable=False)
    title = db.Column(db.String(128), nullable=False, unique=True)
    url = db.Column(db.String(1024), nullable=False)
    snapshot = db.Column(db.String(512))
    created = db.Column(db.DateTime(), default=func.now())
    updated = db.Column(db.DateTime(), onupdate=func.now())

    @classmethod
    def get(cls, ref_id=None, ref_title=None, **kwargs):
        if ref_id is not None:
            reference = cls.query.filter_by(id=ref_id).first()
            if reference is None:
                raise ObjectDoesNotExist('Reference "%s" does not exists' %
                                         ref_id)
            return reference

        if ref_title is not None:
            reference = cls.query.filter_by(name=ref_title).first()
            if reference is None:
                raise ObjectDoesNotExist('Reference "%s" does not exists' %
                                         ref_title)
            return reference

        if len(kwargs) > 0:
            return cls.query.filter_by(**kwargs).all()

        return None

    @classmethod
    def create(cls, **params):
        """Add a new reference
        """
        new_ref = Reference(**params)
        db.session.add(new_ref)
        return new_ref
Exemplo n.º 9
0
class Organization(db.Model):
    """
    Database of dataset-publishing organizations, One-to-Many
    """
    __tablename__ = 'organization'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), nullable=False, unique=True)
    email = db.Column(db.String(128))
    web = db.Column(db.String(1024))
    country = db.Column(db.String(28))
    created = db.Column(db.DateTime(), default=func.now())
    updated = db.Column(db.DateTime(), onupdate=func.now())

    @classmethod
    def get(cls, org_id=None, org_name=None, **kwargs):
        if org_id is not None:
            organization = cls.query.filter_by(id=org_id).first()
            if organization is None:
                raise ObjectDoesNotExist('Organization "%s" does not exists' %
                                         org_id)
            return organization

        if org_name is not None:
            organization = cls.query.filter_by(name=org_name).first()
            if organization is None:
                raise ObjectDoesNotExist('Organization "%s" does not exists' %
                                         org_name)
            return organization

        if len(kwargs) > 0:
            return cls.query.filter_by(**kwargs).all()

        return None

    @classmethod
    def create(cls, **params):
        """Add a new Organization
        """
        new_org = Organization(**params)
        db.session.add(new_org)
        return new_org
Exemplo n.º 10
0
class OAuth2Grant(db.Model):
    """
    Intermediate temporary helper for OAuth2 Grants.
    """

    __tablename__ = 'oauth2_grant'

    id = db.Column(db.Integer, primary_key=True)

    user_id = db.Column(db.ForeignKey('user.id', ondelete='CASCADE'),
                        index=True,
                        nullable=False)
    user = db.relationship('User')

    client_id = db.Column(
        db.String(length=40),
        db.ForeignKey('oauth2_client.client_id'),
        index=True,
        nullable=False,
    )
    client = db.relationship('OAuth2Client')

    code = db.Column(db.String(length=255), index=True, nullable=False)

    redirect_uri = db.Column(db.String(length=255), nullable=False)
    expires = db.Column(db.DateTime, nullable=False)

    scopes = db.Column(ScalarListType(separator=' '), nullable=False)

    def delete(self):
        db.session.delete(self)
        db.session.commit()
        return self

    @classmethod
    def find(cls, client_id, code):
        return cls.query.filter_by(client_id=client_id, code=code).first()
Exemplo n.º 11
0
class License(db.Model):
    """
    License database, One-to-Many
    """
    __tablename__ = 'license'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), nullable=False, unique=True)
    url = db.Column(db.String(1024))
    type = db.Column(db.String(64))
    created = db.Column(db.DateTime(), default=func.now())
    updated = db.Column(db.DateTime(), onupdate=func.now())

    @classmethod
    def get(cls, license_id=None, license_name=None, **kwargs):
        if license_id is not None:
            license = cls.query.filter_by(id=license_id).first()
            if license is None:
                raise ObjectDoesNotExist('License "%s" does not exists' %
                                         license_id)
            return license

        if license_name is not None:
            license = cls.query.filter_by(name=license_name).first()
            if license is None:
                raise ObjectDoesNotExist('License "%s" does not exists' %
                                         license_name)
            return license

        if len(kwargs) > 0:
            return cls.query.filter_by(**kwargs).all()

        return None

    @classmethod
    def create(cls, **params):
        """Add a new License
        """
        new_license = License(**params)
        db.session.add(new_license)
        return new_license
Exemplo n.º 12
0
class OAuth2Client(db.Model):
    """
    Model that binds OAuth2 Client ID and Secret to a specific User.
    """

    __tablename__ = 'oauth2_client'

    client_id = db.Column(db.String(length=40), primary_key=True)
    client_secret = db.Column(db.String(length=55), nullable=False)

    user_id = db.Column(db.ForeignKey('user.id', ondelete='CASCADE'),
                        index=True,
                        nullable=False)
    user = db.relationship('User')

    class ClientTypes(str, enum.Enum):
        public = 'public'
        confidential = 'confidential'

    client_type = db.Column(db.Enum(ClientTypes),
                            default=ClientTypes.public,
                            nullable=False)
    redirect_uris = db.Column(ScalarListType(separator=' '),
                              default=[],
                              nullable=False)
    default_scopes = db.Column(ScalarListType(separator=' '), nullable=False)

    @property
    def default_redirect_uri(self):
        redirect_uris = self.redirect_uris
        if redirect_uris:
            return redirect_uris[0]
        return None

    @classmethod
    def find(cls, client_id):
        if not client_id:
            return
        return cls.query.get(client_id)
Exemplo n.º 13
0
class Comment(db.Model):
    """
    Database of user comments on datasets and stories
    """
    __tablename__ = 'comment'

    id = db.Column(db.String(128), primary_key=True, nullable=False)
    comment = db.Column(db.Text, nullable=False)
    target_id = db.Column(db.String(128), nullable=False)
    target_type = db.Column(db.Integer, nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    user = db.relationship('User', backref='comments')
    stars = db.Column(db.Integer, default=0)
    created = db.Column(db.DateTime(), default=func.now())
    updated = db.Column(db.DateTime(), onupdate=func.now())

    @classmethod
    def comment_id(cls):
        return uuid.uuid4().hex

    @classmethod
    def create(cls, user_id, target_id, target_type, comment):
        """
        Create a new comment
        :param user_id: the user id
        :param target_id: the target id
        :param target_type: the target type, as an instance of `CommentType`
        :param comment: comment content
        :return: created comment
        """
        cid = cls.comment_id()
        comment = Comment(id=cid,
                          comment=comment,
                          target_id=target_id,
                          target_type=int(target_type),
                          user_id=user_id)
        db.session.add(comment)
        return comment

    @classmethod
    def get(cls, comment_id=None, **kwargs):
        """Get specific comment or a general query"""
        if comment_id is not None:
            comment = cls.query.filter_by(id=comment_id).first()
            if comment is None:
                raise ObjectDoesNotExist('Comment "%s" does not exists' %
                                         comment_id)
            return comment

        return cls.query.filter_by(**kwargs).all()

    @classmethod
    def delete(cls, comment_id=None, comment=None):
        if comment_id is not None:
            comment = cls.get(comment_id=comment_id)
        db.session.delete(comment)

    @classmethod
    def get_target_comments(cls, target_id, target_type=None):
        """ Get all comments of a target"""
        params = {'target_id': target_id}
        if target_type is not None:
            params.update(target_type=int(target_type))
        return cls.get(**params)

    @classmethod
    def delete_target_all_comments(cls, target_id, target_type=None):
        comments = cls.get_target_comments(target_id, target_type)
        for comment in comments:
            db.session.delete(comment)
Exemplo n.º 14
0
class User(db.Model):
    """
    User database model.
    """

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(length=80), unique=True, nullable=False)
    password = db.Column(column_types.PasswordType(max_length=128,
                                                   schemes=('bcrypt', )),
                         nullable=False)
    email = db.Column(column_types.EmailType(length=120),
                      unique=True,
                      nullable=False)
    first_name = db.Column(db.String(length=30), default='', nullable=False)
    middle_name = db.Column(db.String(length=30), default='', nullable=False)
    last_name = db.Column(db.String(length=30), default='', nullable=False)

    organization = db.Column(db.String(128))
    github = db.Column(db.String(128))
    country = db.Column(db.String(64))
    bio = db.Column(db.Text)

    followers = db.Column(db.Integer, default=0, nullable=False)
    following = db.Column(db.Integer, default=0, nullable=False)

    created = db.Column(db.DateTime(), default=func.now(), nullable=False)
    updated = db.Column(db.DateTime(),
                        onupdate=func.now(),
                        default=func.now(),
                        nullable=False)

    class StaticRoles(enum.Enum):
        INTERNAL = (0x8000, "Internal")
        ADMIN = (0x4000, "Admin")
        REGULAR_USER = (0x2000, "Regular User")
        ACTIVE = (0x1000, "Active Account")

        @property
        def mask(self):
            return self.value[0]

        @property
        def title(self):
            return self.value[1]

    static_roles = db.Column(db.Integer, default=0, nullable=False)
    is_internal = _get_is_static_role_property('is_internal',
                                               StaticRoles.INTERNAL)
    is_admin = _get_is_static_role_property('is_admin', StaticRoles.ADMIN)
    is_regular_user = _get_is_static_role_property('is_regular_user',
                                                   StaticRoles.REGULAR_USER)
    is_active = _get_is_static_role_property('is_active', StaticRoles.ACTIVE)

    def __repr__(self):
        return ("<{class_name}("
                "id={self.id}, "
                "username=\"{self.username}\", "
                "email=\"{self.email}\", "
                "is_internal={self.is_internal}, "
                "is_admin={self.is_admin}, "
                "is_regular_user={self.is_regular_user}, "
                "is_active={self.is_active}, "
                ")>".format(class_name=self.__class__.__name__, self=self))

    def has_static_role(self, role):
        return (self.static_roles & role.mask) != 0

    def set_static_role(self, role):
        if self.has_static_role(role):
            return
        self.static_roles |= role.mask

    def unset_static_role(self, role):
        if not self.has_static_role(role):
            return
        self.static_roles ^= role.mask

    def check_owner(self, user):
        return self == user

    @property
    def is_authenticated(self):
        return True

    @property
    def is_anonymous(self):
        return False

    @classmethod
    def find_with_password(cls, username, password):
        """
        Args:
            username (str)
            password (str) - plain-text password

        Returns:
            user (User) - if there is a user with a specified username and
            password, None otherwise.
        """
        user = cls.query.filter_by(username=username).first()
        if not user:
            return None
        if user.password == password:
            return user
        return None

    @classmethod
    def get(cls, user_id=None, username=None, **kwargs):
        """
        DAO: query dataset by ID or arguments.
        :return: Dataset object or None
        """
        if user_id is not None:
            user = cls.query.filter_by(id=user_id).first()
            if user is None:
                raise ObjectDoesNotExist('User "%s" does not exists' % user_id)
            return user

        if username is not None:
            user = cls.query.filter_by(username=username).first()
            if user is None:
                raise ObjectDoesNotExist('User "%s" does not exists' %
                                         username)
            return user

        if len(kwargs) > 0:
            return cls.query.filter_by(**kwargs).all()

        return None

    def follows(self, another_id):
        """Follow another user
        """
        follower = UserFollowers(user_id=another_id, follower_id=self.id)
        db.session.add(follower)

        # Update stat.
        another = self.query.get_or_404(another_id)
        another.followers += 1
        self.following += 1

    def unfollows(self, another_id):
        """Unfollow another user
        """
        follower = UserFollowers.query \
            .filter_by(user_id=another_id, follower_id=self.id) \
            .first_or_404()

        # Update stat.
        another = self.query.get_or_404(another_id)
        if another.followers > 0:
            another.followers -= 1
        if self.following > 0:
            self.following -= 1

        db.session.delete(follower)

    @classmethod
    def query_all_followers(cls, uid):
        """Return query of all followers of current user
        """
        followers_query = cls.query \
            .join(UserFollowers, User.id == UserFollowers.follower_id) \
            .filter(UserFollowers.user_id == uid)
        return followers_query

    @classmethod
    def query_all_following(cls, uid):
        """Return query of all following of current user
        """
        following_query = cls.query \
            .join(UserFollowers, User.id == UserFollowers.user_id) \
            .filter(UserFollowers.follower_id == uid)
        return following_query
Exemplo n.º 15
0
class Dataset(db.Model):
    """
    Database of datasets
    """
    __tablename__ = 'dataset'
    type = 'table'

    id = db.Column(db.String(128), primary_key=True)
    name = db.Column(db.String(128), unique=True, nullable=False)
    title = db.Column(db.String(256), nullable=False)
    description = db.Column(db.Text, nullable=False)
    homepage = db.Column(db.String(1024), nullable=False)
    version = db.Column(db.String(24))
    keywords = db.Column(ScalarListType(separator=' '), nullable=False)
    image = db.Column(db.String(1024))
    temporal = db.Column(db.String(64))
    spatial = db.Column(db.String(64))
    access_level = db.Column(db.String(32), nullable=False)
    copyrights = db.Column(db.String(256))
    accrual_periodicity = db.Column(db.String(32))
    specification = db.Column(db.Text)
    data_quality = db.Column(db.Boolean, nullable=False)
    data_dictionary = db.Column(db.String(1024))
    category = db.Column(db.String(128), nullable=False)
    issued_time = db.Column(db.String(64))
    language = db.Column(db.String(64))
    stars = db.Column(db.Integer, default=0)

    license_id = db.Column(db.Integer, db.ForeignKey('license.id'))
    license = db.relationship('License', backref='datasets')

    organization_id = db.Column(db.Integer, db.ForeignKey('organization.id'))
    organization = db.relationship('Organization', backref='datasets')

    # Original publisher of dataset
    publisher_id = db.Column(db.String(128), db.ForeignKey('publisher.id'))
    publisher = db.relationship('Publisher', backref='datasets')

    # Owner
    contributor_id = db.Column(db.Integer,
                               db.ForeignKey('user.id'),
                               nullable=True)
    contributor = db.relationship('User', backref='datasets')

    created = db.Column(db.DateTime(), default=func.now())
    updated = db.Column(db.DateTime(), onupdate=func.now())
    deleted = db.Column(db.Boolean, default=False)

    # relationships
    sources = db.relationship('Source', backref='dataset', lazy='dynamic')
    references = db.relationship('Reference',
                                 backref='dataset',
                                 lazy='dynamic')

    @classmethod
    def dataset_id(cls):
        return uuid.uuid4().hex

    @classmethod
    def get(cls, id=None, deleted=False, **kwargs):
        """
        DAO: query dataset by ID or arguments.
        :return: Dataset object or None
        """
        if id is not None:
            dataset = cls.query.filter_by(id=id, deleted=deleted,
                                          **kwargs).first()
            if dataset is None:
                raise ObjectDoesNotExist('Dataset "%s" does not exists' % id)
            return dataset

        if len(kwargs) > 0:
            return Dataset.query.filter_by(**kwargs).all()
        return None

    @classmethod
    def create(cls, **params):
        new_dataset = Dataset(
            id=cls.dataset_id(),
            name=params.get('name'),
            title=params.get('title'),
            license_id=params.get('license_id'),
            organization_id=params.get('organization_id'),
            publisher_id=params.get('publisher_id'),
            contributor_id=params.get('contributor_id'),
            description=params.get('description'),
            homepage=params.get('homepage'),
            version=params.get('version'),
            keywords=params.get('keywords'),
            image=params.get('image'),
            temporal=params.get('temporal'),
            spatial=params.get('spatial'),
            access_level=params.get('access_level'),
            copyrights=params.get('copyrights'),
            accrual_periodicity=params.get('accrual_periodicity'),
            specification=params.get('specification'),
            data_quality=params.get('data_quality'),
            data_dictionary=params.get('data_dictionary'),
            category=params.get('category'),
            issued_time=params.get('issued_time'),
            language=params.get('language'),
            stars=params.get('stars', 0))
        db.session.add(new_dataset)
        return new_dataset

    @classmethod
    def update(cls, id, **kwargs):
        cls.query.filter_by(id=id, deleted=False).update(dict(kwargs))
        return cls.get(id=id)

    @classmethod
    def delete(cls, id=None, dataset=None, hard=True):
        if id is not None:
            dataset = cls.get(id=id)

        if hard:
            db.session.delete(dataset)
        else:
            dataset.deleted = True

    @classmethod
    def delete_all(cls, hard=True):
        try:
            if not hard:
                db.session.get(Dataset).update(deleted=True)
            else:
                db.session.get(Dataset).delete()
        except Exception as e:
            logger.error(
                'Problems occur for deleting datastes, rollback: {}'.format(e))
            db.session.rollback()

    @classmethod
    def update_contributor(cls, dataset_id, contributor):
        dataset = cls.get(id=dataset_id)
        dataset.contributor = contributor

    @classmethod
    def update_license(cls, dataset_id, license):
        dataset = cls.get(id=dataset_id)
        dataset.license = license

    @classmethod
    def update_organization(cls, dataset_id, organization):
        dataset = cls.get(id=dataset_id)
        dataset.organization = organization

    @classmethod
    def update_publisher(cls, dataset_id, publisher):
        dataset = cls.get(id=dataset_id)
        dataset.publisher = publisher

    @classmethod
    def add_reference(cls, dataset_id, **params):
        """Add a new Reference
        """
        name = params.get('name')
        reference = params.get('reference')
        new_ref = Reference(dataset_id=dataset_id,
                            name=name,
                            reference=reference)
        db.session.add(new_ref)
        return new_ref

    @classmethod
    def add_source(cls, dataset_id, **params):
        """Add a new Source
        """
        title = params.get('title')
        format = params.get('format')
        access_url = params.get('access_url')
        download_url = params.get('download_url')
        if download_url is None:
            download_url = access_url
        email = params.get('email')
        description = params.get('description')
        media_type = params.get('media_type')
        schema = params.get('schema')

        new_source = Source(dataset_id=dataset_id,
                            title=title,
                            format=format,
                            access_url=access_url,
                            download_url=download_url,
                            email=email,
                            description=description,
                            media_type=media_type,
                            schema=schema)
        db.session.add(new_source)
        return new_source

    def associated_stories_num(self):
        """
        Get the number of associated stories with the dataset
        :return: integer
        """
        return len(list(self.stories_association))