Exemplo n.º 1
0
def register_item_metadata(item):
    """Upload file content.

    :argument
        list_record    -- {list} list item import.
        file_path      -- {str} file path.
    """
    item_id = str(item.get('id'))
    try:
        pid = PersistentIdentifier.query.filter_by(
            pid_type='recid',
            pid_value=item_id
        ).first()

        record = WekoDeposit.get_record(pid.object_uuid)

        _deposit_data = record.dumps().get("_deposit")
        deposit = WekoDeposit(record, record.model)
        new_data = dict(
            **item.get('metadata'),
            **_deposit_data,
            **{
                '$schema': item.get('$schema'),
                'title': handle_get_title(item.get('Title')),
            }
        )
        item_status = {
            'index': new_data['path'],
            'actions': 'publish',
        }
        if not new_data.get('pid'):
            new_data = dict(**new_data, **{
                'pid': {
                    'revision_id': 0,
                    'type': 'recid',
                    'value': item_id
                }
            })
        deposit.update(item_status, new_data)
        deposit.commit()
        deposit.publish()
        with current_app.test_request_context():
            first_ver = deposit.newversion(pid)
            if first_ver:
                first_ver.publish()
        db.session.commit()

    except Exception as ex:
        db.session.rollback()
        current_app.logger.error('item id: %s update error.' % item_id)
        current_app.logger.error(ex)
        return {
            'success': False,
            'error': str(ex)
        }
    return {
        'success': True
    }
Exemplo n.º 2
0
def process_item(record, resync, counter):
    """Process item."""
    event_counter('processed_items', counter)
    event = ItemEvents.INIT
    xml = etree.tostring(record, encoding='utf-8').decode()
    mapper = JPCOARMapper(xml)

    resyncid = PersistentIdentifier.query.filter_by(
        pid_type='syncid',
        pid_value=gen_resync_pid_value(resync, mapper.identifier())).first()
    if resyncid:
        r = RecordMetadata.query.filter_by(id=resyncid.object_uuid).first()
        recid = PersistentIdentifier.query.filter_by(
            pid_type='recid', object_uuid=resyncid.object_uuid).first()
        recid.status = PIDStatus.REGISTERED
        pubdate = dateutil.parser.parse(
            r.json['pubdate']['attribute_value']).date()
        dep = WekoDeposit(r.json, r)
        indexes = dep['path'].copy()
        event = ItemEvents.UPDATE
    elif mapper.is_deleted():
        return
    else:
        dep = WekoDeposit.create({})
        PersistentIdentifier.create(pid_type='syncid',
                                    pid_value=gen_resync_pid_value(
                                        resync, mapper.identifier()),
                                    status=PIDStatus.REGISTERED,
                                    object_type=dep.pid.object_type,
                                    object_uuid=dep.pid.object_uuid)
        indexes = []
        event = ItemEvents.CREATE
    indexes.append(str(resync.index_id)) if str(
        resync.index_id) not in indexes else None

    if mapper.is_deleted():
        soft_delete(recid.pid_value)
        event = ItemEvents.DELETE
    else:
        json = mapper.map()
        json['$schema'] = '/items/jsonschema/' + str(mapper.itemtype.id)
        dep['_deposit']['status'] = 'draft'
        dep.update({'actions': 'publish', 'index': indexes}, json)
        dep.commit()
        dep.publish()
        # add item versioning
        pid = PersistentIdentifier.query.filter_by(
            pid_type='recid', pid_value=dep.pid.pid_value).first()
        with current_app.test_request_context() as ctx:
            first_ver = dep.newversion(pid)
            first_ver.publish()
    db.session.commit()
    if event == ItemEvents.CREATE:
        event_counter('created_items', counter)
    elif event == ItemEvents.UPDATE:
        event_counter('updated_items', counter)
    elif event == ItemEvents.DELETE:
        event_counter('deleted_items', counter)
Exemplo n.º 3
0
def prepare_edit_item():
    """Prepare_edit_item.

    Host the api which provide 2 service:
        Create new activity for editing flow
        Check permission: check if user is owner/admin/shared user
    request:
        header: Content type must be json
        data:
            pid_value: pid_value
    return: The result json:
        code: status code,
        msg: meassage result,
        data: url redirect
    """
    def _get_workflow_by_item_type_id(item_type_name_id, item_type_id):
        """Get workflow settings by item type id."""
        workflow = WorkFlow.query.filter_by(itemtype_id=item_type_id).first()
        if not workflow:
            item_type_list = ItemTypes.get_by_name_id(item_type_name_id)
            id_list = [x.id for x in item_type_list]
            workflow = (WorkFlow.query.filter(
                WorkFlow.itemtype_id.in_(id_list)).order_by(
                    WorkFlow.itemtype_id.desc()).order_by(
                        WorkFlow.flow_id.asc()).first())
        return workflow

    if request.headers['Content-Type'] != 'application/json':
        """Check header of request"""
        return jsonify(code=-1, msg=_('Header Error'))
    post_activity = request.get_json()
    pid_value = post_activity.get('pid_value')

    if pid_value:
        try:
            record = WekoRecord.get_record_by_pid(pid_value)
            owner = str(record.get('owner'))
            shared_id = str(record.get('weko_shared_id'))
            user_id = str(get_current_user())
            is_admin = get_user_roles()
            activity = WorkActivity()

            pid_object = PersistentIdentifier.get('recid', pid_value)

            latest_pid = PIDVersioning(child=pid_object).last_child

            # check user's permission
            if user_id != owner and not is_admin[0] and user_id != shared_id:
                return jsonify(
                    code=-1, msg=_(r"You are not allowed to edit this item."))
            lists = ItemTypes.get_latest()
            if not lists:
                return jsonify(code=-1,
                               msg=_(r"You do not even have an Itemtype."))
            item_type_id = record.get('item_type_id')
            item_type = ItemTypes.get_by_id(item_type_id)
            if not item_type:
                return jsonify(code=-1, msg=_(r"This itemtype isn't found."))

            # check item is being editied
            item_id = latest_pid.object_uuid
            workflow_activity = activity.get_workflow_activity_by_item_id(
                item_id)
            if not workflow_activity:
                # get workflow of first record attached version ID: x.1
                workflow_activity = activity.get_workflow_activity_by_item_id(
                    pid_object.object_uuid)
                # if workflow of the item is not found
                # use default settings of item type to which the item belongs
            else:
                # show error when has stt is Begin or Doing
                if workflow_activity.action_status == \
                    ActionStatusPolicy.ACTION_BEGIN \
                    or workflow_activity.action_status == \
                        ActionStatusPolicy.ACTION_DOING:
                    return jsonify(code=-1,
                                   msg=_(r"The workflow is being edited."))

            # prepare params for new workflow activity
            if workflow_activity:
                post_activity['workflow_id'] = workflow_activity.workflow_id
                post_activity['flow_id'] = workflow_activity.flow_id
            else:
                workflow = _get_workflow_by_item_type_id(
                    item_type.name_id, item_type_id)
                if not workflow:
                    return jsonify(code=-1,
                                   msg=_('Workflow setting does not exist.'))
                post_activity['workflow_id'] = workflow.id
                post_activity['flow_id'] = workflow.flow_id
            post_activity['itemtype_id'] = item_type_id
            getargs = request.args
            community = getargs.get('community', None)

            # Create a new version of a record.
            record = WekoDeposit.get_record(item_id)
            if not record:
                return jsonify(code=-1, msg=_('Record does not exist.'))

            deposit = WekoDeposit(record, record.model)
            draft_record = deposit.newversion(pid_object)

            if not draft_record:
                return jsonify(code=-1, msg=_('An error has occurred.'))

            # Create snapshot bucket for draft record
            from invenio_records_files.models import RecordsBuckets
            try:
                with db.session.begin_nested():
                    from weko_workflow.utils import delete_bucket
                    draft_deposit = WekoDeposit(draft_record,
                                                draft_record.model)
                    snapshot = record.files.bucket.snapshot(lock=False)
                    snapshot.locked = False
                    draft_deposit['_buckets'] = {'deposit': str(snapshot.id)}
                    draft_record_bucket = RecordsBuckets.create(
                        record=draft_record.model, bucket=snapshot)

                    # Remove duplicated buckets
                    draft_record_buckets = RecordsBuckets.query.filter_by(
                        record_id=draft_record.model.id).all()
                    for record_bucket in draft_record_buckets:
                        if record_bucket != draft_record_bucket:
                            delete_bucket_id = record_bucket.bucket_id
                            RecordsBuckets.query.filter_by(
                                bucket_id=delete_bucket_id).delete()
                            delete_bucket(delete_bucket_id)
                    draft_deposit.commit()
            except Exception as ex:
                db.session.rollback()
                current_app.logger.exception(str(ex))
                return jsonify(code=-1, msg=_('An error has occurred.'))

            # Create a new workflow activity.
            rtn = activity.init_activity(post_activity, community,
                                         draft_record.model.id)

            if rtn:
                # GOTO: TEMPORARY EDIT MODE FOR IDENTIFIER
                identifier_actionid = get_actionid('identifier_grant')
                if workflow_activity:
                    identifier = activity.get_action_identifier_grant(
                        workflow_activity.activity_id, identifier_actionid)
                else:
                    identifier = activity.get_action_identifier_grant(
                        '', identifier_actionid)

                if identifier:
                    if identifier.get('action_identifier_select') > \
                            IDENTIFIER_GRANT_DOI:
                        identifier['action_identifier_select'] = \
                            IDENTIFIER_GRANT_CAN_WITHDRAW
                    elif identifier.get('action_identifier_select') == \
                            IDENTIFIER_GRANT_IS_WITHDRAWING:
                        identifier['action_identifier_select'] = \
                            IDENTIFIER_GRANT_WITHDRAWN
                    activity.create_or_update_action_identifier(
                        rtn.activity_id, identifier_actionid, identifier)

                mail_list = FeedbackMailList.get_mail_list_by_item_id(
                    item_id=pid_object.object_uuid)
                if mail_list:
                    activity.create_or_update_action_feedbackmail(
                        activity_id=rtn.activity_id,
                        action_id=ITEM_REGISTRATION_ACTION_ID,
                        feedback_maillist=mail_list)

                if community:
                    comm = GetCommunity.get_community_by_id(community)
                    url_redirect = url_for('weko_workflow.display_activity',
                                           activity_id=rtn.activity_id,
                                           community=comm.id)
                else:
                    url_redirect = url_for('weko_workflow.display_activity',
                                           activity_id=rtn.activity_id)
                return jsonify(code=0,
                               msg='success',
                               data={'redirect': url_redirect})

        except Exception as e:
            current_app.logger.error('Unexpected error: ', str(e))
    return jsonify(code=-1, msg=_('An error has occurred.'))
Exemplo n.º 4
0
def process_item(record, harvesting, counter):
    """Process item."""
    event_counter('processed_items', counter)
    event = ItemEvents.INIT
    xml = etree.tostring(record, encoding='utf-8').decode()
    if harvesting.metadata_prefix == 'oai_dc':
        mapper = DCMapper(xml)
    elif harvesting.metadata_prefix == 'jpcoar' or \
            harvesting.metadata_prefix == 'jpcoar_1.0':
        mapper = JPCOARMapper(xml)
    elif harvesting.metadata_prefix == 'oai_ddi25' or \
            harvesting.metadata_prefix == 'ddi':
        mapper = DDIMapper(xml)
    else:
        return
    hvstid = PersistentIdentifier.query.filter_by(
        pid_type='hvstid', pid_value=mapper.identifier()).first()
    if hvstid:
        r = RecordMetadata.query.filter_by(id=hvstid.object_uuid).first()
        recid = PersistentIdentifier.query.filter_by(
            pid_type='recid', object_uuid=hvstid.object_uuid).first()
        recid.status = PIDStatus.REGISTERED
        pubdate = dateutil.parser.parse(
            r.json['pubdate']['attribute_value']).date()
        dep = WekoDeposit(r.json, r)
        indexes = dep['path'].copy()
        event = ItemEvents.UPDATE
    elif mapper.is_deleted():
        return
    else:
        dep = WekoDeposit.create({})
        PersistentIdentifier.create(pid_type='hvstid',
                                    pid_value=mapper.identifier(),
                                    object_type=dep.pid.object_type,
                                    object_uuid=dep.pid.object_uuid)
        indexes = []
        event = ItemEvents.CREATE
    if int(harvesting.auto_distribution):
        for i in map_indexes(mapper.specs(), harvesting.index_id):
            indexes.append(str(i)) if i not in indexes else None
    else:
        indexes.append(str(harvesting.index_id)) if str(
            harvesting.index_id) not in indexes else None

    if hvstid and pubdate >= mapper.datestamp() and \
       indexes == dep['path'] and harvesting.update_style == '1':
        return

    if mapper.is_deleted():
        soft_delete(recid.pid_value)
        event = ItemEvents.DELETE
    else:
        json = mapper.map()
        json['$schema'] = '/items/jsonschema/' + str(mapper.itemtype.id)
        dep['_deposit']['status'] = 'draft'
        dep.update({'actions': 'publish', 'index': indexes}, json)
        dep.commit()
        dep.publish()
        # add item versioning
        pid = PersistentIdentifier.query.filter_by(
            pid_type='recid', pid_value=dep.pid.pid_value).first()

        idt_list = mapper.identifiers
        from weko_workflow.utils import IdentifierHandle

        idt = IdentifierHandle(pid.object_uuid)
        for it in idt_list:
            if not it.get('type'):
                continue
            pid_type = it['type'].lower()
            pid_obj = idt.get_pidstore(pid_type)
            if not pid_obj:
                idt.register_pidstore(pid_type, it['identifier'])

        with current_app.test_request_context() as ctx:
            first_ver = dep.newversion(pid)
            first_ver.publish()

    harvesting.item_processed = harvesting.item_processed + 1
    db.session.commit()

    if event == ItemEvents.CREATE:
        event_counter('created_items', counter)
    elif event == ItemEvents.UPDATE:
        event_counter('updated_items', counter)
    elif event == ItemEvents.DELETE:
        event_counter('deleted_items', counter)