def get_post_data(request, item_model, item_name_field_name, action_type, required_fields, hidden_field_tuples):
    # Get all fields on the model
    fields = item_model._meta.fields

    fields_to_save = {}
    missing_field_names = []

    # Build a list of potential fields to fill in
    for field in fields:
        fields_to_save[field.name] = request.POST.get(field.name, "")
        field_is_missing = False

        if fields_to_save[field.name] == "":
            if hidden_field_tuples:
                for hidden_field_tuple in hidden_field_tuples:
                    if field.name == hidden_field_tuple[0]:
                        if hidden_field_tuple[1] is None:
                            fields_to_save[field.name] = request.user
                        else:
                            fields_to_save[field.name] = getattr(request.user, hidden_field_tuple[1]).id

                        break
                else:
                    # For-else means if it wasn't found
                    field_is_missing = True
            else:
                field_is_missing = True

            if field_is_missing:
                missing_field_names.append(field.name)
                fields_to_save.pop(field.name, None)

    message = ""
    has_missing_required_fields = False

    if action_type == MERGE or action_type == ADD or action_type == CLONE or action_type == EDIT:
        # Check if other required fields are missing from the post
        for missing_field_name in missing_field_names:
            if missing_field_name in required_fields:
                message += prettify_string(missing_field_name) + " is required. "
                has_missing_required_fields = True

        # If anything was missing, return an error with the list of missing required fields
        if has_missing_required_fields:
            logger.error(message)

            return HttpResponse(content=message, status=500)

        item_name = fields_to_save[item_name_field_name]  # This will be in the list if we made it this far
    else:
        item_name = None

    item_id = None
    item2_id = None

    if "item_id" in request.POST:
        item_id = request.POST["item_id"]

    # This will only be sent if it is a merge
    if "item2_id" in request.POST:
        item2_id = request.POST["item2_id"]

    return fields_to_save, item_name, item_id, item2_id
def add_item_to_context(context, item_name, item_model, field_list, name_of_app_with_url, current_item_id,
                        item_name_field_name="name", item_html_name=None, allow_empty=True, field_to_order_by=None,
                        is_used_only_for_maced_fields=False, filters=None):
    if not isinstance(context, dict):
        raise TypeError("Please provide a valid context")

    if not isinstance(item_name, STR_UNICODE_TUPLE):
        raise TypeError("item_name must be a string")

    if not is_item_name_valid(item_name):
        raise ValueError(
            "item_name was \"" + str(item_name) + "\" but it must not contain " +
            get_bad_item_name_characters_in_string()
        )

    if not inspect.isclass(item_model):
        raise TypeError("item_model must be a class")

    if not isinstance(item_name_field_name, STR_UNICODE_TUPLE):
        raise TypeError("object_name_field_name must be a string")

    if not isinstance(field_list, list):
        raise TypeError("field_list must be a list")

    if not isinstance(name_of_app_with_url, STR_UNICODE_TUPLE):
        raise TypeError("name_of_app_with_url must be a string")

    if not isinstance(current_item_id, int):
        raise TypeError("current_item_id must be a integer")

    if not isinstance(item_html_name, STR_UNICODE_TUPLE) and item_html_name is not None:
        raise TypeError("item_html_name must be a string or None")

    if not isinstance(allow_empty, bool):
        raise TypeError("allow_empty must be a bool")

    if not isinstance(field_to_order_by, STR_UNICODE_TUPLE) and field_to_order_by is not None:
        raise TypeError(
            "field_to_order_by must be a string that is the name of the field you want to order your objects by or None"
        )

    if not isinstance(is_used_only_for_maced_fields, bool):
        raise TypeError("is_used_only_for_maced_fields must be a bool")

    if "maced_data" not in context:
        context["maced_data"] = {}

    if "maced_modals" not in context:
        context["maced_modals"] = ""

    if "individual_maced_modals" not in context:
        context["individual_maced_modals"] = {}

    maced_data = context["maced_data"]

    if "items_to_remove" not in maced_data:
        maced_data["items_to_remove"] = []

    if "item_names" not in maced_data:
        maced_data["item_names"] = []

    if item_name in maced_data["item_names"]:
        raise ValueError("Duplicate item var name of " + str(item_name))

    if "maced_names" not in maced_data:
        maced_data["maced_names"] = {}

    if "item_html_names" not in maced_data:
        maced_data["item_html_names"] = {}

    if "field_names" not in maced_data:
        maced_data["field_names"] = {}

    if "field_identifiers" not in maced_data:
        maced_data["field_identifiers"] = {}

    if "urls" not in maced_data:
        maced_data["urls"] = {}

    if "item_names_with_ignored_alerts" not in maced_data:
        maced_data["item_names_with_ignored_alerts"] = []

    if is_used_only_for_maced_fields:
        maced_data["items_to_remove"].append(item_name)
    else:
        maced_data["item_names"].append(item_name)

    if item_html_name is None:
        item_html_name = prettify_string(item_name)

    if field_to_order_by is None:
        field_to_order_by = item_name_field_name

    maced_data["maced_names"][item_name] = item_name
    maced_data["item_html_names"][item_name] = item_html_name

    initialize_fields_for_item_in_maced_data(maced_data=maced_data, item_name=item_name)
    context[str(item_name) + "_dependencies"] = []

    # Get all items of this type
    items = get_items(item_model=item_model, field_to_order_by=field_to_order_by, filters=filters)

    # Create an option_tuple_list which is a list of tuples defined as (id_of_the_item, name_of_the_item). This will
    # be used in the merge function.
    option_tuple_list = [(item.id, getattr(item, str(item_name_field_name))) for item in items]
    options_html_code = get_html_code_for_options(option_tuple_list=option_tuple_list)

    # Constructs url
    url = build_url(item_name=item_name, name_of_app_with_url=name_of_app_with_url)

    # Add the get url to the context
    maced_data["urls"][item_name] = url

    # Make a builder so we can reuse it later for maced fields
    context[str(item_name) + "_builder"] = build_builder(
        item_name=item_name, item_html_name=item_html_name, item_model=item_model, field_to_order_by=field_to_order_by,
        url=url, options_html_code=options_html_code, field_list=field_list, allow_empty=allow_empty, filters=filters
    )

    # All the special html that is dynamically generated
    html_code_dictionary = build_html_code(
        context=context, options_html_code=options_html_code, item_name=item_name, item_html_name=item_html_name,
        field_list=field_list, maced_name=item_name
    )

    # The final step of putting it all together to make 2 sets of html;
    # one for the item on the page and one for the modal that pops up.
    maced_html_code, maced_modal_html_code = build_templates(
        builder=context[str(item_name) + "_builder"], html_code_dictionary=html_code_dictionary,
        item_id=current_item_id, maced_name=item_name
    )

    context[str(item_name) + "_item"] = maced_html_code
    context["individual_maced_modals"][item_name] = maced_modal_html_code  # This will be added to "maced_modals" later
    context[str(item_name) + "_options_html_code"] = options_html_code
def build_html_code(context, options_html_code, item_name, item_html_name, field_list, maced_name):
    maced_data = context["maced_data"]
    html_code_dictionary = {}
    html_code_dictionary[item_name] = {}

    for action_type in PRIMARY_ACTION_TYPES:
        html_code_dictionary[item_name][action_type] = ""

    # Merge has special html before the regular html
    merge_context = {}
    merge_context["item_name"] = item_name
    merge_context["item_html_name"] = item_html_name
    merge_context["options_html_code"] = options_html_code
    merge_context["input_id1"] = MERGE + "-" + item_name + "1-input"
    merge_context["input_id2"] = MERGE + "-" + item_name + "2-input"
    merge_context["modal_id"] = MERGE + "-" + item_name + "-modal"
    merge_context["item_html_class_name"] = get_item_html_class_name(maced_name)

    html_code_dictionary[item_name][MERGE] = render(
        request=None, template_name="maced/merge_table_row_1.html", context=merge_context
    ).content.strip().decode('utf-8')

    # Create html input fields for each field on the model
    for field in field_list:
        extra_info = None

        if "name" not in field:
            raise ValueError("Field in field_list is missing \"name\"")

        if "type" not in field:
            field["type"] = "text"

        if field["type"] not in VALID_INPUT_TYPES:
            raise ValueError(
                "Field named \"" + str(field["name"]) + "\" in field_list for \"" + str(item_name) + "\" has a type " +
                "of \"" + str(field["type"]) + "\" which is invalid"
            )

        if field["type"] == "select":
            if "select_type" not in field:
                field["select_type"] = "object"

            if field["select_type"] not in VALID_SELECT_TYPES:
                raise ValueError(
                    "The select for the field named \"" + str(field["name"]) + "\" has a type of \"" +
                    str(field["select_type"]) + "\" which is invalid"
                )

            if "options" in field:
                extra_info = field["options"]

                # Will raise errors if invalid, else it move on
                validate_select_options(
                    extra_info=extra_info, field=field, item_name=item_name, select_type=field["select_type"]
                )
            else:
                raise ValueError(
                    "Field \"" + str(field["name"]) + "\" in field_list for \"" + str(item_name) + "\" " +
                    "is set to type \"select\", but doesn't have \"options\""
                )

        if field["type"] == "maced":
            if "maced_name" not in field:
                field["maced_name"] = field["name"]

            if field["maced_name"] + "_item" not in context:
                raise ValueError(
                    "Field named \"" + str(field["name"]) + "\" in field_list for \"" + str(item_name) + "\"" +
                    " is set as type \"maced\" and is referencing \"" + str(field["maced_name"]) + "\" but it is not " +
                    "in the context. Please make sure you have created a maced item for it and ensure that it is " +
                    "created prior to this one. If you are trying to use an object with a name different from the " +
                    "name given for \"name\" for this field, please use \"maced_name\" to specify the name you want. " +
                    "By default, \"name\" is used."
                )

            if maced_name + "_dependencies" not in context:
                raise RuntimeError("\"" + item_name + "_dependencies\" was not in the context. Did you overwrite it?")

            if field["maced_name"] + "_builder" not in context:
                raise RuntimeError("\"" + item_name + "_builder\" was not in the context. Did you overwrite it?")

            # Add this maced item as a dependency of the main item
            dependency = {}
            dependency["maced_name"] = field["maced_name"]
            dependency["parents_name_for_child"] = field["name"]
            dependency["builder"] = context[field["maced_name"] + "_builder"]

            context[maced_name + "_dependencies"].append(dependency)

            extra_info = {}
            extra_info["context"] = context
            extra_info["field_maced_name"] = field["maced_name"]

        if "html_name" not in field:
            field["html_name"] = prettify_string(ugly_string=field["name"])

        # Form the html based on the info from field
        insert_items_html_code(
            original_dictionary=html_code_dictionary, maced_name=maced_name, item_name=item_name,
            field_type=field["type"], field_html_name=field["html_name"], field_name=field["name"],
            extra_info=extra_info
        )

        # Lastly add the field info to the context
        maced_data["field_names"][item_name].append(field["name"])
        maced_data["field_identifiers"][item_name].append(field["name"])

    return html_code_dictionary
def add_item_to_context(context, item_name, item_model, field_list, name_of_app_with_url, current_item_id,
                        item_name_field_name="name", item_html_name=None, allow_empty=True, field_to_order_by=None,
                        is_used_only_for_maced_fields=False, filters=None):
    if not isinstance(context, dict):
        raise TypeError("Please provide a valid context")

    if not isinstance(item_name, STR_UNICODE_TUPLE):
        raise TypeError("item_name must be a string")

    if not is_item_name_valid(item_name):
        raise ValueError(
            "item_name was \"" + str(item_name) + "\" but it must not contain " +
            get_bad_item_name_characters_in_string()
        )

    if not inspect.isclass(item_model):
        raise TypeError("item_model must be a class")

    if not isinstance(item_name_field_name, STR_UNICODE_TUPLE):
        raise TypeError("object_name_field_name must be a string")

    if not isinstance(field_list, list):
        raise TypeError("field_list must be a list")

    if not isinstance(name_of_app_with_url, STR_UNICODE_TUPLE):
        raise TypeError("name_of_app_with_url must be a string")

    if not isinstance(current_item_id, int):
        raise TypeError("current_item_id must be a integer")

    if not isinstance(item_html_name, STR_UNICODE_TUPLE) and item_html_name is not None:
        raise TypeError("item_html_name must be a string or None")

    if not isinstance(allow_empty, bool):
        raise TypeError("allow_empty must be a bool")

    if not isinstance(field_to_order_by, STR_UNICODE_TUPLE) and field_to_order_by is not None:
        raise TypeError(
            "field_to_order_by must be a string that is the name of the field you want to order your objects by or None"
        )

    if not isinstance(is_used_only_for_maced_fields, bool):
        raise TypeError("is_used_only_for_maced_fields must be a bool")

    if "maced_data" not in context:
        context["maced_data"] = {}

    if "maced_modals" not in context:
        context["maced_modals"] = ""

    if "individual_maced_modals" not in context:
        context["individual_maced_modals"] = {}

    maced_data = context["maced_data"]

    if "items_to_remove" not in maced_data:
        maced_data["items_to_remove"] = []

    if "item_names" not in maced_data:
        maced_data["item_names"] = []

    if item_name in maced_data["item_names"]:
        raise ValueError("Duplicate item var name of " + str(item_name))

    if "maced_names" not in maced_data:
        maced_data["maced_names"] = {}

    if "item_html_names" not in maced_data:
        maced_data["item_html_names"] = {}

    if "field_names" not in maced_data:
        maced_data["field_names"] = {}

    if "field_identifiers" not in maced_data:
        maced_data["field_identifiers"] = {}

    if "urls" not in maced_data:
        maced_data["urls"] = {}

    if "item_names_with_ignored_alerts" not in maced_data:
        maced_data["item_names_with_ignored_alerts"] = []

    if is_used_only_for_maced_fields:
        maced_data["items_to_remove"].append(item_name)
    else:
        maced_data["item_names"].append(item_name)

    if item_html_name is None:
        item_html_name = prettify_string(item_name)

    if field_to_order_by is None:
        field_to_order_by = item_name_field_name

    maced_data["maced_names"][item_name] = item_name
    maced_data["item_html_names"][item_name] = item_html_name

    initialize_fields_for_item_in_maced_data(maced_data=maced_data, item_name=item_name)
    context[str(item_name) + "_dependencies"] = []

    # Get all items of this type
    items = get_items(item_model=item_model, field_to_order_by=field_to_order_by, filters=filters)

    # Create an option_tuple_list which is a list of tuples defined as (id_of_the_item, name_of_the_item). This will
    # be used in the merge function.
    option_tuple_list = [(item.id, getattr(item, str(item_name_field_name))) for item in items]
    options_html_code = get_html_code_for_options(option_tuple_list=option_tuple_list)

    # Constructs url
    url = build_url(item_name=item_name, name_of_app_with_url=name_of_app_with_url)

    # Add the get url to the context
    maced_data["urls"][item_name] = url

    # Make a builder so we can reuse it later for maced fields
    context[str(item_name) + "_builder"] = build_builder(
        item_name=item_name, item_html_name=item_html_name, item_model=item_model, field_to_order_by=field_to_order_by,
        url=url, options_html_code=options_html_code, field_list=field_list, allow_empty=allow_empty, filters=filters
    )

    # All the special html that is dynamically generated
    html_code_dictionary = build_html_code(
        context=context, options_html_code=options_html_code, item_name=item_name, item_html_name=item_html_name,
        field_list=field_list, maced_name=item_name
    )

    # The final step of putting it all together to make 2 sets of html;
    # one for the item on the page and one for the modal that pops up.
    maced_html_code, maced_modal_html_code = build_templates(
        builder=context[str(item_name) + "_builder"], html_code_dictionary=html_code_dictionary,
        item_id=current_item_id, maced_name=item_name
    )

    context[str(item_name) + "_item"] = maced_html_code
    context["individual_maced_modals"][item_name] = maced_modal_html_code  # This will be added to "maced_modals" later
    context[str(item_name) + "_options_html_code"] = options_html_code
def build_html_code(context, options_html_code, item_name, item_html_name, field_list, maced_name):
    maced_data = context["maced_data"]
    html_code_dictionary = {}
    html_code_dictionary[item_name] = {}

    for action_type in PRIMARY_ACTION_TYPES:
        html_code_dictionary[item_name][action_type] = ""

    # Merge has special html before the regular html
    merge_context = {}
    merge_context["item_name"] = item_name
    merge_context["item_html_name"] = item_html_name
    merge_context["options_html_code"] = options_html_code
    merge_context["input_id1"] = MERGE + "-" + item_name + "1-input"
    merge_context["input_id2"] = MERGE + "-" + item_name + "2-input"
    merge_context["modal_id"] = MERGE + "-" + item_name + "-modal"
    merge_context["item_html_class_name"] = get_item_html_class_name(maced_name)

    html_code_dictionary[item_name][MERGE] = render(
        request=None, template_name="maced/merge_table_row_1.html", context=merge_context
    ).content.strip().decode('utf-8')

    # Create html input fields for each field on the model
    for field in field_list:
        extra_info = None

        if "name" not in field:
            raise ValueError("Field in field_list is missing \"name\"")

        if "type" not in field:
            field["type"] = "text"

        if field["type"] not in VALID_INPUT_TYPES:
            raise ValueError(
                "Field named \"" + str(field["name"]) + "\" in field_list for \"" + str(item_name) + "\" has a type " +
                "of \"" + str(field["type"]) + "\" which is invalid"
            )

        if field["type"] == "select":
            if "select_type" not in field:
                field["select_type"] = "object"

            if field["select_type"] not in VALID_SELECT_TYPES:
                raise ValueError(
                    "The select for the field named \"" + str(field["name"]) + "\" has a type of \"" +
                    str(field["select_type"]) + "\" which is invalid"
                )

            if "options" in field:
                extra_info = field["options"]

                # Will raise errors if invalid, else it move on
                validate_select_options(
                    extra_info=extra_info, field=field, item_name=item_name, select_type=field["select_type"]
                )
            else:
                raise ValueError(
                    "Field \"" + str(field["name"]) + "\" in field_list for \"" + str(item_name) + "\" " +
                    "is set to type \"select\", but doesn't have \"options\""
                )

        if field["type"] == "maced":
            if "maced_name" not in field:
                field["maced_name"] = field["name"]

            if field["maced_name"] + "_item" not in context:
                raise ValueError(
                    "Field named \"" + str(field["name"]) + "\" in field_list for \"" + str(item_name) + "\"" +
                    " is set as type \"maced\" and is referencing \"" + str(field["maced_name"]) + "\" but it is not " +
                    "in the context. Please make sure you have created a maced item for it and ensure that it is " +
                    "created prior to this one. If you are trying to use an object with a name different from the " +
                    "name given for \"name\" for this field, please use \"maced_name\" to specify the name you want. " +
                    "By default, \"name\" is used."
                )

            if maced_name + "_dependencies" not in context:
                raise RuntimeError("\"" + item_name + "_dependencies\" was not in the context. Did you overwrite it?")

            if field["maced_name"] + "_builder" not in context:
                raise RuntimeError("\"" + item_name + "_builder\" was not in the context. Did you overwrite it?")

            # Add this maced item as a dependency of the main item
            dependency = {}
            dependency["maced_name"] = field["maced_name"]
            dependency["parents_name_for_child"] = field["name"]
            dependency["builder"] = context[field["maced_name"] + "_builder"]

            context[maced_name + "_dependencies"].append(dependency)

            extra_info = {}
            extra_info["context"] = context
            extra_info["field_maced_name"] = field["maced_name"]

        if "html_name" not in field:
            field["html_name"] = prettify_string(ugly_string=field["name"])

        # Form the html based on the info from field
        insert_items_html_code(
            original_dictionary=html_code_dictionary, maced_name=maced_name, item_name=item_name,
            field_type=field["type"], field_html_name=field["html_name"], field_name=field["name"],
            extra_info=extra_info
        )

        # Lastly add the field info to the context
        maced_data["field_names"][item_name].append(field["name"])
        maced_data["field_identifiers"][item_name].append(field["name"])

    return html_code_dictionary
Exemple #6
0
def get_post_data(request, item_model, item_name_field_name, action_type,
                  required_fields, hidden_field_tuples):
    # Get all fields on the model
    fields = item_model._meta.fields

    fields_to_save = {}
    missing_field_names = []

    # Build a list of potential fields to fill in
    for field in fields:
        fields_to_save[field.name] = request.POST.get(field.name, "")
        field_is_missing = False

        if fields_to_save[field.name] == "":
            if hidden_field_tuples:
                for hidden_field_tuple in hidden_field_tuples:
                    if field.name == hidden_field_tuple[0]:
                        if hidden_field_tuple[1] is None:
                            fields_to_save[field.name] = request.user
                        else:
                            fields_to_save[field.name] = getattr(
                                request.user, hidden_field_tuple[1]).id

                        break
                else:
                    # For-else means if it wasn't found
                    field_is_missing = True
            else:
                field_is_missing = True

            if field_is_missing:
                missing_field_names.append(field.name)
                fields_to_save.pop(field.name, None)

    message = ""
    has_missing_required_fields = False

    if action_type == MERGE or action_type == ADD or action_type == CLONE or action_type == EDIT:
        # Check if other required fields are missing from the post
        for missing_field_name in missing_field_names:
            if missing_field_name in required_fields:
                message += prettify_string(
                    missing_field_name) + " is required. "
                has_missing_required_fields = True

        # If anything was missing, return an error with the list of missing required fields
        if has_missing_required_fields:
            logger.error(message)

            return HttpResponse(content=message, status=500)

        item_name = fields_to_save[
            item_name_field_name]  # This will be in the list if we made it this far
    else:
        item_name = None

    item_id = None
    item2_id = None

    if "item_id" in request.POST:
        item_id = request.POST["item_id"]

    # This will only be sent if it is a merge
    if "item2_id" in request.POST:
        item2_id = request.POST["item2_id"]

    return fields_to_save, item_name, item_id, item2_id