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))
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))
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
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()