Ejemplo n.º 1
0
    def do_get_component_info(self):
        target_id = self.param_dict.get("target_id", str())
        da_object = DAComponent(target_id, self.component)
        self.context["component_info"] = "welcome to " + str(
            da_object.get_component_count())

        return self.context
Ejemplo n.º 2
0
    def __init__(self, **kwargs):
        self.param_dict = kwargs
        self.context = self.param_dict.get("context", dict())
        self.component = self.param_dict.get("component", str())
        self.visualize = self.param_dict.get("visualize", str())
        self.profile_id = self.param_dict.get("profile_id", str())
        self.auto_fields = self.param_dict.get("auto_fields", dict())

        if self.auto_fields and isinstance(self.auto_fields, str):
            self.auto_fields = json.loads(self.auto_fields)

        self.broker_visuals = BrokerVisuals(**kwargs)
        self.da_object = DAComponent(self.profile_id, self.component)

        da_dict = dict(publication=Publication,
                       person=Person,
                       sample=Sample,
                       source=Source,
                       profile=Profile,
                       datafile=DataFile,
                       submission=Submission,
                       annotation=Annotation,
                       cgcore=CGCore,
                       metadata_template=MetadataTemplate)

        if self.component in da_dict:
            self.da_object = da_dict[self.component](self.profile_id)
Ejemplo n.º 3
0
    def get_display_name(self):
        """
        sets display name for Dataset
        :return:
        """

        profile = DAComponent(component="profile").get_record(
            self.submission_record.get("profile_id", str()))

        return profile.get("title", str())
Ejemplo n.º 4
0
def generate_copo_form(component=str(), target_id=str(), component_dict=dict(), message_dict=dict(), profile_id=str(),
                       **kwargs):
    # message_dict templates are defined in the lookup dictionary: "MESSAGES_LKUPS"

    label_dict = get_labels()

    da_object = DAComponent(component=component, profile_id=profile_id)

    if component in da_dict:
        da_object = da_dict[component](profile_id)

    form_value = component_dict

    # get record, if in edit mode
    if target_id:
        form_value = da_object.get_record(target_id)

    form_schema = list()

    # get schema fields
    for f in da_object.get_component_schema(**kwargs):
        if f.get("show_in_form", True):

            # if required, resolve data source for select-type controls,
            # i.e., if a callback is defined on the 'option_values' field
            if "option_values" in f or f.get("control", "text") in ["copo-lookup", "copo-lookup2"]:
                f['data'] = form_value.get(f["id"].split(".")[-1], str())
                f["option_values"] = get_control_options(f)

            # resolve values for unique items...
            # if a list of unique items is provided with the schema, use it, else dynamically
            # generate unique items based on the component records
            if "unique" in f and not f.get("unique_items", list()):
                f["unique_items"] = generate_unique_items(component=component, profile_id=profile_id,
                                                          elem_id=f["id"].split(".")[-1], record_id=target_id, **kwargs)

            # filter based on sample type
            if component == "sample" and not filter_sample_type(form_value, f):
                continue

            form_schema.append(f)

    if form_value:
        form_value["_id"] = str(target_id)
    else:
        form_value = str()

    return dict(component_name=component,
                form_label=label_dict.get(component, dict()).get("label", str()),
                form_value=form_value,
                target_id=target_id,
                form_schema=form_schema,
                form_message=message_dict,
                )
Ejemplo n.º 5
0
def resolve_copo_datafile_id_data(data, elem):
    resolved_data = dict()

    da_object = DAComponent(component="datafile")

    if data:
        datafile = da_object.get_record(data)
        resolved_data["recordLabel"] = datafile.get("name", str())
        resolved_data["recordID"] = data

    return resolved_data
Ejemplo n.º 6
0
def generate_attributes(component, target_id):
    da_object = DAComponent(component=component)

    if component in da_dict:
        da_object = da_dict[component]()

    # get and filter schema elements based on displayable columns
    schema = [x for x in da_object.get_schema().get("schema_dict") if x.get("show_as_attribute", False)]

    # build db column projection
    projection = [(x["id"].split(".")[-1], 1) for x in schema]

    # account for description metadata in datafiles
    if component == "datafile":
        projection.append(('description', 1))

    filter_by = dict(_id=ObjectId(target_id))
    record = da_object.get_all_records_columns(projection=dict(projection), filter_by=filter_by)

    result = dict()

    if len(record):
        record = record[0]

        if component == "sample":  # filter based on sample type
            sample_types = [s_t['value'] for s_t in d_utils.get_sample_type_options()]
            sample_type = record.get("sample_type", str())
            schema = [x for x in schema if sample_type in x.get("specifications", sample_types)]

        for x in schema:
            x['id'] = x["id"].split(".")[-1]

        if component == "datafile":
            key_split = "___0___"
            attributes = record.get("description", dict()).get("attributes", dict())
            stages = record.get("description", dict()).get("stages", list())

            datafile_attributes = dict()
            datafile_items = list()

            for st in stages:
                for item in st.get("items", list()):
                    if str(item.get("hidden", False)).lower() == "false":
                        atrib_val = attributes.get(st["ref"], dict()).get(item["id"], str())
                        item["id"] = st["ref"] + key_split + item["id"]
                        datafile_attributes[item["id"]] = atrib_val
                        datafile_items.append(item)

            record.update(datafile_attributes)
            schema = schema + datafile_items

        result = resolve_display_data(schema, record)

    return result
Ejemplo n.º 7
0
    def get_resolve(self, component=str()):
        da_object = DAComponent(component=component)

        message_display_templates = d_utils.json_to_pytype(
            lkup.MESSAGES_LKUPS["message_templates"])["templates"]
        lookup_messages = d_utils.json_to_pytype(
            lkup.MESSAGES_LKUPS["lookup_messages"])["properties"]
        component_dict = dict()
        message_dict = dict()

        resolved_dict = self.publication_metadata()

        if resolved_dict.get("status") == "success":
            message_dict = message_display_templates.get("success", dict())
            message_dict["text"] = lookup_messages.get(
                "doi_metadata_crosscheck", str()).get("text", str())
            for f in da_object.get_schema().get("schema"):
                data_dict = resolved_dict.get("data", dict())
                key = f.id.split(".")[-1]
                if key in data_dict:
                    val = data_dict[key]
                    # reconcile schema type mismatch
                    if isinstance(val, list) and f.type == "string":
                        val = ','.join(str(e)
                                       for e in val)  # account for numbers
                    if isinstance(val, str) and f.type == "object":
                        object_type_control = d_utils.object_type_control_map(
                        ).get(f.control.lower(), str())
                        if object_type_control == "ontology_annotation":
                            object_schema = d_utils.get_db_json_schema(
                                object_type_control)
                            value_dict = dict(annotationValue=val)
                            for k in object_schema:
                                object_schema[k] = value_dict.get(
                                    k,
                                    d_utils.default_jsontype(
                                        object_schema.get(k, dict()).get(
                                            "type", "object")))

                            val = object_schema
                    component_dict[key] = val

                if key not in component_dict:  # set default values based on type
                    component_dict[key] = d_utils.default_jsontype(f.type)
        else:
            error_list = resolved_dict.get("error", list())
            message_dict = message_display_templates.get("danger", dict())
            message_dict["text"] = '; '.join(
                str(e) for e in error_list) + lookup_messages.get(
                    "doi_metadata_error", str()).get("text", str())

        return dict(component_dict=component_dict, message_dict=message_dict)
Ejemplo n.º 8
0
def generate_unique_items(component=str(), profile_id=str(), elem_id=str(), record_id=str(), **kwargs):
    da_object = DAComponent(component=component, profile_id=profile_id)
    action_type = kwargs.get("action_type", str())
    component_records = list()

    all_records = da_object.get_all_records()

    if action_type == "cloning":
        component_records = [x[elem_id] for x in all_records if elem_id in x]
    else:
        component_records = [x[elem_id] for x in all_records if elem_id in x and not str(x["_id"]) == record_id]

    return component_records
Ejemplo n.º 9
0
def generate_copo_form(component=str(), target_id=str(), component_dict=dict(), message_dict=dict(), profile_id=str()):
    # message_dict templates are defined in the lookup dictionary, "MESSAGES_LKUPS"

    label_dict = dict(publication=dict(label="Publication", clonable=False),
                      person=dict(label="Person", clonable=False),
                      sample=dict(label="Sample", clonable=False),
                      source=dict(label="Source", clonable=True),
                      profile=dict(label="Profile", clonable=False),
                      annotation=dict(label="Annotation", clonable=False),
                      )

    da_object = DAComponent(component=component, profile_id=profile_id)

    form_value = component_dict

    # get record, if in edit mode
    if target_id:
        form_value = da_object.get_record(target_id)

    form_schema = list()

    # get schema fields
    for f in da_object.get_schema().get("schema_dict"):
        if f.get("show_in_form", True):

            # if required, resolve data source for select-type controls,
            # i.e., if a callback is defined on the 'option_values' field

            if "option_values" in f:
                f["option_values"] = get_control_options(f)

            # filter based on sample type
            if component == "sample" and not filter_sample_type(form_value, f):
                continue

            form_schema.append(f)

    # get all records: used in the UI for 'cloning' and other purposes
    component_records = generate_component_records(component, profile_id)
    # if label_dict.get(component, dict()).get("clonable", False):
    #     component_records = generate_component_records(component, profile_id)

    return dict(component_name=component,
                form_label=label_dict.get(component, dict()).get("label", str()),
                form_value=form_value,
                target_id=target_id,
                form_schema=form_schema,
                form_message=message_dict,
                component_records=component_records,
                clonable=label_dict.get(component, dict()).get("clonable", False),
                )
Ejemplo n.º 10
0
def generate_component_records(component=str(), profile_id=str()):
    da_object = DAComponent(component=component, profile_id=profile_id)
    component_records = list()

    for record in da_object.get_all_records():
        rec_dict = dict(_id=str(record["_id"]))
        for f in da_object.get_schema().get("schema_dict"):
            if f.get("show_in_form", True):
                key_split = f["id"].split(".")[-1]
                rec_dict[key_split] = record.get(key_split, d_utils.default_jsontype(f.get("type", str())))

        component_records.append(rec_dict)

    return component_records
Ejemplo n.º 11
0
    def __init__(self, **kwargs):
        self.param_dict = kwargs
        self.context = self.param_dict.get("context", dict())
        self.component = self.param_dict.get("component", str())
        self.visualize = self.param_dict.get("visualize", str())
        self.profile_id = self.param_dict.get("profile_id", str())
        self.auto_fields = self.param_dict.get("auto_fields", dict())

        if self.auto_fields and isinstance(self.auto_fields, str):
            self.auto_fields = ast.literal_eval(self.auto_fields)

        self.broker_visuals = BrokerVisuals(**kwargs)
        self.da_object = DAComponent(self.profile_id, self.component)

        da_dict = dict(
            publication=Publication,
            person=Person,
            sample=Sample,
            source=Source,
            profile=Profile,
            datafile=DataFile,
            submission=Submission,
            annotation=Annotation
        )

        if da_dict.get(self.component):
            self.da_object = da_dict[self.component](self.profile_id)
Ejemplo n.º 12
0
    def get_resolve(self, component=str()):
        da_object = DAComponent(component=component)

        message_display_templates = d_utils.json_to_pytype(lkup.MESSAGES_LKUPS["message_templates"])["templates"]
        lookup_messages = d_utils.json_to_pytype(lkup.MESSAGES_LKUPS["lookup_messages"])["properties"]
        component_dict = dict()
        message_dict = dict()

        resolved_dict = self.publication_metadata()

        if resolved_dict.get("status") == "success":
            message_dict = message_display_templates.get("success", dict())
            message_dict["text"] = lookup_messages.get("doi_metadata_crosscheck", str()).get("text", str())
            for f in da_object.get_schema().get("schema"):
                data_dict = resolved_dict.get("data", dict())
                key = f.id.split(".")[-1]
                if key in data_dict:
                    val = data_dict[key]
                    # reconcile schema type mismatch
                    if isinstance(val, list) and f.type == "string":
                        val = ','.join(str(e) for e in val)  # account for numbers
                    if isinstance(val, str) and f.type == "object":
                        object_type_control = d_utils.control_to_schema_name(f.control.lower())
                        if object_type_control == "ontology_annotation":
                            object_schema = d_utils.get_isa_schema(object_type_control)
                            value_dict = dict(annotationValue=val
                                              )
                            for k in object_schema:
                                object_schema[k] = value_dict.get(k, d_utils.default_jsontype(
                                    object_schema.get(k, dict()).get("type", "object")))

                            val = object_schema
                    component_dict[key] = val

                if key not in component_dict:  # set default values based on type
                    component_dict[key] = d_utils.default_jsontype(f.type)
        else:
            error_list = resolved_dict.get("error", list())
            message_dict = message_display_templates.get("danger", dict())
            message_dict["text"] = '; '.join(
                str(e) for e in error_list) + lookup_messages.get("doi_metadata_error", str()).get("text", str())

        return dict(component_dict=component_dict,
                    message_dict=message_dict
                    )
Ejemplo n.º 13
0
def generate_component_records(component=str(), profile_id=str(), label_key=str(), **kwargs):
    da_object = DAComponent(component=component, profile_id=profile_id)

    if component in da_dict:
        da_object = da_dict[component](profile_id)

    component_records = list()
    schema = da_object.get_component_schema(**kwargs)

    # if label_key is not provided, we will assume the first element in the schema to be the label_key

    if not label_key:
        label_key = schema[0]["id"].split(".")[-1] if schema else ''

    for record in da_object.get_all_records(**kwargs):
        option = dict(value=str(record["_id"]), label=record.get(label_key, "N/A"))
        component_records.append(option)

    return component_records
Ejemplo n.º 14
0
def generate_table_columns(component=str()):
    da_object = DAComponent(component=component)

    # get and filter schema elements based on displayable columns
    schema = [x for x in da_object.get_schema().get("schema_dict") if x.get("show_in_table", True)]

    columns = list()
    columns.append(dict(data="record_id", visible=False))
    detail_dict = dict(className='summary-details-control detail-hover-message', orderable=False, data=None,
                       title='', defaultContent='', width="5%")

    columns.insert(0, detail_dict)

    # get indexed fields - only fields that are indexed can be ordered when using server-side processing
    indexed_fields = list()

    for k, v in da_object.get_collection_handle().index_information().items():
        indexed_fields.append(v['key'][0][0])

    for x in schema:
        x["id"] = x["id"].split(".")[-1]
        orderable = False
        if x["id"] in indexed_fields:
            orderable = True
        columns.append(dict(data=x["id"], title=x["label"], orderable=orderable))

    # add column for annotation control
    if component == "datafile":
        special_dict = dict(className='annotate-datafile', orderable=False, data=None,
                            title='', width="1%",
                            defaultContent='<span title="Annotate datafile" style="cursor: '
                                           'pointer;" class="copo-tooltip">'
                                           '<i class="ui icon violet write" aria-hidden="true"></i></span>')
        columns.append(special_dict)

    return columns
Ejemplo n.º 15
0
def get_record_data(record_object=dict(), component=str()):
    # This function is targeted for tabular record display for a single row data

    schema = DAComponent(component=component).get_schema().get("schema_dict")

    row = list()

    for f in schema:
        if f.get("show_in_table", True):
            row.append(resolve_control_output(record_object, f))

    row.append(str(record_object["_id"]))  # last element in a row exposes the id of the record

    return_dict = dict(row_data=row,
                       table_id=table_id_dict.get(component, str())
                       )

    return return_dict
Ejemplo n.º 16
0
def generate_copo_table_data(profile_id=str(), component=str()):
    # This method generates the 'json' for building an UI table

    # instantiate data access object
    da_object = DAComponent(profile_id, component)

    # get records
    records = da_object.get_all_records()

    columns = list()
    dataSet = list()

    displayable_fields = list()

    # headers
    for f in da_object.get_schema().get("schema_dict"):
        if f.get("show_in_table", True):
            displayable_fields.append(f)
            columns.append(dict(title=f["label"]))

    columns.append(dict(title=str()))  # extra 'blank' header for record actions column

    # data
    for rec in records:
        row = list()
        for df in displayable_fields:
            row.append(resolve_control_output(rec, df))

        row.append(str(rec["_id"]))  # last element in a row exposes the id of the record
        dataSet.append(row)

    # define action buttons
    button_templates = d_utils.get_button_templates()

    common_btn_dict = dict(row_btns=[button_templates['edit_row'], button_templates['delete_row']],
                           global_btns=[button_templates['delete_global']])

    sample_info = copy.deepcopy(button_templates['info_row'])
    sample_info["text"] = "Sample Attributes"

    buttons_dict = dict(publication=common_btn_dict,
                        person=common_btn_dict,
                        sample=dict(row_btns=[sample_info, button_templates['edit_row'],
                                              button_templates['delete_row']],
                                    global_btns=[button_templates['add_new_samples_global'],
                                                 button_templates['delete_global']]),
                        source=common_btn_dict,
                        profile=common_btn_dict,
                        annotation=common_btn_dict,
                        metadata_template=common_btn_dict,
                        datafile=dict(
                            row_btns=[button_templates['info_row'], button_templates['describe_row'],
                                      button_templates['delete_row']],
                            global_btns=[button_templates['describe_global'],
                                         button_templates['undescribe_global']])
                        )

    action_buttons = dict(row_btns=buttons_dict.get(component).get("row_btns"),
                          global_btns=buttons_dict.get(component).get("global_btns")
                          )

    return_dict = dict(columns=columns,
                       dataSet=dataSet,
                       table_id=table_id_dict.get(component, str()),
                       action_buttons=action_buttons
                       )

    return return_dict
Ejemplo n.º 17
0
class BrokerDA:
    def __init__(self, **kwargs):
        self.param_dict = kwargs
        self.context = self.param_dict.get("context", dict())
        self.component = self.param_dict.get("component", str())
        self.visualize = self.param_dict.get("visualize", str())
        self.profile_id = self.param_dict.get("profile_id", str())
        self.auto_fields = self.param_dict.get("auto_fields", dict())

        if self.auto_fields and isinstance(self.auto_fields, str):
            self.auto_fields = ast.literal_eval(self.auto_fields)

        self.broker_visuals = BrokerVisuals(**kwargs)
        self.da_object = DAComponent(self.profile_id, self.component)

        da_dict = dict(
            publication=Publication,
            person=Person,
            sample=Sample,
            source=Source,
            profile=Profile,
            datafile=DataFile,
            submission=Submission,
            annotation=Annotation
        )

        if da_dict.get(self.component):
            self.da_object = da_dict[self.component](self.profile_id)

    def set_extra_params(self, extra_param):
        for k, v in extra_param.items():
            self.param_dict[k] = v

    def do_copo_schemas(self):
        copo_schemas = dict(
            ontology_schema=d_utils.get_copo_schema("ontology_annotation"),
            comment_schema=d_utils.get_copo_schema("comment"),
            characteristics_schema=d_utils.get_copo_schema("material_attribute_value"),
            source_schema=d_utils.get_copo_schema("source")
        )

        self.context["copo_schemas"] = copo_schemas
        return self.context

    def do_save_edit(self):
        kwargs = dict()
        kwargs["target_id"] = self.param_dict.get("target_id", str())

        record_object = self.da_object.save_record(self.auto_fields, **kwargs)

        # process visualisation context
        self.broker_visuals.set_extra_params(dict(record_object=record_object))

        visualize_dict = dict(profiles_counts=self.broker_visuals.do_profiles_counts,
                              sources_json=self.broker_visuals.get_sources_json,
                              sources_json_and_last_record_id=self.broker_visuals.get_sources_json_last_record_id,
                              last_record=self.broker_visuals.get_last_record,
                              get_profile_count=self.broker_visuals.get_profile_count
                              )

        if self.visualize in visualize_dict:
            self.context = visualize_dict[self.visualize]()
        elif self.param_dict.get("target_id", str()):
            self.context = self.broker_visuals.do_table_data()
        else:
            self.context = self.broker_visuals.do_row_data()

        return self.context

    def do_delete(self):
        target_ids = [ObjectId(i) for i in self.param_dict.get("target_ids")]

        self.da_object.get_collection_handle().update_many(
            {"_id": {"$in": target_ids}}, {"$set": {"deleted": d_utils.get_deleted_flag()}}
        )

        self.context = self.broker_visuals.do_table_data()
        return self.context

    def do_form(self):
        target_id = self.param_dict.get("target_id")
        component_dict = self.param_dict.get("component_dict", dict())
        message_dict = self.param_dict.get("message_dict", dict())

        self.context["form"] = htags.generate_copo_form(self.component, target_id, component_dict, message_dict,
                                                        self.profile_id)
        self.context["form"]["visualize"] = self.param_dict.get("visualize")
        return self.context

    def do_doi(self):
        id_handle = self.param_dict.get("id_handle")
        id_type = self.param_dict.get("id_type")

        doi_resolve = DOI2Metadata(id_handle, id_type).get_resolve(self.component)

        self.set_extra_params(dict(target_id=str(),
                                   component_dict=doi_resolve.get("component_dict", dict()),
                                   message_dict=doi_resolve.get("message_dict", dict()))
                              )

        return self.do_form()

    def do_initiate_submission(self):
        kwarg = dict(datafile_ids=self.param_dict.get("datafile_ids", list()))
        self.context["submission_token"] = str(self.da_object.save_record(dict(), **kwarg).get("_id", str()))
        return self.context

    def do_user_email(self):
        user_id = self.param_dict.get("user_id", str())
        user_email = self.param_dict.get("user_email", str())
        user = User.objects.get(pk=int(user_id))
        user.email = user_email
        user.save()

        return self.context
Ejemplo n.º 18
0
def generate_server_side_table_records(profile_id=str(), component=str(), request=dict()):
    # function generates component records for building an UI table using server-side processing
    # - please note that for effective data display,
    # all array and object-type fields (e.g., characteristics) are deferred to sub-table display.
    # please define such in the schema as "show_in_table": false and "show_as_attribute": true

    data_set = list()

    n_size = int(request.get("length", 10))  # assumes 10 records per page if length not set
    draw = int(request.get("draw", 1))
    start = int(request.get("start", 0))

    # instantiate data access object
    da_object = DAComponent(profile_id, component)

    return_dict = dict()

    records_total = da_object.get_collection_handle().count(
        {'profile_id': profile_id, 'deleted': data_utils.get_not_deleted_flag()})

    # retrieve and process records
    filter_by = dict()

    if component == "datafile":
        # get all active bundles in the profile
        existing_bundles = Description().get_all_records_columns(projection=dict(_id=1),
                                                                 filter_by=dict(profile_id=profile_id,
                                                                                component=component))
        existing_bundles = [str(x["_id"]) for x in existing_bundles]
        records_total = da_object.get_collection_handle().count({"$and": [
            {"profile_id": profile_id, 'deleted': data_utils.get_not_deleted_flag()},
            {"$or": [
                {"description_token": {"$in": [None, False, ""]}},
                {"description_token": {"$nin": existing_bundles}}]}
        ]})

        filter_by = {"$or": [
            {"description_token": {"$in": [None, False, ""]}},
            {"description_token": {"$nin": existing_bundles}}]}

    # get and filter schema elements based on displayable columns
    schema = [x for x in da_object.get_schema().get("schema_dict") if x.get("show_in_table", True)]

    # build db column projection
    projection = [(x["id"].split(".")[-1], 1) for x in schema]

    # order by
    sort_by = request.get('order[0][column]', '0')
    sort_by = request.get('columns[' + sort_by + '][data]', '')
    sort_direction = request.get('order[0][dir]', 'asc')

    sort_by = '_id' if not sort_by else sort_by
    sort_direction = 1 if sort_direction == 'asc' else -1

    # search
    search_term = request.get('search[value]', '').strip()

    records = da_object.get_all_records_columns_server(sort_by=sort_by, sort_direction=sort_direction,
                                                       search_term=search_term, projection=dict(projection),
                                                       limit=n_size, skip=start, filter_by=filter_by)

    records_filtered = records_total

    if search_term:
        records_filtered = da_object.get_collection_handle().count(
            {'profile_id': profile_id, 'deleted': data_utils.get_not_deleted_flag(),
             'name': {'$regex': search_term, "$options": 'i'}})

    if records:
        df = pd.DataFrame(records)

        df['record_id'] = df._id.astype(str)
        df["DT_RowId"] = df.record_id
        df.DT_RowId = 'row_' + df.DT_RowId
        df = df.drop('_id', axis='columns')

        for x in schema:
            x["id"] = x["id"].split(".")[-1]
            df[x["id"]] = df[x["id"]].apply(resolve_control_output_apply, args=(x,)).astype(str)

        data_set = df.to_dict('records')

    return_dict["records_total"] = records_total
    return_dict["records_filtered"] = records_filtered
    return_dict["data_set"] = data_set
    return_dict["draw"] = draw

    return return_dict
Ejemplo n.º 19
0
class BrokerDA:
    def __init__(self, **kwargs):
        self.param_dict = kwargs
        self.context = self.param_dict.get("context", dict())
        self.component = self.param_dict.get("component", str())
        self.visualize = self.param_dict.get("visualize", str())
        self.profile_id = self.param_dict.get("profile_id", str())
        self.auto_fields = self.param_dict.get("auto_fields", dict())

        if self.auto_fields and isinstance(self.auto_fields, str):
            self.auto_fields = json.loads(self.auto_fields)

        self.broker_visuals = BrokerVisuals(**kwargs)
        self.da_object = DAComponent(self.profile_id, self.component)

        da_dict = dict(publication=Publication,
                       person=Person,
                       sample=Sample,
                       source=Source,
                       profile=Profile,
                       datafile=DataFile,
                       submission=Submission,
                       annotation=Annotation,
                       cgcore=CGCore,
                       metadata_template=MetadataTemplate)

        if self.component in da_dict:
            self.da_object = da_dict[self.component](self.profile_id)

    def set_extra_params(self, extra_param):
        for k, v in extra_param.items():
            self.param_dict[k] = v

    def do_form_control_schemas(self):
        """
        function returns object type control schemas used in building form controls
        :return:
        """

        copo_schemas = dict()
        for k, v in d_utils.object_type_control_map().items():
            copo_schemas[k] = d_utils.get_copo_schema(v)

        self.context["copo_schemas"] = copo_schemas
        return self.context

    def do_save_edit(self):
        kwargs = dict()
        kwargs["target_id"] = self.param_dict.get("target_id", str())

        # set report parameter
        status = "success"  # 'success', 'warning', 'info', 'danger' - modelled after bootstrap alert classes
        action_type = "add"

        report_metadata = dict()

        if self.param_dict.get("target_id", str()):
            action_type = "edit"

        record_object = self.da_object.save_record(self.auto_fields, **kwargs)

        if not record_object:
            status = "danger"

        if action_type == "add":
            report_metadata[
                "message"] = "New " + self.component + " record created!"
            if status != "success":
                report_metadata[
                    "message"] = "There was a problem creating the " + self.component + " record!"
        elif action_type == "edit":
            report_metadata["message"] = "Record updated!"
            if status != "success":
                report_metadata[
                    "message"] = "There was a problem updating the " + self.component + " record!"

        report_metadata["status"] = status
        self.context["action_feedback"] = report_metadata

        # process visualisation context,

        # set extra parameters which will be passed along to the visualize object
        self.broker_visuals.set_extra_params(
            dict(record_object=record_object,
                 data_source=self.param_dict.get("data_source", str())))

        # build dictionary of executable tasks/functions
        visualize_dict = dict(
            profiles_counts=self.broker_visuals.do_profiles_counts,
            created_component_json=self.broker_visuals.
            get_created_component_json,
            last_record=self.broker_visuals.get_last_record,
            get_profile_count=self.broker_visuals.get_profile_count)

        if self.visualize in visualize_dict:
            self.context = visualize_dict[self.visualize]()
        elif self.param_dict.get("target_id", str()):
            self.context = self.broker_visuals.do_table_data()
        else:
            self.context = self.broker_visuals.do_row_data()

        return self.context

    def do_delete(self):
        target_ids = [ObjectId(i) for i in self.param_dict.get("target_ids")]

        # if ever it was needed to re-implement 'soft' delete uncomment the following lines and
        # comment out the 'hard' delete query

        # soft delete
        # self.da_object.get_collection_handle().update_many(
        #     {"_id": {"$in": target_ids}}, {"$set": {"deleted": d_utils.get_deleted_flag()}}
        # )

        # hard delete
        self.da_object.get_collection_handle().remove(
            {'_id': {
                '$in': target_ids
            }})

        self.context = self.broker_visuals.do_table_data()
        return self.context

    def do_form(self):
        target_id = self.param_dict.get("target_id")
        component_dict = self.param_dict.get("component_dict", dict())
        message_dict = self.param_dict.get("message_dict", dict())

        kwargs = dict()
        kwargs["referenced_field"] = self.param_dict.get(
            "referenced_field", str())
        kwargs["referenced_type"] = self.param_dict.get(
            "referenced_type", str())

        self.context["form"] = htags.generate_copo_form(
            self.component, target_id, component_dict, message_dict,
            self.profile_id, **kwargs)
        self.context["form"]["visualize"] = self.param_dict.get("visualize")
        return self.context

    def do_form_and_component_records(self):
        # generates form, and in addition returns records of the form component, this could, for instance, be
        # used for cloning of a record

        kwargs = dict()
        kwargs["referenced_field"] = self.param_dict.get(
            "referenced_field", str())
        kwargs["referenced_type"] = self.param_dict.get(
            "referenced_type", str())

        self.context = self.do_form()
        self.context["component_records"] = htags.generate_component_records(
            self.component, self.profile_id, **kwargs)

        return self.context

    def do_doi(self):
        id_handle = self.param_dict.get("id_handle")
        id_type = self.param_dict.get("id_type")

        doi_resolve = DOI2Metadata(id_handle,
                                   id_type).get_resolve(self.component)

        self.set_extra_params(
            dict(target_id=str(),
                 component_dict=doi_resolve.get("component_dict", dict()),
                 message_dict=doi_resolve.get("message_dict", dict())))

        return self.do_form()

    def do_initiate_submission(self):
        kwarg = dict(datafile_ids=self.param_dict.get("datafile_ids", list()))
        self.context["submission_token"] = str(
            self.da_object.save_record(dict(), **kwarg).get("_id", str()))
        return self.context

    def do_user_email(self):
        user_id = self.param_dict.get("user_id", str())
        user_email = self.param_dict.get("user_email", str())
        user = User.objects.get(pk=int(user_id))
        user.email = user_email
        user.save()

        return self.context

    def do_component_record(self):
        self.context["component_record"] = self.da_object.get_record(
            self.param_dict.get("target_id"))

        return self.context

    def component_form_record(self):
        target_id = self.param_dict.get("target_id")
        component_dict = self.param_dict.get("component_dict", dict())
        message_dict = self.param_dict.get("message_dict", dict())

        kwargs = dict()
        kwargs["referenced_field"] = self.param_dict.get(
            "referenced_field", str())
        kwargs["referenced_type"] = self.param_dict.get(
            "referenced_type", str())
        kwargs["action_type"] = self.param_dict.get("action_type", str())

        form_value = htags.generate_copo_form(self.component, target_id,
                                              component_dict, message_dict,
                                              self.profile_id, **kwargs)

        self.context["component_record"] = form_value["form_value"]
        self.context["component_schema"] = form_value["form_schema"]
        return self.context

    def do_sanitise_submissions(self):

        records = self.da_object.get_all_records()

        for submission in records:
            if "bundle_meta" not in submission:
                bundle_meta = list()

                for file_id in submission.get("bundle", list()):
                    datafile = DataFile().get_record(file_id)
                    if datafile:
                        upload_status = False

                        if str(submission.get("complete",
                                              False)).lower() == 'true':
                            upload_status = True
                        bundle_meta.append(
                            dict(file_id=file_id,
                                 file_path=datafile.get(
                                     "file_location", str()),
                                 upload_status=upload_status))
                submission["bundle_meta"] = bundle_meta
                submission['target_id'] = str(submission.pop('_id'))
                self.da_object.save_record(dict(), **submission)

        self.context["sanitise_status"] = True

        return self.context

    def do_clone_description_bundle(self):
        """
        function creates a new description by cloning an existing (specified) bundle
        :return:
        """

        target_id = self.param_dict.get("target_id", str())
        bundle_name = self.param_dict.get("bundle_name", str())

        result = dict(status="success", message="")

        if Description().get_description_handle().find({
                "name": {
                    '$regex': "^" + bundle_name + "$",
                    "$options": 'i'
                }
        }).count() >= 1:
            result["status"] = "error"
            result["message"] = "Bundle name must be unique"

            self.context["result"] = result
            return self.context

        # retrieve clone target
        description = Description().GET(target_id)

        # new bundle being created
        try:
            bundle = Description().create_description(
                profile_id=self.profile_id,
                component=self.component,
                name=bundle_name,
                stages=description.get('stages', list()),
                attributes=description.get('attributes', dict()),
                meta=description.get('meta', dict()))

            result["data"] = dict(id=str(bundle["_id"]), name=bundle["name"])
        except Exception as e:
            message = "Couldn't create bundle: " + bundle_name + " " + str(e)
            result["status"] = "error"
            result["message"] = message

        self.context["result"] = result
        return self.context

    def create_rename_description_bundle(self):
        """
        function creates a new description bundle or renames an existing one
        :return:
        """

        target_id = self.param_dict.get("target_id", str())
        bundle_name = self.param_dict.get("bundle_name", str())

        result = dict(status="success", message="")

        if Description().get_description_handle().find({
                "name": {
                    '$regex': "^" + bundle_name + "$",
                    "$options": 'i'
                }
        }).count() >= 1:
            result["status"] = "error"
            result["message"] = "Bundle name must be unique"
        elif target_id:
            # updating existing bundle
            Description().edit_description(target_id, {"name": bundle_name})

            try:
                Description().edit_description(target_id,
                                               {"name": bundle_name})
            except Exception as e:
                message = "Couldn't update bundle: " + bundle_name + " " + str(
                    e)
                result["status"] = "error"
                result["message"] = message
        else:
            # new bundle being created
            try:
                bundle = Description().create_description(
                    profile_id=self.profile_id,
                    component=self.component,
                    name=bundle_name)
                result["data"] = dict(id=str(bundle["_id"]),
                                      name=bundle["name"])
            except Exception as e:
                message = "Couldn't create bundle: " + bundle_name + " " + str(
                    e)
                result["status"] = "error"
                result["message"] = message

        self.context["result"] = result
        return self.context
Ejemplo n.º 20
0
def generate_table_records(profile_id=str(), component=str()):
    # function generates component records for building an UI table - please note that for effective tabular display,
    # all array and object-type fields (e.g., characteristics) are deferred to sub-table display.
    # please define such in the schema as "show_in_table": false and "show_as_attribute": true

    columns = list()
    data_set = list()

    # instantiate data access object
    da_object = DAComponent(profile_id, component)

    # get and filter schema elements based on displayable columns
    schema = [x for x in da_object.get_schema().get("schema_dict") if x.get("show_in_table", True)]

    # build db column projection
    projection = [(x["id"].split(".")[-1], 1) for x in schema]

    # retrieve and process records
    if component == "submission":
        records = da_object.get_all_records_columns(sort_by="date_created", sort_direction=1,
                                                    projection=dict(projection))
    else:
        records = da_object.get_all_records_columns(projection=dict(projection))

    if len(records):
        df = pd.DataFrame(records)
        df['s_n'] = df.index

        df['record_id'] = df._id.astype(str)
        df["DT_RowId"] = df.record_id
        df.DT_RowId = 'row_' + df.DT_RowId
        df = df.drop('_id', axis='columns')

        if component == "submission":
            df["special_repositories"] = df["repository"]

            columns.append(dict(data="special_repositories", visible=False))

        columns.append(dict(data="record_id", visible=False))
        detail_dict = dict(className='summary-details-control detail-hover-message', orderable=False, data=None,
                           title='', defaultContent='', width="5%")

        columns.insert(0, detail_dict)

        df_columns = list(df.columns)

        for x in schema:
            x["id"] = x["id"].split(".")[-1]
            columns.append(dict(data=x["id"], title=x["label"]))
            if x["id"] not in df_columns:
                df[x["id"]] = str()
            df[x["id"]] = df[x["id"]].fillna('')
            df[x["id"]] = df[x["id"]].apply(resolve_control_output_apply, args=(x,))

        data_set = df.to_dict('records')

    return_dict = dict(dataSet=data_set,
                       columns=columns
                       )

    # do check for custom repos here
    if component == "submission":
        correct_repos = list()
        user = ThreadLocal.get_current_user()
        repo_ids = user.userdetails.repo_submitter
        all_repos = Repository().get_by_ids(repo_ids)

        for repo in all_repos:
            for r_id in repo_ids:
                if r_id == str(repo["_id"]):
                    correct_repos.append(repo)

        for repo in correct_repos:
            repo["_id"] = str(repo["_id"])

        return_dict["repos"] = correct_repos

    return return_dict
Ejemplo n.º 21
0
def generate_copo_table_data(profile_id=str(), component=str()):
    # This method generates the 'json' for building an UI table

    # instantiate data access object
    da_object = DAComponent(profile_id, component)

    # get records
    records = da_object.get_all_records()

    columns = list()
    dataSet = list()

    # headers
    for f in da_object.get_schema().get("schema_dict"):
        if f.get("show_in_table", True):
            columns.append(dict(title=f["label"]))

    columns.append(dict(title=str()))  # extra 'blank' header for record actions column

    # data
    for rec in records:
        row = list()
        for f in da_object.get_schema().get("schema_dict"):
            if f.get("show_in_table", True):
                row.append(resolve_control_output(rec, f))

        row.append(str(rec["_id"]))  # last element in a row exposes the id of the record
        dataSet.append(row)

    # define action buttons
    button_templates = d_utils.get_button_templates()

    common_btn_dict = dict(row_btns=[button_templates['edit_row'], button_templates['delete_row']],
                           global_btns=[button_templates['delete_global']])

    sample_info = copy.deepcopy(button_templates['info_row'])
    sample_info["text"] = "Sample Attributes"

    buttons_dict = dict(publication=common_btn_dict,
                        person=common_btn_dict,
                        sample=dict(row_btns=[sample_info, button_templates['edit_row'],
                                               button_templates['delete_row']],
                                    global_btns=[button_templates['add_new_samples_global'],
                                                 button_templates['delete_global']]),
                        source=common_btn_dict,
                        profile=common_btn_dict,
                        annotation=common_btn_dict,
                        datafile=dict(
                            row_btns=[button_templates['info_row'], button_templates['describe_row'],
                                      button_templates['delete_row']],
                            global_btns=[button_templates['describe_global'],
                                         button_templates['undescribe_global']])
                        )

    action_buttons = dict(row_btns=buttons_dict.get(component).get("row_btns"),
                          global_btns=buttons_dict.get(component).get("global_btns")
                          )

    return_dict = dict(columns=columns,
                       dataSet=dataSet,
                       table_id=table_id_dict.get(component, str()),
                       action_buttons=action_buttons
                       )

    return return_dict