Beispiel #1
0
def communities(db, users):
    """Create communities."""
    comm_data = [
        {
            'id': 'c1',
            'user_id': users[1]['id']
        },
        {
            'id': 'c2',
            'user_id': users[1]['id']
        },
        {
            'id': 'c3',
            'user_id': users[0]['id']
        },
        {
            'id': 'c4',
            'user_id': users[0]['id']
        },
        {
            'id': 'zenodo',
            'user_id': users[2]['id']
        },
        {
            'id': 'ecfunded',
            'user_id': users[2]['id']
        },
    ]
    for c in comm_data:
        Community.create(c['id'], user_id=c['user_id'])
    db.session.commit()
    return comm_data
Beispiel #2
0
def test_filter_community(app, db, communities_for_filtering, user,
                          case_modifier):
    """Test the community filter task."""
    (comm0, comm1, comm2) = communities_for_filtering

    # Case insensitive
    results = Community.filter_communities(p=case_modifier('beautiful'),
                                           so='title').all()
    assert len(results) == 1
    assert {c.id for c in results} == {comm0.id}

    # Keyword search
    results = Community.filter_communities(p=case_modifier('errors'),
                                           so='title').all()
    assert len(results) == 1
    assert {c.id for c in results} == {comm2.id}

    # Partial keyword present
    results = Community.filter_communities(p=case_modifier('test'),
                                           so='title').all()
    assert len(results) == 3
    assert {c.id for c in results} == {comm0.id, comm1.id, comm2.id}

    # Order matter
    results = Community.filter_communities(
        p=case_modifier('explicit implicit'), so='title').all()
    assert len(results) == 1
    assert {c.id for c in results} == {comm0.id}

    results = Community.filter_communities(
        p=case_modifier('implicit explicit'), so='title').all()
    assert len(results) == 0
    assert {c.id for c in results} == set()
Beispiel #3
0
    def get(self, **kwargs):
        """Get tree json."""
        try:
            action = request.values.get('action')
            comm_id = request.values.get('community')

            pid = kwargs.get('pid_value')

            if pid:
                if comm_id:
                    comm = Community.get(comm_id)
                    tree = self.record_class.get_contribute_tree(pid, int(comm.root_node_id))
                else:
                    tree = self.record_class.get_contribute_tree(pid)
            elif action and 'browsing' in action and comm_id is None:
                tree = self.record_class.get_browsing_tree()
            elif action and 'browsing' in action and not comm_id is None:
                comm = Community.get(comm_id)

                if not comm is None:
                    tree = self.record_class.get_browsing_tree(int(comm.root_node_id))
            else:
                tree = self.record_class.get_index_tree()
            return make_response(jsonify(tree), 200)
        except Exception as ex:
            current_app.logger.error('IndexTree Action Exception: ', ex)
            raise InvalidDataRESTError()
def test_basic_community_workflow(app, db, communities, deposit, deposit_file):
    """Test simple (without concurrent events) deposit publishing workflow."""
    deposit = _publish_and_expunge(db, deposit)
    assert InclusionRequest.query.count() == 0
    pid, record = deposit.fetch_published()
    assert not record.get('communities', [])

    # Open record for edit, request a community and publish
    deposit = deposit.edit()
    deposit['communities'] = ['c1', ]
    deposit = _publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()

    # Should contain just an InclusionRequest
    assert not record.get('communities', [])
    assert InclusionRequest.query.count() == 1
    ir = InclusionRequest.query.one()
    assert ir.id_community == 'c1'
    assert ir.id_record == record.id

    # Accept a record to the community 'c1'
    c1 = Community.get('c1')
    c1.accept_record(record)
    record.commit()
    db.session.commit()
    assert InclusionRequest.query.count() == 0
    assert record['communities'] == ['c1', ]

    # Open for edit and request another community
    deposit = deposit.edit()
    assert deposit['communities'] == ['c1', ]
    deposit['communities'] = ['c1', 'c2', ]  # New request for community 'c2'
    deposit = _publish_and_expunge(db, deposit)
    deposit['communities'] = ['c1', 'c2', ]
    pid, record = deposit.fetch_published()
    assert record['communities'] == ['c1', ]
    assert InclusionRequest.query.count() == 1
    ir = InclusionRequest.query.one()
    assert ir.id_community == 'c2'
    assert ir.id_record == record.id

    # Reject the request for community 'c2'
    c2 = Community.get('c2')
    c2.reject_record(record)
    db.session.commit()
    deposit = deposit.edit()

    # The deposit should not contain obsolete inclusion requests
    assert deposit['communities'] == ['c1', ]
    assert InclusionRequest.query.count() == 0
    pid, record = deposit.fetch_published()
    assert record['communities'] == ['c1', ]

    # Request for removal from a previously accepted community 'c1'
    deposit['communities'] = []
    deposit = _publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    assert not deposit.get('communities', [])
    assert not record.get('communities', [])
    assert InclusionRequest.query.count() == 0
Beispiel #5
0
def communities_for_filtering(app, db, user):
    """Create some example communities."""
    user1 = db_.session.merge(user)

    index = Index()
    db.session.add(index)
    db.session.commit()
    comm0 = Community.create(community_id='comm1',
                             user_id=user1.id,
                             title='Test1',
                             description=('Beautiful is better than ugly. '
                                          'Explicit is better than implicit.'),
                             root_node_id=index.id)
    comm1 = Community.create(community_id='comm2',
                             user_id=user1.id,
                             title='Testing case 2',
                             description=('Flat is better than nested. '
                                          'Sparse is better than dense.'),
                             root_node_id=index.id)
    comm2 = Community.create(community_id='oth3',
                             user_id=user1.id,
                             title='A word about testing',
                             description=('Errors should never pass silently. '
                                          'Unless explicitly silenced.'),
                             root_node_id=index.id)
    return comm0, comm1, comm2
def communities(app, db, user):
    """Create some example communities."""
    user1 = db_.session.merge(user)

    comm0 = Community.create(community_id="comm1", user_id=user1.id, title="Title1", description="Description1")
    comm1 = Community.create(community_id="comm2", user_id=user1.id, title="A")
    comm2 = Community.create(community_id="oth3", user_id=user1.id)
    return comm0, comm1, comm2
def communities(app, db, user):
    """Create some example communities."""
    user1 = db_.session.merge(user)

    comm0 = Community.create(community_id='comm1', user_id=user1.id,
                             title='Title1', description='Description1')
    comm1 = Community.create(community_id='comm2', user_id=user1.id, title='A')
    comm2 = Community.create(community_id='oth3', user_id=user1.id)
    return comm0, comm1, comm2
Beispiel #8
0
def communities(app, db, user):
    """Create some example communities."""
    user1 = db_.session.merge(user)

    comm0 = Community.create(community_id='comm1',
                             user_id=user1.id,
                             title='Title1',
                             description='Description1')
    comm1 = Community.create(community_id='comm2', user_id=user1.id, title='A')
    comm2 = Community.create(community_id='oth3', user_id=user1.id)
    return comm0, comm1, comm2
Beispiel #9
0
def communities(db, users):
    """Create communities."""
    comm_data = [
        {'id': 'c1', 'user_id': users[1]['id']},
        {'id': 'c2', 'user_id': users[1]['id']},
        {'id': 'c3', 'user_id': users[0]['id']},
        {'id': 'c4', 'user_id': users[0]['id']},
    ]
    for c in comm_data:
        Community.create(c['id'], user_id=c['user_id'])
    db.session.commit()
    return comm_data
Beispiel #10
0
def loadcommunities(owner_email):
    """Load the Zenodo communities fixture.

    Create extra PID if license is to be mapped and already exists, otherwise
    create a new license record and a PID.
    """
    data = read_json('data/communities.json')
    owner = User.query.filter_by(email=owner_email).one()

    for comm_data in data:
        community_id = comm_data.pop('id')
        user_id = owner.id
        Community.create(community_id, user_id, **comm_data)
    db.session.commit()
Beispiel #11
0
def loadcommunities(owner_email):
    """Load the Zenodo communities fixture.

    Create extra PID if license is to be mapped and already exists, otherwise
    create a new license record and a PID.
    """
    data = read_json('data/communities.json')
    owner = User.query.filter_by(email=owner_email).one()

    for comm_data in data:
        community_id = comm_data.pop('id')
        user_id = owner.id
        Community.create(community_id, user_id, **comm_data)
    db.session.commit()
Beispiel #12
0
def index():
    """Index page with uploader and list of existing depositions."""
    ctx = mycommunities_ctx()

    p = request.args.get('p', type=str)
    so = request.args.get('so', type=str)
    page = request.args.get('page', type=int, default=1)

    so = so or current_app.config.get('COMMUNITIES_DEFAULT_SORTING_OPTION')

    communities = Community.filter_communities(p, so)
    featured_community = FeaturedCommunity.get_featured_or_none()
    form = SearchForm(p=p)
    per_page = 10
    page = max(page, 1)
    p = Pagination(page, per_page, communities.count())

    ctx.update({
        'r_from': max(p.per_page * (p.page - 1), 0),
        'r_to': min(p.per_page * p.page, p.total_count),
        'r_total': p.total_count,
        'pagination': p,
        'form': form,
        'title': _('Communities'),
        'communities': communities.slice(
            per_page * (page - 1), per_page * page).all(),
        'featured_community': featured_community,
    })

    return render_template(
        "invenio_communities/index.html",
        **ctx
    )
Beispiel #13
0
 def _get_community_list(self):
     try:
         query_data = Community.query.all()
         query_data.insert(0, Community(id='Root Index'))
     except Exception as ex:
         current_app.logger.debug(ex)
     return query_data
Beispiel #14
0
def index():
    """Index page with uploader and list of existing depositions."""
    ctx = mycommunities_ctx()

    p = request.args.get('p', type=str)
    so = request.args.get('so', type=str)
    page = request.args.get('page', type=int, default=1)

    so = so or current_app.config.get('COMMUNITIES_DEFAULT_SORTING_OPTION')

    communities = Community.filter_communities(p, so)
    featured_community = FeaturedCommunity.get_featured_or_none()
    form = SearchForm(p=p)
    per_page = 10
    page = max(page, 1)
    p = Pagination(page, per_page, communities.count())

    ctx.update({
        'r_from': max(p.per_page * (p.page - 1), 0),
        'r_to': min(p.per_page * p.page, p.total_count),
        'r_total': p.total_count,
        'pagination': p,
        'form': form,
        'title': _('Communities'),
        'communities': communities.slice(
            per_page * (page - 1), per_page * page).all(),
        'featured_community': featured_community,
    })

    return render_template(
        current_app.config['COMMUNITIES_INDEX_TEMPLATE'], **ctx)
Beispiel #15
0
def community_curation(record, user):
    """Generate a list of pending and accepted communities with permissions.

    Return a 2-tuple containing two lists, first for 'pending' and second
    for 'accepted' communities. Each item in both of the list is another
    2-tuple of (Community, bool), describing community itself,
    and the permission (bool) to curate it.
    """
    irs = InclusionRequest.query.filter_by(id_record=record.id).order_by(InclusionRequest.id_community).all()
    pending = [ir.community for ir in irs]
    accepted = [Community.get(c) for c in record.get("communities", [])]
    # Additionally filter out community IDs that did not resolve (None)
    accepted = [c for c in accepted if c]

    # Check for global curation permission (all communites on this record).
    global_perm = None
    if user.is_anonymous:
        global_perm = False
    elif DynamicPermission(ActionNeed("admin-access")).can():
        global_perm = True

    if global_perm:
        return (pending, pending, accepted, accepted)
    else:
        return (
            [c for c in pending if _can_curate(c, user, record)],
            [c for c in accepted if _can_curate(c, user, record, accepted=True)],
            pending,
            accepted,
        )
Beispiel #16
0
def community_curation(record, user):
    """Generate a list of pending and accepted communities with permissions.

    Return a 4-tuple of lists (in order):
     * 'pending' communities, which can be curated by given user
     * 'accepted' communities, which can be curated by given user
     * All 'pending' communities
     * All 'accepted' communities
    """
    irs = ZenodoCommunity.get_irs(record).all()
    pending = list(set(ir.community for ir in irs))
    accepted = [Community.get(c) for c in record.get('communities', [])]
    # Additionally filter out community IDs that did not resolve (None)
    accepted = [c for c in accepted if c]

    # Check for global curation permission (all communites on this record).
    global_perm = None
    if user.is_anonymous:
        global_perm = False
    elif DynamicPermission(ActionNeed('admin-access')).can():
        global_perm = True

    if global_perm:
        return (pending, accepted, pending, accepted)
    else:
        return (
            [c for c in pending if _can_curate(c, user, record)],
            [
                c for c in accepted
                if _can_curate(c, user, record, accepted=True)
            ],
            pending,
            accepted,
        )
Beispiel #17
0
    def _default_parser_community(community_id, qstr=None):
        """Default parser that uses the Q() from elasticsearch_dsl.

           Full text Search.
           Detail Search.

        :param qstr: Query string.
        :returns: Query parser.
        """
        # add  Permission filter by publish date and status
        comm = Community.get(community_id)
        root_node_id = comm.root_node_id
        mt = get_permission_filter(root_node_id)

        # multi keywords search filter
        kmt = _get_detail_keywords_query()
        # detail search
        if kmt:
            mt.extend(kmt)
            q = _get_search_qs_query(qs)
            if q:
                mt.append(q)
        else:
            # Full Text Search
            if qstr:
                q_s = _get_file_content_query(qstr)
                mt.append(q_s)
        return Q('bool', must=mt) if mt else Q()
Beispiel #18
0
def index():
    """Index page with uploader and list of existing depositions."""
    ctx = mycommunities_ctx()

    p = request.args.get('p', type=str)
    so = request.args.get('so', type=str)
    page = request.args.get('page', type=int, default=1)

    so = so or current_app.config.get('COMMUNITIES_DEFAULT_SORTING_OPTION')

    communities = Community.filter_communities(p, so).all()
    communities = [c for c in communities
                   if _get_permission("communities-read", c).can()
                   or DynamicPermission(ActionNeed('admin-access')).can()]
    featured_community = FeaturedCommunity.get_featured_or_none()
    form = SearchForm(p=p)
    per_page = 10
    page = max(page, 1)
    p = Pagination(page, per_page, len(communities))

    ctx.update({
        'r_from': max(p.per_page * (p.page - 1), 0),
        'r_to': min(p.per_page * p.page, p.total_count),
        'r_total': p.total_count,
        'pagination': p,
        'form': form,
        'title': _('Communities'),
        'communities': communities[per_page * (page - 1):per_page * page],
        'featured_community': featured_community
    })

    return render_template(
        "invenio_communities/index.html",
        **ctx
    )
Beispiel #19
0
def test_fixed_communities_edit(app, db, users, communities, deposit,
                                deposit_file, communities_autoadd_enabled):
    """Test automatic adding and requesting to fixed communities."""
    deposit = publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    assert deposit['communities'] == ['zenodo', ]
    assert 'communities' not in record
    ir = InclusionRequest.query.one()
    assert ir.id_community == 'zenodo'
    assert ir.id_record == record.id

    # Open for edit
    deposit = deposit.edit()
    # Make sure 'zenodo' community is requested
    pid, record = deposit.fetch_published()
    assert deposit['communities'] == ['zenodo', ]
    assert not record.get('communities', [])
    assert InclusionRequest.query.count() == 1

    comm = Community.get('zenodo')
    comm.accept_record(record)
    record.commit()
    db.session.commit()

    # Publish and make sure nothing is missing
    deposit = publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    assert deposit['communities'] == ['zenodo']
    assert record['communities'] == ['zenodo', ]
    assert record['_oai']['sets'] == ['user-zenodo', ]
    assert InclusionRequest.query.count() == 0
Beispiel #20
0
def load_community(data, logos_dir):
    """Load community from data dump.

    :param data: Dictionary containing community data.
    :type data: dict
    :param logos_dir: Path to a local directory with community logos.
    :type logos_dir: str
    """
    from invenio_communities.models import Community
    from invenio_communities.utils import save_and_validate_logo
    logo_ext_washed = logo_ext_wash(data['logo_ext'])
    c = Community(
        id=data['id'],
        id_user=data['id_user'],
        title=data['title'],
        description=data['description'],
        page=data['page'],
        curation_policy=data['curation_policy'],
        last_record_accepted=iso2dt_or_none(data['last_record_accepted']),
        logo_ext=logo_ext_washed,
        ranking=data['ranking'],
        fixed_points=data['fixed_points'],
        created=iso2dt(data['created']),
        updated=iso2dt(data['last_modified']),
    )
    logo_path = join(logos_dir, "{0}.{1}".format(c.id, logo_ext_washed))
    db.session.add(c)
    if isfile(logo_path):
        with open(logo_path, 'rb') as fp:
            save_and_validate_logo(fp, logo_path, c.id)
    db.session.commit()
Beispiel #21
0
def community_curation(record, user):
    """Generate a list of pending and accepted communities with permissions.

    Return a 2-tuple containing two lists, first for 'pending' and second
    for 'accepted' communities. Each item in both of the list is another
    2-tuple of (Community, bool), describing community itself,
    and the permission (bool) to curate it.
    """
    irs = InclusionRequest.query.filter_by(id_record=record.id).order_by(
        InclusionRequest.id_community).all()
    pending = [ir.community for ir in irs]
    accepted = [Community.get(c) for c in record.get('communities', [])]
    # Additionally filter out community IDs that did not resolve (None)
    accepted = [c for c in accepted if c]

    # Check for global curation permission (all communites on this record).
    global_perm = None
    if user.is_anonymous:
        global_perm = False
    elif DynamicPermission(ActionNeed('admin-access')).can():
        global_perm = True

    if global_perm:
        return (pending, pending, accepted, accepted)
    else:
        return (
            [c for c in pending if _can_curate(c, user, record)],
            [c for c in accepted
             if _can_curate(c, user, record, accepted=True)],
            pending,
            accepted,
        )
Beispiel #22
0
def legacy_index():
    """Legacy deposit."""
    c_id = request.args.get('c', type=str)
    if c_id:
        c = Community.get(c_id)
        return redirect('/communities/{0}/upload'.format(c.id))
    return redirect(url_for('invenio_deposit_ui.new'))
Beispiel #23
0
def community_curation(record, user):
    """Generate a list of pending and accepted communities with permissions.

    Return a 4-tuple of lists (in order):
     * 'pending' communities, which can be curated by given user
     * 'accepted' communities, which can be curated by given user
     * All 'pending' communities
     * All 'accepted' communities
    """
    irs = ZenodoCommunity.get_irs(record).all()
    pending = list(set(ir.community for ir in irs))
    accepted = [Community.get(c) for c in record.get('communities', [])]
    # Additionally filter out community IDs that did not resolve (None)
    accepted = [c for c in accepted if c]

    # Check for global curation permission (all communities on this record).
    global_perm = None
    if user.is_anonymous:
        global_perm = False
    elif Permission(ActionNeed('admin-access')).can():
        global_perm = True

    if global_perm:
        return (pending, accepted, pending, accepted)
    else:
        return (
            [c for c in pending if _can_curate(c, user, record)],
            [c for c in accepted
             if _can_curate(c, user, record, accepted=True)],
            pending,
            accepted,
        )
def test_accept_while_edit(app, db, communities, deposit, deposit_file):
    """Test deposit publishing with concurrent events.

    Accept a record, while deposit in open edit and then published.
    """
    deposit['communities'] = ['c1', 'c2']
    deposit = _publish_and_expunge(db, deposit)
    assert InclusionRequest.query.count() == 2
    pid, record = deposit.fetch_published()
    assert deposit['communities'] == ['c1', 'c2']
    assert not record.get('communities', [])

    # Open for edit
    deposit = deposit.edit()
    pid, record = deposit.fetch_published()
    assert deposit['communities'] == ['c1', 'c2']
    assert not record.get('communities', [])
    assert InclusionRequest.query.count() == 2

    # Accept a record meanwhile
    c1 = Community.get('c1')
    c1.accept_record(record)
    record.commit()
    db.session.commit()

    # Publish and make sure nothing is missing
    deposit = _publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    assert deposit['communities'] == ['c1', 'c2']
    assert record['communities'] == ['c1', ]
    assert InclusionRequest.query.count() == 1
    ir = InclusionRequest.query.one()
    assert ir.id_community == 'c2'
    assert ir.id_record == record.id
def communities_for_filtering(app, db, user):
    """Create some example communities."""
    user1 = db_.session.merge(user)

    comm0 = Community.create(community_id='comm1', user_id=user1.id,
                             title='Test1',
                             description=('Beautiful is better than ugly. '
                                          'Explicit is better than implicit.'))
    comm1 = Community.create(community_id='comm2', user_id=user1.id,
                             title='Testing case 2',
                             description=('Flat is better than nested. '
                                          'Sparse is better than dense.'))
    comm2 = Community.create(community_id='oth3', user_id=user1.id,
                             title='A word about testing',
                             description=('Errors should never pass silently. '
                                          'Unless explicitly silenced.'))
    return comm0, comm1, comm2
Beispiel #26
0
def new():
    """Create a new deposit."""
    c = Community.get(request.args.get('c', type=str))
    return render_template(current_app.config['DEPOSIT_UI_NEW_TEMPLATE'],
                           record={'_deposit': {
                               'id': None
                           }},
                           community=c)
def test_model_init(app):
    """Test basic model initialization and actions."""
    with app.app_context():
        # Init the User and the Community
        user1 = create_test_user()
        comm1 = Community(id='comm1', id_user=user1.id)
        db.session.add(comm1)
        db.session.commit()
        communities_key = app.config["COMMUNITIES_RECORD_KEY"]
        # Create a record and accept it into the community by creating an
        # InclusionRequest and then calling the accept action
        rec1 = Record.create({'title': 'Foobar'})
        InclusionRequest.create(community=comm1, record=rec1)
        assert InclusionRequest.query.count() == 1
        comm1.accept_record(rec1)
        assert 'comm1' in rec1[communities_key]
        assert InclusionRequest.query.count() == 0

        # Likewise, reject a record from the community
        rec2 = Record.create({'title': 'Bazbar'})
        InclusionRequest.create(community=comm1, record=rec2)
        assert InclusionRequest.query.count() == 1
        comm1.reject_record(rec2)
        assert communities_key not in rec2  # dict key should not be created
        assert InclusionRequest.query.count() == 0

        # Add record to another community
        comm2 = Community(id='comm2', id_user=user1.id)
        db.session.add(comm2)
        db.session.commit()
        InclusionRequest.create(community=comm2, record=rec1)
        comm2.accept_record(rec1)
        assert communities_key in rec1
        assert len(rec1[communities_key]) == 2
        assert comm1.id in rec1[communities_key]
        assert comm2.id in rec1[communities_key]

        # Accept/reject a record to/from a community without inclusion request
        rec3 = Record.create({'title': 'Spam'})
        pytest.raises(InclusionRequestMissingError, comm1.accept_record, rec3)
        pytest.raises(InclusionRequestMissingError, comm1.reject_record, rec3)

        # Create two inclusion requests
        comm3 = Community(id='comm3', id_user=user1.id)
        db.session.add(comm3)
        db.session.commit()
        InclusionRequest.create(community=comm3, record=rec1)
        pytest.raises(InclusionRequestExistsError, InclusionRequest.create,
                      community=comm3, record=rec1)

        # Try to accept a record to a community twice (should raise)
        # (comm1 is already in rec1)
        pytest.raises(InclusionRequestObsoleteError, InclusionRequest.create,
                      community=comm1, record=rec1)
Beispiel #28
0
    def _filter_by_owned_communities(self, comms):
        """Filter the list of communities for auto accept.

        :param comms: Community IDs to be filtered by the deposit owners.
        :type comms: list of str
        :returns: Community IDs, which are owned by one of the deposit owners.
        :rtype: list
        """
        return [c for c in comms if Community.get(c).id_user in
                self['_deposit']['owners']]
Beispiel #29
0
    def _filter_by_owned_communities(self, comms):
        """Filter the list of communities for auto accept.

        :param comms: Community IDs to be filtered by the deposit owners.
        :type comms: list of str
        :returns: Community IDs, which are owned by one of the deposit owners.
        :rtype: list
        """
        return [c for c in comms if Community.get(c).id_user in
                self['_deposit']['owners']]
Beispiel #30
0
 def validate_publish(self):
     """Validate deposit."""
     super(ZenodoDeposit, self).validate()
     if len(self.files) == 0:
         raise MissingFilesError()
     if 'communities' in self:
         missing = [c for c in self['communities']
                    if Community.get(c) is None]
         if missing:
             raise MissingCommunityError(missing)
Beispiel #31
0
def communities(app, db, user):
    """Create some example communities."""
    user1 = db_.session.merge(user)

    index = Index()
    db.session.add(index)
    db.session.commit()
    comm0 = Community.create(community_id='comm1',
                             user_id=user1.id,
                             title='Title1',
                             description='Description1',
                             root_node_id=index.id)
    comm1 = Community.create(community_id='comm2',
                             user_id=user1.id,
                             title='A',
                             root_node_id=index.id)
    comm2 = Community.create(community_id='oth3',
                             user_id=user1.id,
                             root_node_id=index.id)
    return comm0, comm1, comm2
Beispiel #32
0
def test_remove_community_by_key_del(app, db, communities, deposit,
                                     deposit_file):
    """Test removal of communities by key deletion.

    Communities can be removed by not providing or deleting the communities
    from the key deposit. Moreover, the redundant 'empty' keys should not be
    automatically added to deposit nor record.
    """
    # If 'communities' key was not in deposit metadata,
    # it shouldn't be automatically added
    assert 'communities' not in deposit
    deposit = publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    assert 'communities' not in deposit
    assert 'communities' not in record
    assert not record['_oai'].get('sets', [])

    # Request for 'c1' and 'c2'
    deposit = deposit.edit()
    deposit['communities'] = [
        'c1',
        'c2',
    ]
    deposit = publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    # No reason to have 'communities' in record since nothing was accepted
    assert 'communities' not in record
    assert not record['_oai'].get('sets', [])

    # Accept 'c1'
    c1 = Community.get('c1')
    c1.accept_record(record)
    record.commit()

    pid, record = deposit.fetch_published()
    assert deposit['communities'] == [
        'c1',
        'c2',
    ]
    assert InclusionRequest.query.count() == 1
    assert record['communities'] == [
        'c1',
    ]
    assert set(record['_oai']['sets']) == set(['user-c1'])

    # Remove the key from deposit and publish
    deposit = deposit.edit()
    del deposit['communities']
    deposit = publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    assert 'communities' not in deposit
    assert 'communities' not in record
    assert InclusionRequest.query.count() == 0
    assert not record['_oai'].get('sets', [])
Beispiel #33
0
    def _autoadd_communities(comms, record):
        """Add record to all communities ommiting the inclusion request.

        :param comms: Community IDs, to which the record should be added.
        :type comms: list of str
        :param record: Record corresponding to this deposit.
        :type record: `invenio_records.api.Record`
        """
        for comm_id in comms:
            comm = Community.get(comm_id)
            comm.add_record(record)  # Handles oai-sets internally
Beispiel #34
0
    def _autoadd_communities(comms, record):
        """Add record to all communities ommiting the inclusion request.

        :param comms: Community IDs, to which the record should be added.
        :type comms: list of str
        :param record: Record corresponding to this deposit.
        :type record: `invenio_records.api.Record`
        """
        for comm_id in comms:
            comm = Community.get(comm_id)
            if not comm.has_record(record):
                comm.add_record(record)  # Handles oai-sets internally
Beispiel #35
0
 def load_communities(self, data):
     """Load communities type."""
     if not isinstance(data, list):
         raise ValidationError(_('Not a list.'))
     comm_ids = list(
         sorted([x['identifier'] for x in data if x.get('identifier')]))
     errors = {c for c in comm_ids if not Community.get(c)}
     if errors:
         raise ValidationError('Invalid communities: {0}'.format(
             ', '.join(errors)),
                               field_names='communities')
     return comm_ids or missing
Beispiel #36
0
    def __init__(self, community):
        """Construct the API object.

        :param community: Instantiate the API with the community.
            Parameter can be either the model instance, or string
            (community ID).
        :type community: invenio_communities.model.Community or str
        """
        if isinstance(community, (text_type, string_types)):
            self.community = Community.get(community)
        else:
            self.community = community
Beispiel #37
0
def loadcommunity(comm_data):
    """Load the Zenodo communities fixture."""
    logo_path = comm_data.pop('logo', None)
    community_id = comm_data.pop('id')
    owner_email = comm_data.pop('owner_email')
    owner_id = User.query.filter_by(email=owner_email).one().id
    c = Community.create(community_id, owner_id, **comm_data)
    if logo_path:
        logo = file_stream(logo_path)
        ext = save_and_validate_logo(logo, logo.name, community_id)
        c.logo_ext = ext
    db.session.commit()
Beispiel #38
0
def loadcommunity(comm_data):
    """Load the Zenodo communities fixture."""
    logo_path = comm_data.pop('logo', None)
    community_id = comm_data.pop('id')
    owner_email = comm_data.pop('owner_email')
    owner_id = User.query.filter_by(email=owner_email).one().id
    c = Community.create(community_id, owner_id, **comm_data)
    if logo_path:
        logo = file_stream(logo_path)
        ext = save_and_validate_logo(logo, logo.name, community_id)
        c.logo_ext = ext
    db.session.commit()
Beispiel #39
0
    def __init__(self, community):
        """Construct the API object.

        :param community: Instantiate the API with the community.
            Parameter can be either the model instance, or string
            (community ID).
        :type community: invenio_communities.model.Community or str
        """
        if isinstance(community, (text_type, string_types)):
            self.community = Community.get(community)
        else:
            self.community = community
Beispiel #40
0
def migrate_record(record_uuid, logger=None):
    """Migrate a record."""
    try:
        # Migrate record
        record = Record.get_record(record_uuid)
        if '$schema' in record:
            if logger:
                logger.info("Record already migrated.")
            return
        record = transform_record(record)
        provisional_communities = record.pop('provisional_communities', None)
        record.commit()
        # Create provisional communities.
        if provisional_communities:
            for c_id in provisional_communities:
                try:
                    c = Community.get(c_id)
                    if c:
                        InclusionRequest.create(c, record, notify=False)
                    else:
                        if logger:
                            logger.warning(
                                "Community {0} does not exists "
                                "(record {1}).".format(
                                    c_id, str(record.id)))
                except InclusionRequestExistsError:
                    if logger:
                        logger.warning("Inclusion request exists.")
        # Register DOI
        doi = record.get('doi')
        if doi:
            is_internal = doi.startswith('10.5281')
            PersistentIdentifier.create(
                pid_type='doi',
                pid_value=doi,
                pid_provider='datacite' if is_internal else None,
                object_type='rec',
                object_uuid=record_uuid,
                status=(
                    PIDStatus.REGISTERED if is_internal
                    else PIDStatus.RESERVED),
            )
        db.session.commit()
    except NoResultFound:
        if logger:
            logger.info("Deleted record - no migration required.")
    except Exception:
        db.session.rollback()
        pid = PersistentIdentifier.get_by_object('recid', 'rec', record_uuid)
        pid.status = PIDStatus.RESERVED
        db.session.commit()
        raise
Beispiel #41
0
    def _create_inclusion_requests(comms, record):
        """Create inclusion requests for communities.

        :param comms: Community IDs for which the inclusion requests might
                      should be created (if they don't exist already).
        :type comms: list of str
        :param record: Record corresponding to this deposit.
        :type record: `invenio_records.api.Record`
        """
        for comm_id in comms:
            comm = Community.get(comm_id)
            if not InclusionRequest.get(comm_id, record.id):
                InclusionRequest.create(comm, record)
Beispiel #42
0
    def _create_inclusion_requests(comms, record):
        """Create inclusion requests for communities.

        :param comms: Community IDs for which the inclusion requests might
                      should be created (if they don't exist already).
        :type comms: list of str
        :param record: Record corresponding to this deposit.
        :type record: `invenio_records.api.Record`
        """
        for comm_id in comms:
            comm = Community.get(comm_id)
            if not InclusionRequest.get(comm_id, record.id):
                InclusionRequest.create(comm, record)
def test_filter_community(app, db, communities_for_filtering, user,
                          case_modifier):
    """Test the community filter task."""
    (comm0, comm1, comm2) = communities_for_filtering

    # Case insensitive
    results = Community.filter_communities(
                p=case_modifier('beautiful'),
                so='title').all()
    assert len(results) == 1
    assert {c.id for c in results} == {comm0.id}

    # Keyword search
    results = Community.filter_communities(
                p=case_modifier('errors'),
                so='title').all()
    assert len(results) == 1
    assert {c.id for c in results} == {comm2.id}

    # Partial keyword present
    results = Community.filter_communities(
                p=case_modifier('test'),
                so='title').all()
    assert len(results) == 3
    assert {c.id for c in results} == {comm0.id,
                                       comm1.id, comm2.id}

    # Order matter
    results = Community.filter_communities(
                p=case_modifier('explicit implicit'),
                so='title').all()
    assert len(results) == 1
    assert {c.id for c in results} == {comm0.id}

    results = Community.filter_communities(
                p=case_modifier('implicit explicit'),
                so='title').all()
    assert len(results) == 0
    assert {c.id for c in results} == set()
Beispiel #44
0
    def get(self, query, sort, page, size):
        """Get a list of all the communities.

        .. http:get:: /communities/(string:id)
            Returns a JSON list with all the communities.
            **Request**:
            .. sourcecode:: http
                GET /communities HTTP/1.1
                Accept: application/json
                Content-Type: application/json
                Host: localhost:5000
            :reqheader Content-Type: application/json
            **Response**:
            .. sourcecode:: http
                HTTP/1.0 200 OK
                Content-Length: 334
                Content-Type: application/json
                [
                    {
                        "id": "comm1"
                    },
                    {
                        "id": "comm2"
                    }
                ]
            :resheader Content-Type: application/json
            :statuscode 200: no error
        """
        urlkwargs = {
            'q': query,
            'sort': sort,
            'size': size,
        }

        communities = Community.filter_communities(query, sort)
        page = communities.paginate(page, size)

        links = default_links_pagination_factory(page, urlkwargs)

        links_headers = map(
            lambda key:
            ('link', 'ref="{0}" href="{1}"'.format(key, links[key])), links)

        return self.make_response(
            page,
            headers=links_headers,
            links_item_factory=default_links_item_factory,
            page=page,
            urlkwargs=urlkwargs,
            links_pagination_factory=default_links_pagination_factory,
        )
Beispiel #45
0
    def get(self, query, sort, page, size):
        """Get a list of all the communities.

        .. http:get:: /communities/(string:id)
            Returns a JSON list with all the communities.
            **Request**:
            .. sourcecode:: http
                GET /communities HTTP/1.1
                Accept: application/json
                Content-Type: application/json
                Host: localhost:5000
            :reqheader Content-Type: application/json
            **Response**:
            .. sourcecode:: http
                HTTP/1.0 200 OK
                Content-Length: 334
                Content-Type: application/json
                [
                    {
                        "id": "comm1"
                    },
                    {
                        "id": "comm2"
                    }
                ]
            :resheader Content-Type: application/json
            :statuscode 200: no error
        """
        urlkwargs = {
            'q': query,
            'sort': sort,
            'size': size,
        }

        communities = Community.filter_communities(query, sort)
        page = communities.paginate(page, size)

        links = default_links_pagination_factory(page, urlkwargs)

        links_headers = map(lambda key: ('link', 'ref="{0}" href="{1}"'.format(
            key, links[key])), links)

        return self.make_response(
            page,
            headers=links_headers,
            links_item_factory=default_links_item_factory,
            page=page,
            urlkwargs=urlkwargs,
            links_pagination_factory=default_links_pagination_factory,
        )
Beispiel #46
0
def migrate_record(record_uuid, logger=None):
    """Migrate a record."""
    try:
        # Migrate record
        record = Record.get_record(record_uuid)
        if '$schema' in record:
            if logger:
                logger.info("Record already migrated.")
            return
        record = transform_record(record)
        provisional_communities = record.pop('provisional_communities', None)
        record.commit()
        # Create provisional communities.
        if provisional_communities:
            for c_id in provisional_communities:
                try:
                    c = Community.get(c_id)
                    if c:
                        InclusionRequest.create(c, record, notify=False)
                    else:
                        if logger:
                            logger.warning("Community {0} does not exists "
                                           "(record {1}).".format(
                                               c_id, str(record.id)))
                except InclusionRequestExistsError:
                    if logger:
                        logger.warning("Inclusion request exists.")
        # Register DOI
        doi = record.get('doi')
        if doi:
            is_internal = doi.startswith('10.5281')
            PersistentIdentifier.create(
                pid_type='doi',
                pid_value=doi,
                pid_provider='datacite' if is_internal else None,
                object_type='rec',
                object_uuid=record_uuid,
                status=(PIDStatus.REGISTERED
                        if is_internal else PIDStatus.RESERVED),
            )
        db.session.commit()
    except NoResultFound:
        if logger:
            logger.info("Deleted record - no migration required.")
    except Exception:
        db.session.rollback()
        pid = PersistentIdentifier.get_by_object('recid', 'rec', record_uuid)
        pid.status = PIDStatus.RESERVED
        db.session.commit()
        raise
Beispiel #47
0
def mycommunities_ctx():
    """Helper method for return ctx used by many views."""
    communities = Community.filter_communities("", "title").all()
    mycommunities = [c for c in communities
                     if _get_permission("communities-read", c).can()
                     or DynamicPermission(ActionNeed('admin-access')).can()]
    return {
        "mycommunities": mycommunities,
        "permission_admin": DynamicPermission(ActionNeed('admin-access')),
        "permission_cadmin": partial(_get_permission, "communities-admin"),
        "permission_curate": partial(_get_permission, "communities-curate"),
        "permission_manage": partial(_get_permission, "communities-manage"),
        "permission_read": partial(_get_permission, "communities-read"),
    }
Beispiel #48
0
    def validate_publish(self):
        """Validate deposit."""
        super(ZenodoDeposit, self).validate()

        if len(self.files) == 0:
            raise MissingFilesError()

        if self.multipart_files.count() != 0:
            raise OngoingMultipartUploadError()

        if 'communities' in self:
            missing = [c for c in self['communities']
                       if Community.get(c) is None]
            if missing:
                raise MissingCommunityError(missing)
def test_fixed_communities(app, db, users, communities, deposit, deposit_file,
                           communities_autoadd_enabled):
    """Test automatic adding and requesting to fixed communities."""

    deposit['grants'] = [{'title': 'SomeGrant'}, ]
    # 'c3' is owned by one of the deposit owner
    assert Community.get('c3').id_user in deposit['_deposit']['owners']
    deposit['communities'] = ['c3', ]
    deposit = _publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    assert record['communities'] == ['c3', 'ecfunded']
    assert deposit['communities'] == ['c3', 'ecfunded', 'zenodo']
    ir = InclusionRequest.query.one()
    assert ir.id_community == 'zenodo'
    assert ir.id_record == record.id
Beispiel #50
0
    def _create_inclusion_requests(comms, record):
        """Create inclusion requests for communities.

        :param comms: Community IDs for which the inclusion requests might
                      should be created (if they don't exist already).
        :type comms: list of str
        :param record: Record corresponding to this deposit.
        :type record: `invenio_records.api.Record`
        """
        for comm_id in comms:
            comm_api = ZenodoCommunity(comm_id)
            # Check if InclusionRequest exists for any version already
            pending_irs = comm_api.get_comm_irs(record)
            if pending_irs.count() == 0 and not comm_api.has_record(record):
                comm = Community.get(comm_id)
                InclusionRequest.create(comm, record)
Beispiel #51
0
    def _create_inclusion_requests(comms, record):
        """Create inclusion requests for communities.

        :param comms: Community IDs for which the inclusion requests might
                      should be created (if they don't exist already).
        :type comms: list of str
        :param record: Record corresponding to this deposit.
        :type record: `invenio_records.api.Record`
        """
        for comm_id in comms:
            comm_api = ZenodoCommunity(comm_id)
            # Check if InclusionRequest exists for any version already
            pending_irs = comm_api.get_comm_irs(record)
            if pending_irs.count() == 0 and not comm_api.has_record(record):
                comm = Community.get(comm_id)
                InclusionRequest.create(comm, record)
Beispiel #52
0
    def _remove_accepted_communities(comms, record):
        """Remove accepted communities.

        :param comms: Already accepted community IDs which no longer
                      should have this record.
        :type comms: list of str
        :param record: Record corresponding to this deposit.
        :type record: `invenio_records.api.Record`
        :returns: modified 'record' argument
        :rtype: `invenio_records.api.Record`
        """
        for comm_id in comms:
            comm = Community.get(comm_id)
            if comm.has_record(record):
                comm.remove_record(record)  # Handles oai-sets internally
        return record
Beispiel #53
0
    def _remove_accepted_communities(comms, record):
        """Remove accepted communities.

        :param comms: Already accepted community IDs which no longer
                      should have this record.
        :type comms: list of str
        :param record: Record corresponding to this deposit.
        :type record: `invenio_records.api.Record`
        :returns: modified 'record' argument
        :rtype: `invenio_records.api.Record`
        """
        for comm_id in comms:
            comm = Community.get(comm_id)
            if comm.has_record(record):
                comm.remove_record(record)  # Handles oai-sets internally
        return record
def test_remove_community_by_key_del(app, db, communities, deposit,
                                     deposit_file):
    """Test removal of communities by key deletion.

    Communities can be removed by not providing or deleting the communities
    from the key deposit. Moreover, the redundant 'empty' keys should not be
    automatically added to deposit nor record.
    """
    # If 'communities' key was not in deposit metadata,
    # it shouldn't be automatically added
    assert 'communities' not in deposit
    deposit = publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    assert 'communities' not in deposit
    assert 'communities' not in record
    assert not record['_oai'].get('sets', [])

    # Request for 'c1' and 'c2'
    deposit = deposit.edit()
    deposit['communities'] = ['c1', 'c2', ]
    deposit = publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    # No reason to have 'communities' in record since nothing was accepted
    assert 'communities' not in record
    assert not record['_oai'].get('sets', [])

    # Accept 'c1'
    c1 = Community.get('c1')
    c1.accept_record(record)
    record.commit()

    pid, record = deposit.fetch_published()
    assert deposit['communities'] == ['c1', 'c2', ]
    assert InclusionRequest.query.count() == 1
    assert record['communities'] == ['c1', ]
    assert set(record['_oai']['sets']) == set(['user-c1'])

    # Remove the key from deposit and publish
    deposit = deposit.edit()
    del deposit['communities']
    deposit = publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    assert 'communities' not in deposit
    assert 'communities' not in record
    assert InclusionRequest.query.count() == 0
    assert not record['_oai'].get('sets', [])
Beispiel #55
0
    def _get_simple_search_community_query(community_id, qs=None):
        """Query parser for simple search.

        :param qs: Query string.
        :return: Query parser.
        """
        # add  Permission filter by publish date and status
        comm = Community.get(community_id)
        root_node_id = comm.root_node_id

        mt = get_permission_filter(root_node_id)
        q = _get_search_qs_query(qs)

        if q:
            mt.append(q)
        mt.extend(_get_detail_keywords_query())
        return Q('bool', must=mt) if mt else Q()
Beispiel #56
0
def test_fixed_communities(app, db, users, communities, deposit, deposit_file,
                           communities_autoadd_enabled):
    """Test automatic adding and requesting to fixed communities."""
    deposit['grants'] = [{'title': 'SomeGrant'}, ]
    # 'c3' is owned by one of the deposit owner
    assert Community.get('c3').id_user in deposit['_deposit']['owners']
    deposit['communities'] = ['c3', ]
    deposit = publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    assert record['communities'] == ['c3', 'grants_comm']
    assert deposit['communities'] == ['c3', 'ecfunded', 'grants_comm',
                                      'zenodo']
    InclusionRequest.query.count() == 2
    ir1 = InclusionRequest.query.filter_by(id_community='zenodo').one()
    assert ir1.id_record == record.id
    ir2 = InclusionRequest.query.filter_by(id_community='ecfunded').one()
    assert ir2.id_record == record.id
Beispiel #57
0
def new():
    """Create a new community."""
    form = CommunityForm(request.values)

    ctx = mycommunities_ctx()
    ctx.update({
        'form': form,
        'is_new': True,
        'community': None,
    })

    if form.validate_on_submit():
        data = copy.deepcopy(form.data)

        community_id = data.pop('identifier')
        del data['logo']

        community = Community.create(
            community_id, current_user.get_id(), **data)

        file = request.files.get('logo', None)
        if file:
            if not community.save_logo(file.stream, file.filename):
                form.logo.errors.append(_(
                    'Cannot add this file as a logo. Supported formats: '
                    'PNG, JPG and SVG. Max file size: 1.5 MB.'))
                db.session.rollback()
                community = None

        if community:
            permissions = _get_permissions()
            for permission in permissions:
                db.session.add(ActionUsers(action=permission,
                               user=current_user,
                               argument=community_id))
            db.session.commit()
            flash("{} was successfully created.".format(
                    current_app.config["COMMUNITIES_NAME"].capitalize()),
                  category='success')
            return redirect(url_for('.edit', community_id=community.id))

    return render_template(
        "/invenio_communities/new.html",
        community_form=form,
        **ctx
    )
Beispiel #58
0
def community_list():
    """Index page with uploader and list of existing depositions."""
    ctx = mycommunities_ctx()
    from weko_theme.utils import get_design_layout
    # Get the design for widget rendering
    render_page, render_widgets = get_design_layout(
        current_app.config['WEKO_THEME_DEFAULT_COMMUNITY'])
    p = request.args.get('p', type=str)
    so = request.args.get('so', type=str)
    page = request.args.get('page', type=int, default=1)

    so = so or current_app.config.get('COMMUNITIES_DEFAULT_SORTING_OPTION')

    communities = Community.filter_communities(p, so)
    featured_community = FeaturedCommunity.get_featured_or_none()
    form = SearchForm(p=p)
    per_page = 10
    page = max(page, 1)
    p = Pagination(page, per_page, communities.count())

    ctx.update({
        'r_from':
        max(p.per_page * (p.page - 1), 0),
        'r_to':
        min(p.per_page * p.page, p.total_count),
        'r_total':
        p.total_count,
        'pagination':
        p,
        'form':
        form,
        'title':
        _('Communities'),
        'communities':
        communities.slice(per_page * (page - 1), per_page * page).all(),
        'featured_community':
        featured_community,
    })

    return render_template('invenio_communities/communities_list.html',
                           page=render_page,
                           render_widgets=render_widgets,
                           **ctx)
def test_fixed_autoadd_redundant(app, db, users, communities, deposit,
                                 deposit_file, communities_autoadd_enabled):
    """Test automatic adding and requesting to fixed communities."""
    deposit['grants'] = [{'title': 'SomeGrant'}, ]
    # 'c3' is owned by one of the deposit owner
    assert Community.get('c3').id_user in deposit['_deposit']['owners']
    # Requesting for 'grants_comm', which would be added automatically
    # shouldn't cause problems
    deposit['communities'] = ['c3', 'grants_comm', 'zenodo']
    deposit = publish_and_expunge(db, deposit)
    pid, record = deposit.fetch_published()
    assert record['communities'] == ['c3', 'grants_comm']
    assert deposit['communities'] == ['c3', 'ecfunded', 'grants_comm',
                                      'zenodo']
    InclusionRequest.query.count() == 2
    ir1 = InclusionRequest.query.filter_by(id_community='zenodo').one()
    assert ir1.id_record == record.id
    ir2 = InclusionRequest.query.filter_by(id_community='ecfunded').one()
    assert ir2.id_record == record.id