def draft_field_set(user_id, uuid, field_name, value):
    """ Alters the value of a field """

    Workflow.set_extra_data(user_id=user_id,
                            uuid=uuid,
                            setter=draft_setter(key=field_name,
                                                value=value,
                                                field_setter=True))
def preingest_form_data(user_id,
                        form_data,
                        uuid=None,
                        append=False,
                        cached_data=False):
    """Used to insert form data to the workflow before running it
    Creates an identical json structure to the draft json.
    If cached_data is enabled, the data will be used by the next workflow
    initiated by the user, so the uuid can be ommited in this case.

    @param user_id: the user id

    @param uuid: the id of the workflow

    @param form_data: a json with field_name -> value structure

    @param append: set to True if you want to append the values to the existing
                   ones

    @param cached_data: set to True if you want to cache the data.
    """
    def preingest_data(form_data, append):
        def preingest(json):
            if 'pop_obj' not in json:
                json['pop_obj'] = {}
            for field, value in form_data.items():
                if append:
                    try:
                        if isinstance(json['pop_obj'][field], list):
                            json['pop_obj'][field].append(value)
                        else:
                            new_values_list = [json['pop_obj'][field]]
                            new_values_list.append(value)
                            json['pop_obj'][field] = new_values_list
                    except KeyError:
                        json['pop_obj'][field] = [value]
                else:
                    json['pop_obj'][field] = value
            json['pop_obj']['timestamp'] = str(datetime.now())

        return preingest

    if cached_data:
        cache.set(str(user_id) + ':cached_form_data', form_data)
    else:
        Workflow.set_extra_data(user_id=user_id,
                                uuid=uuid,
                                setter=preingest_data(form_data, append))

        # Ingest the data in the forms, in case there are any
        if append:
            for field_name, value in form_data.items():
                draft_field_list_add(user_id, uuid, field_name, value)
        else:
            for field_name, value in form_data.items():
                draft_field_set(user_id, uuid, field_name, value)
def set_form_status(user_id, uuid, status, step=None):
    try:
        Workflow.set_extra_data(user_id=user_id,
                                uuid=uuid,
                                setter=draft_setter(step, 'status', status))
    except ValueError:
        # No drafts found
        raise NoResultFound
    except NoResultFound:
        return None
def save_form(user_id, uuid, form):
    """
    Saves the draft form_values and form_field_flags of a form.
    """
    json_data = dict((key, value) for key, value in form.json_data.items()
                     if value is not None)

    draft_data_update = {
        'form_values': json_data,
        'form_field_flags': form.get_flags(),
    }

    Workflow.set_extra_data(user_id=user_id,
                            uuid=uuid,
                            setter=draft_setter(data=draft_data_update))
示例#5
0
    def render(obj, eng):
        from invenio.webdeposit_utils import CFG_DRAFT_STATUS, add_draft, \
            get_preingested_form_data, preingest_form_data

        uuid = eng.uuid
        user_id = obj.data['user_id']
        # TODO: get the current step from the object
        step = max(obj.get_current_task())  # data['step']
        form_type = form.__name__

        if obj.data.has_key(
                'form_values') and obj.data['form_values'] is not None:
            form_values = obj.data['form_values']
        else:
            form_values = {}
        # Prefill the form from cache
        cached_form = get_preingested_form_data(user_id, cached_data=True)

        # Check for preingested data from webdeposit API
        preingested_form_data = get_preingested_form_data(user_id, uuid)
        if preingested_form_data != {} and preingested_form_data is not None:
            form_data = preingested_form_data
        elif cached_form is not None:
            form_data = cached_form
            # Clear cache
            preingest_form_data(user_id, None, cached_data=True)
        else:
            form_data = {}

        # Filter the form_data to match the current form
        for field in form():
            if field.name in form_data:
                form_values[field.name] = form_data[field.name]

        draft = dict(form_type=form_type,
                     form_values=form_values,
                     status=CFG_DRAFT_STATUS['unfinished'],
                     timestamp=str(datetime.now()),
                     step=step)

        Workflow.set_extra_data(user_id=user_id,
                                uuid=uuid,
                                setter=add_draft(draft))
def draft_field_list_add(user_id,
                         uuid,
                         field_name,
                         value,
                         dummy_subfield=None):
    """Adds value to field
    Used for fields that contain multiple values
    e.g.1: { field_name : value1 } OR
           { field_name : [value1] }
           -->
           { field_name : [value1, value2] }
    e.g.2  { }
           -->
           { field_name : [value] }
    e.g.3  { }
           -->
           { field_name : {key : value} }
    """

    Workflow.set_extra_data(user_id=user_id,
                            uuid=uuid,
                            setter=draft_field_list_setter(field_name, value))
示例#7
0
    def test_record_creation(self):
        import os
        from wtforms import TextAreaField
        from datetime import datetime

        from invenio.search_engine import record_exists
        from invenio.cache import cache
        from invenio.config import CFG_PREFIX
        from invenio.webuser_flask import login_user
        from invenio.bibworkflow_model import Workflow
        from invenio.bibworkflow_config import CFG_WORKFLOW_STATUS
        from invenio.bibsched_model import SchTASK

        from invenio.webdeposit_utils import get_form, create_workflow, \
            set_form_status, CFG_DRAFT_STATUS
        from invenio.webdeposit_load_deposition_types import \
            deposition_metadata
        from invenio.webdeposit_workflow_utils import \
            create_record_from_marc
        from invenio.bibfield import get_record

        login_user(1)
        for deposition_type in deposition_metadata.keys():

            deposition = create_workflow(deposition_type, 1)
            assert deposition is not None

            # Check if deposition creates a record
            create_rec = create_record_from_marc()
            function_exists = False
            for workflow_function in deposition.workflow:
                if create_rec.func_code == workflow_function.func_code:
                    function_exists = True
            if not function_exists:
                # if a record is not created,
                #continue with the next deposition
                continue

            uuid = deposition.get_uuid()

            cache.delete_many("1:current_deposition_type", "1:current_uuid")
            cache.add("1:current_deposition_type", deposition_type)
            cache.add("1:current_uuid", uuid)

            # Run the workflow
            deposition.run()

            # Create form's json based on the field name
            form = get_form(1, uuid=uuid)
            webdeposit_json = {}

            # Fill the json with dummy data
            for field in form:
                if isinstance(field, TextAreaField):
                    # If the field is associated with a marc field
                    if field.has_recjson_key() or field.has_cook_function():
                        webdeposit_json[field.name] = "test " + field.name

            draft = dict(
                form_type=form.__class__.__name__,
                form_values=webdeposit_json,
                step=0,  # dummy step
                status=CFG_DRAFT_STATUS['finished'],
                timestamp=str(datetime.now()))

            # Add a draft for the first step
            Workflow.set_extra_data(user_id=1,
                                    uuid=uuid,
                                    key='drafts',
                                    value={0: draft})

            workflow_status = CFG_WORKFLOW_STATUS.RUNNING
            while workflow_status != CFG_WORKFLOW_STATUS.COMPLETED:
                # Continue workflow
                deposition.run()
                set_form_status(1, uuid, CFG_DRAFT_STATUS['finished'])
                workflow_status = deposition.get_status()

            # Workflow is finished. Test if record is created
            recid = deposition.get_data('recid')
            assert recid is not None
            # Test that record id exists
            assert record_exists(recid) == 1

            # Test that the task exists
            task_id = deposition.get_data('task_id')
            assert task_id is not None

            bibtask = SchTASK.query.filter(SchTASK.id == task_id).first()
            assert bibtask is not None

            # Run bibupload, bibindex, webcoll manually
            cmd = "%s/bin/bibupload %s" % (CFG_PREFIX, task_id)
            assert not os.system(cmd)
            rec = get_record(recid)
            marc = rec.legacy_export_as_marc()
            for field in form:
                if isinstance(field, TextAreaField):
                    # If the field is associated with a marc field
                    if field.has_recjson_key() or field.has_cook_function():
                        assert "test " + field.name in marc
示例#8
0
    def export(obj, eng):
        user_id = obj.data['user_id']
        uuid = eng.uuid
        steps_num = obj.data['steps_num']

        from invenio.webdeposit_utils import get_form
        from invenio.webdeposit_load_deposition_types import deposition_metadata
        json_reader = JsonReader()

        try:
            pop_obj = Workflow.get_extra_data(user_id=user_id,
                                              uuid=uuid,
                                              key='pop_obj')
        except KeyError:
            pop_obj = None

        form_data = {}
        if 'form_values' in obj.data or pop_obj is not None:

            # copy the form values to be able to
            # delete the fields in the workflow object during iteration
            form_data = pop_obj or obj.data['form_values']

        # Populate the form with data
        for step in range(steps_num):
            form = get_form(user_id, uuid, step)

            # Insert the fields' values in bibfield's rec_json dictionary
            if form is not None:  # some steps don't have any form ...
                # Populate preingested data
                for field in form:
                    if field.name in form_data:
                        field.data = form_data.pop(field.name)
                json_reader = form.cook_json(json_reader)

        deposition_type = \
            db.session.query(Workflow.name).\
            filter(Workflow.id_user == user_id,
                   Workflow.uuid == uuid).\
            one()[0]

        # Get the collection from configuration
        if 'collection' in deposition_metadata[deposition_type]:
            json_reader['collection.primary'] = \
                deposition_metadata[deposition_type]['collection']
        else:
            json_reader['collection.primary'] = deposition_type

        if 'recid' not in json_reader or 'record ID' not in json_reader:
            # Record is new, reserve record id
            recid = run_sql(
                "INSERT INTO bibrec (creation_date, modification_date) VALUES (NOW(), NOW())"
            )
            json_reader['recid'] = recid
            obj.data['recid'] = recid
        else:
            obj.data['recid'] = json_reader['recid']
            obj.data['title'] = json_reader['title.title']

        Workflow.set_extra_data(user_id=user_id,
                                uuid=uuid,
                                key='recid',
                                value=obj.data['recid'])

        obj.data['marc'] = json_reader.legacy_export_as_marc()