예제 #1
0
def edit_module_attr(request, domain, app_id, module_id, attr):
    """
    Called to edit any (supported) module attribute, given by attr
    """
    attributes = {
        "all": None,
        "auto_select_case": None,
        "case_label": None,
        "case_list": ('case_list-show', 'case_list-label'),
        "case_list-menu_item_media_audio": None,
        "case_list-menu_item_media_image": None,
        "case_list_form_id": None,
        "case_list_form_label": None,
        "case_list_form_media_audio": None,
        "case_list_form_media_image": None,
        "case_type": None,
        "display_separately": None,
        "has_schedule": None,
        "media_audio": None,
        "media_image": None,
        "module_filter": None,
        "name": None,
        "parent_module": None,
        "put_in_root": None,
        "referral_label": None,
        "root_module_id": None,
        "source_module_id": None,
        "task_list": ('task_list-show', 'task_list-label'),
    }

    if attr not in attributes:
        return HttpResponseBadRequest()

    def should_edit(attribute):
        if attribute == attr:
            return True
        if 'all' == attr:
            if attributes[attribute]:
                for param in attributes[attribute]:
                    if not request.POST.get(param):
                        return False
                return True
            else:
                return request.POST.get(attribute) is not None

    app = get_app(domain, app_id)
    module = app.get_module(module_id)
    lang = request.COOKIES.get('lang', app.langs[0])
    resp = {'update': {}, 'corrections': {}}
    if should_edit("case_type"):
        case_type = request.POST.get("case_type", None)
        if is_valid_case_type(case_type):
            old_case_type = module["case_type"]
            module["case_type"] = case_type
            for cp_mod in (mod for mod in app.modules if isinstance(mod, CareplanModule)):
                if cp_mod.unique_id != module.unique_id and cp_mod.parent_select.module_id == module.unique_id:
                    cp_mod.case_type = case_type

            def rename_action_case_type(mod):
                for form in mod.forms:
                    for action in form.actions.get_all_actions():
                        if action.case_type == old_case_type:
                            action.case_type = case_type

            if isinstance(module, AdvancedModule):
                rename_action_case_type(module)
            for ad_mod in (mod for mod in app.modules if isinstance(mod, AdvancedModule)):
                if ad_mod.unique_id != module.unique_id and ad_mod.case_type != old_case_type:
                    # only apply change if the module's case_type does not reference the old value
                    rename_action_case_type(ad_mod)
        elif case_type == USERCASE_TYPE:
            return HttpResponseBadRequest('"{}" is a reserved case type'.format(USERCASE_TYPE))
        else:
            return HttpResponseBadRequest("case type is improperly formatted")
    if should_edit("put_in_root"):
        module["put_in_root"] = json.loads(request.POST.get("put_in_root"))
    if should_edit("source_module_id"):
        module["source_module_id"] = request.POST.get("source_module_id")
    if should_edit("display_separately"):
        module["display_separately"] = json.loads(request.POST.get("display_separately"))
    if should_edit("parent_module"):
        parent_module = request.POST.get("parent_module")
        module.parent_select.module_id = parent_module
    if should_edit("auto_select_case"):
        module["auto_select_case"] = request.POST.get("auto_select_case") == 'true'

    if (feature_previews.MODULE_FILTER.enabled(app.domain) and
            app.enable_module_filtering and
            should_edit('module_filter')):
        module['module_filter'] = request.POST.get('module_filter')

    if should_edit('case_list_form_id'):
        module.case_list_form.form_id = request.POST.get('case_list_form_id')
    if should_edit('case_list_form_label'):
        module.case_list_form.label[lang] = request.POST.get('case_list_form_label')
    if should_edit('case_list_form_media_image'):
        new_path = process_media_attribute(
            'case_list_form_media_image',
            resp,
            request.POST.get('case_list_form_media_image')
        )
        module.case_list_form.set_icon(lang, new_path)

    if should_edit('case_list_form_media_audio'):
        new_path = process_media_attribute(
            'case_list_form_media_audio',
            resp,
            request.POST.get('case_list_form_media_audio')
        )
        module.case_list_form.set_audio(lang, new_path)

    if should_edit('case_list-menu_item_media_image'):
        val = process_media_attribute(
            'case_list-menu_item_media_image',
            resp,
            request.POST.get('case_list-menu_item_media_image')
        )
        module.case_list.set_icon(lang, val)
    if should_edit('case_list-menu_item_media_audio'):
        val = process_media_attribute(
            'case_list-menu_item_media_audio',
            resp,
            request.POST.get('case_list-menu_item_media_audio')
        )
        module.case_list.set_audio(lang, val)

    for attribute in ("name", "case_label", "referral_label"):
        if should_edit(attribute):
            name = request.POST.get(attribute, None)
            module[attribute][lang] = name
            if should_edit("name"):
                resp['update'].update({'.variable-module_name': module.name[lang]})
    for SLUG in ('case_list', 'task_list'):
        show = '{SLUG}-show'.format(SLUG=SLUG)
        label = '{SLUG}-label'.format(SLUG=SLUG)
        if request.POST.get(show) == 'true' and (request.POST.get(label) == ''):
            # Show item, but empty label, was just getting ignored
            return HttpResponseBadRequest("A label is required for {SLUG}".format(SLUG=SLUG))
        if should_edit(SLUG):
            module[SLUG].show = json.loads(request.POST[show])
            module[SLUG].label[lang] = request.POST[label]

    if should_edit("root_module_id"):
        if not request.POST.get("root_module_id"):
            module["root_module_id"] = None
        else:
            try:
                app.get_module(module_id)
                module["root_module_id"] = request.POST.get("root_module_id")
            except ModuleNotFoundException:
                messages.error(_("Unknown Module"))

    handle_media_edits(request, module, should_edit, resp, lang)

    app.save(resp)
    resp['case_list-show'] = module.requires_case_details()
    return HttpResponse(json.dumps(resp))
예제 #2
0
def edit_module_attr(request, domain, app_id, module_id, attr):
    """
    Called to edit any (supported) module attribute, given by attr
    """
    attributes = {
        "all": None,
        "auto_select_case": None,
        "case_label": None,
        "case_list": ('case_list-show', 'case_list-label'),
        "case_list-menu_item_media_audio": None,
        "case_list-menu_item_media_image": None,
        "case_list_form_id": None,
        "case_list_form_label": None,
        "case_list_form_media_audio": None,
        "case_list_form_media_image": None,
        "case_type": None,
        'comment': None,
        "display_separately": None,
        "has_schedule": None,
        "media_audio": None,
        "media_image": None,
        "module_filter": None,
        "name": None,
        "parent_module": None,
        "put_in_root": None,
        "referral_label": None,
        "root_module_id": None,
        "source_module_id": None,
        "task_list": ('task_list-show', 'task_list-label'),
        "excl_form_ids": None,
        "display_style": None
    }

    if attr not in attributes:
        return HttpResponseBadRequest()

    def should_edit(attribute):
        if attribute == attr:
            return True
        if 'all' == attr:
            if attributes[attribute]:
                for param in attributes[attribute]:
                    if not request.POST.get(param):
                        return False
                return True
            else:
                return request.POST.get(attribute) is not None

    app = get_app(domain, app_id)
    module = app.get_module(module_id)
    lang = request.COOKIES.get('lang', app.langs[0])
    resp = {'update': {}, 'corrections': {}}
    if should_edit("case_type"):
        case_type = request.POST.get("case_type", None)
        if case_type == USERCASE_TYPE and not isinstance(
                module, AdvancedModule):
            return HttpResponseBadRequest(
                '"{}" is a reserved case type'.format(USERCASE_TYPE))
        elif case_type and not is_valid_case_type(case_type, module):
            return HttpResponseBadRequest("case type is improperly formatted")
        else:
            old_case_type = module["case_type"]
            module["case_type"] = case_type

            # rename other reference to the old case type
            other_careplan_modules = []
            all_advanced_modules = []
            modules_with_old_case_type_exist = False
            for mod in app.modules:
                if mod.unique_id != module_id:
                    if isinstance(mod, CareplanModule):
                        other_careplan_modules.append(mod)

                if isinstance(mod, AdvancedModule):
                    all_advanced_modules.append(mod)

                modules_with_old_case_type_exist |= mod.case_type == old_case_type

            for cp_mod in other_careplan_modules:
                if cp_mod.parent_select.module_id == module_id:
                    cp_mod.case_type = case_type

            for mod in all_advanced_modules:
                for form in mod.forms:
                    for action in form.actions.get_load_update_actions():
                        if action.case_type == old_case_type and action.details_module == module_id:
                            action.case_type = case_type

                    if mod.unique_id == module_id or not modules_with_old_case_type_exist:
                        for action in form.actions.get_open_actions():
                            if action.case_type == old_case_type:
                                action.case_type = case_type

    if should_edit("put_in_root"):
        module["put_in_root"] = json.loads(request.POST.get("put_in_root"))
    if should_edit("display_style"):
        module["display_style"] = request.POST.get("display_style")
    if should_edit("source_module_id"):
        module["source_module_id"] = request.POST.get("source_module_id")
    if should_edit("display_separately"):
        module["display_separately"] = json.loads(
            request.POST.get("display_separately"))
    if should_edit("parent_module"):
        parent_module = request.POST.get("parent_module")
        module.parent_select.module_id = parent_module
        if module_case_hierarchy_has_circular_reference(module):
            return HttpResponseBadRequest(
                _("The case hierarchy contains a circular reference."))
    if should_edit("auto_select_case"):
        module["auto_select_case"] = request.POST.get(
            "auto_select_case") == 'true'

    if app.enable_module_filtering and should_edit('module_filter'):
        module['module_filter'] = request.POST.get('module_filter')

    if should_edit('case_list_form_id'):
        module.case_list_form.form_id = request.POST.get('case_list_form_id')
    if should_edit('case_list_form_label'):
        module.case_list_form.label[lang] = request.POST.get(
            'case_list_form_label')
    if should_edit('case_list_form_media_image'):
        new_path = process_media_attribute(
            'case_list_form_media_image', resp,
            request.POST.get('case_list_form_media_image'))
        module.case_list_form.set_icon(lang, new_path)

    if should_edit('case_list_form_media_audio'):
        new_path = process_media_attribute(
            'case_list_form_media_audio', resp,
            request.POST.get('case_list_form_media_audio'))
        module.case_list_form.set_audio(lang, new_path)

    if should_edit('case_list-menu_item_media_image'):
        val = process_media_attribute(
            'case_list-menu_item_media_image', resp,
            request.POST.get('case_list-menu_item_media_image'))
        module.case_list.set_icon(lang, val)
    if should_edit('case_list-menu_item_media_audio'):
        val = process_media_attribute(
            'case_list-menu_item_media_audio', resp,
            request.POST.get('case_list-menu_item_media_audio'))
        module.case_list.set_audio(lang, val)

    for attribute in ("name", "case_label", "referral_label"):
        if should_edit(attribute):
            name = request.POST.get(attribute, None)
            module[attribute][lang] = name
            if should_edit("name"):
                resp['update'] = {
                    '.variable-module_name':
                    trans(module.name, [lang], use_delim=False)
                }
    if should_edit('comment'):
        module.comment = request.POST.get('comment')
    for SLUG in ('case_list', 'task_list'):
        show = '{SLUG}-show'.format(SLUG=SLUG)
        label = '{SLUG}-label'.format(SLUG=SLUG)
        if request.POST.get(show) == 'true' and (request.POST.get(label)
                                                 == ''):
            # Show item, but empty label, was just getting ignored
            return HttpResponseBadRequest(
                "A label is required for {SLUG}".format(SLUG=SLUG))
        if should_edit(SLUG):
            module[SLUG].show = json.loads(request.POST[show])
            module[SLUG].label[lang] = request.POST[label]

    if should_edit("root_module_id"):
        if not request.POST.get("root_module_id"):
            module["root_module_id"] = None
        else:
            try:
                app.get_module(module_id)
                module["root_module_id"] = request.POST.get("root_module_id")
            except ModuleNotFoundException:
                messages.error(_("Unknown Menu"))

    if should_edit('excl_form_ids') and isinstance(module, ShadowModule):
        excl = request.POST.getlist('excl_form_ids')
        excl.remove(
            '0'
        )  # Placeholder value to make sure excl_form_ids is POSTed when no forms are excluded
        module.excluded_form_ids = excl

    handle_media_edits(request, module, should_edit, resp, lang)

    app.save(resp)
    resp['case_list-show'] = module.requires_case_details()
    return HttpResponse(json.dumps(resp))
예제 #3
0
파일: forms.py 프로젝트: soitun/commcare-hq
def _edit_form_attr(request, domain, app_id, form_unique_id, attr):
    """
    Called to edit any (supported) form attribute, given by attr

    """

    ajax = json.loads(request.POST.get('ajax', 'true'))
    resp = {}

    app = get_app(domain, app_id)
    try:
        form = app.get_form(form_unique_id)
    except FormNotFoundException as e:
        if ajax:
            return HttpResponseBadRequest(str(e))
        else:
            messages.error(request, _("There was an error saving, please try again!"))
            return back_to_main(request, domain, app_id=app_id)
    lang = request.COOKIES.get('lang', app.langs[0])

    def should_edit(attribute):
        return attribute in request.POST

    if 'sha1' in request.POST and (should_edit("xform") or "xform" in request.FILES):
        conflict = _get_xform_conflict_response(form, request.POST['sha1'])
        if conflict is not None:
            return conflict

    if should_edit("name"):
        name = request.POST['name']
        form.name[lang] = name
        if not form.form_type == "shadow_form":
            xform = form.wrapped_xform()
            if xform.exists():
                xform.set_name(name)
                save_xform(app, form, xform.render())
        resp['update'] = {'.variable-form_name': clean_trans(form.name, [lang])}

    if should_edit('comment'):
        form.comment = request.POST['comment']

    if should_edit("xform") or "xform" in request.FILES:
        try:
            # support FILES for upload and POST for ajax post from Vellum
            try:
                xform = request.FILES.get('xform').read()
            except Exception:
                xform = request.POST.get('xform')
            else:
                try:
                    xform = str(xform, encoding="utf-8")
                except Exception:
                    raise Exception("Error uploading form: Please make sure your form is encoded in UTF-8")

            if request.POST.get('cleanup', False):
                try:
                    # First, we strip all newlines and reformat the DOM.
                    px = parseString(xform.replace('\r\n', '')).toprettyxml()
                    # Then we remove excess newlines from the DOM output.
                    text_re = re.compile(r'>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL)
                    prettyXml = text_re.sub(r'>\g<1></', px)
                    xform = prettyXml
                except Exception:
                    pass
            if xform:
                if isinstance(xform, str):
                    xform = xform.encode('utf-8')
                save_xform(app, form, xform)
            else:
                raise Exception("You didn't select a form to upload")
        except Exception as e:
            notify_exception(request, str(e))
            if ajax:
                return HttpResponseBadRequest(str(e))
            else:
                messages.error(request, str(e))
    if should_edit("references") or should_edit("case_references"):
        form.case_references = _get_case_references(request.POST)
    if should_edit("show_count"):
        show_count = request.POST['show_count']
        form.show_count = True if show_count == "True" else False
    if should_edit("put_in_root"):
        put_in_root = request.POST['put_in_root']
        form.put_in_root = True if put_in_root == "True" else False
    if should_edit('form_filter'):
        form.form_filter = request.POST['form_filter']
    if should_edit('post_form_workflow'):
        form.post_form_workflow = request.POST['post_form_workflow']
    if should_edit('auto_gps_capture'):
        form.auto_gps_capture = request.POST['auto_gps_capture'] == 'true'
    if should_edit('is_release_notes_form'):
        form.is_release_notes_form = request.POST['is_release_notes_form'] == 'true'
    if should_edit('enable_release_notes'):
        form.enable_release_notes = request.POST['enable_release_notes'] == 'true'
        if not form.is_release_notes_form and form.enable_release_notes:
            return json_response(
                {'message': _("You can't enable a form as release notes without allowing it as "
                    "a release notes form <TODO messaging>")},
                status_code=400
            )
    if (should_edit("form_links_xpath_expressions")
            and should_edit("form_links_form_ids")
            and toggles.FORM_LINK_WORKFLOW.enabled(domain)):
        form_links = zip(
            request.POST.getlist('form_links_xpath_expressions'),
            request.POST.getlist('form_links_form_ids'),
            [
                json.loads(datum_json) if datum_json else []
                for datum_json in request.POST.getlist('datums_json')
            ],
        )
        module_unique_ids = [m.unique_id for m in app.get_modules()]
        form.form_links = [FormLink(
            xpath=link[0],
            form_id=link[1] if link[1] not in module_unique_ids else None,
            module_unique_id=link[1] if link[1] in module_unique_ids else None,
            datums=[
                FormDatum(name=datum['name'], xpath=datum['xpath'])
                for datum in link[2]
            ]
        ) for link in form_links]

    if should_edit('post_form_workflow_fallback'):
        form.post_form_workflow_fallback = request.POST.get('post_form_workflow_fallback')

    if should_edit('custom_instances'):
        instances = json.loads(request.POST.get('custom_instances'))
        try:  # validate that custom instances can be added into the XML
            for instance in instances:
                etree.fromstring(
                    "<instance id='{}' src='{}' />".format(
                        instance.get('instanceId'),
                        instance.get('instancePath')
                    )
                )
        except etree.XMLSyntaxError as error:
            return json_response(
                {'message': _("There was an issue with your custom instances: {}").format(error)},
                status_code=400
            )

        form.custom_instances = [
            CustomInstance(
                instance_id=instance.get("instanceId"),
                instance_path=instance.get("instancePath"),
            ) for instance in instances
        ]

    if should_edit('custom_assertions'):
        assertions = json.loads(request.POST.get('custom_assertions'))
        try:  # validate that custom assertions can be added into the XML
            for assertion in assertions:
                etree.fromstring(
                    '<assertion test="{test}"><text><locale id="abc.def"/>{text}</text></assertion>'.format(
                        **assertion
                    )
                )
        except etree.XMLSyntaxError as error:
            return json_response(
                {'message': _("There was an issue with your custom assertions: {}").format(error)},
                status_code=400
            )

        existing_assertions = {assertion.test: assertion for assertion in form.custom_assertions}
        new_assertions = []
        for assertion in assertions:
            try:
                new_assertion = existing_assertions[assertion.get('test')]
                new_assertion.text[lang] = assertion.get('text')
            except KeyError:
                new_assertion = CustomAssertion(
                    test=assertion.get('test'),
                    text={lang: assertion.get('text')}
                )
            new_assertions.append(new_assertion)

        form.custom_assertions = new_assertions

    if should_edit("shadow_parent"):
        form.shadow_parent_form_id = request.POST['shadow_parent']

    if should_edit("custom_icon_form"):
        error_message = handle_custom_icon_edits(request, form, lang)
        if error_message:
            return json_response(
                {'message': error_message},
                status_code=400
            )

    if should_edit('session_endpoint_id'):
        raw_endpoint_id = request.POST['session_endpoint_id']
        try:
            set_session_endpoint(form, raw_endpoint_id, app)
        except InvalidSessionEndpoint as e:
            return json_response({'message': str(e)}, status_code=400)

    if should_edit('function_datum_endpoints'):
        if request.POST['function_datum_endpoints']:
            form.function_datum_endpoints = request.POST['function_datum_endpoints'].replace(" ", "").split(",")
        else:
            form.function_datum_endpoints = []

    handle_media_edits(request, form, should_edit, resp, lang)

    app.save(resp)
    notify_form_changed(domain, request.couch_user, app_id, form_unique_id)
    if ajax:
        return HttpResponse(json.dumps(resp))
    else:
        return back_to_main(request, domain, app_id=app_id, form_unique_id=form_unique_id)
예제 #4
0
def edit_module_attr(request, domain, app_id, module_unique_id, attr):
    """
    Called to edit any (supported) module attribute, given by attr
    """
    attributes = {
        "all": None,
        "auto_select_case": None,
        "case_list": ('case_list-show', 'case_list-label'),
        "case_list-menu_item_media_audio": None,
        "case_list-menu_item_media_image": None,
        'case_list-menu_item_use_default_image_for_all': None,
        'case_list-menu_item_use_default_audio_for_all': None,
        "case_list_form_id": None,
        "case_list_form_label": None,
        "case_list_form_media_audio": None,
        "case_list_form_media_image": None,
        'case_list_form_use_default_image_for_all': None,
        'case_list_form_use_default_audio_for_all': None,
        "case_list_post_form_workflow": None,
        "case_type": None,
        'comment': None,
        "display_separately": None,
        "has_schedule": None,
        "media_audio": None,
        "media_image": None,
        "module_filter": None,
        "name": None,
        "name_enum": None,
        "parent_module": None,
        "put_in_root": None,
        "root_module_id": None,
        "source_module_id": None,
        "task_list": ('task_list-show', 'task_list-label'),
        "excl_form_ids": None,
        "display_style": None,
        "custom_icon_form": None,
        "custom_icon_text_body": None,
        "custom_icon_xpath": None,
        "use_default_image_for_all": None,
        "use_default_audio_for_all": None,
    }

    if attr not in attributes:
        return HttpResponseBadRequest()

    def should_edit(attribute):
        if attribute == attr:
            return True
        if 'all' == attr:
            if attributes[attribute]:
                for param in attributes[attribute]:
                    if not request.POST.get(param):
                        return False
                return True
            else:
                return request.POST.get(attribute) is not None

    app = get_app(domain, app_id)

    try:
        module = app.get_module_by_unique_id(module_unique_id)
    except ModuleNotFoundException:
        # temporary fallback
        module = app.get_module(module_unique_id)

    lang = request.COOKIES.get('lang', app.langs[0])
    resp = {'update': {}, 'corrections': {}}
    if should_edit("custom_icon_form"):
        error_message = handle_custom_icon_edits(request, module, lang)
        if error_message:
            return json_response(
                {'message': error_message},
                status_code=400
            )

    if should_edit("name_enum"):
        name_enum = json.loads(request.POST.get("name_enum"))
        module.name_enum = [MappingItem(i) for i in name_enum]

    if should_edit("case_type"):
        case_type = request.POST.get("case_type", None)
        if case_type == USERCASE_TYPE and not isinstance(module, AdvancedModule):
            return HttpResponseBadRequest('"{}" is a reserved case type'.format(USERCASE_TYPE))
        elif case_type and not is_valid_case_type(case_type, module):
            return HttpResponseBadRequest("case type is improperly formatted")
        else:
            old_case_type = module["case_type"]
            module["case_type"] = case_type

            # rename other reference to the old case type
            all_advanced_modules = []
            modules_with_old_case_type_exist = False
            for mod in app.modules:
                if isinstance(mod, AdvancedModule):
                    all_advanced_modules.append(mod)

                modules_with_old_case_type_exist |= mod.case_type == old_case_type
            for mod in all_advanced_modules:
                for form in mod.forms:
                    for action in form.actions.get_load_update_actions():
                        if action.case_type == old_case_type and action.details_module == module_unique_id:
                            action.case_type = case_type

                    if mod.unique_id == module_unique_id or not modules_with_old_case_type_exist:
                        for action in form.actions.get_open_actions():
                            if action.case_type == old_case_type:
                                action.case_type = case_type

    if should_edit("put_in_root"):
        module["put_in_root"] = json.loads(request.POST.get("put_in_root"))
    if should_edit("display_style"):
        module["display_style"] = request.POST.get("display_style")
    if should_edit("source_module_id"):
        module["source_module_id"] = request.POST.get("source_module_id")
    if should_edit("display_separately"):
        module["display_separately"] = json.loads(request.POST.get("display_separately"))
    if should_edit("parent_module"):
        parent_module = request.POST.get("parent_module")
        module.parent_select.module_id = parent_module
        if module_case_hierarchy_has_circular_reference(module):
            return HttpResponseBadRequest(_("The case hierarchy contains a circular reference."))
    if should_edit("auto_select_case"):
        module["auto_select_case"] = request.POST.get("auto_select_case") == 'true'

    if app.enable_module_filtering and should_edit('module_filter'):
        module['module_filter'] = request.POST.get('module_filter')

    if should_edit('case_list_form_id'):
        module.case_list_form.form_id = request.POST.get('case_list_form_id')
    if should_edit('case_list_form_label'):
        module.case_list_form.label[lang] = request.POST.get('case_list_form_label')
    if should_edit('case_list_post_form_workflow'):
        module.case_list_form.post_form_workflow = request.POST.get('case_list_post_form_workflow')

    if should_edit("name"):
        name = request.POST.get("name", None)
        module["name"][lang] = name
        resp['update'] = {'.variable-module_name': trans(module.name, [lang], use_delim=False)}
    if should_edit('comment'):
        module.comment = request.POST.get('comment')
    for SLUG in ('case_list', 'task_list'):
        show = '{SLUG}-show'.format(SLUG=SLUG)
        label = '{SLUG}-label'.format(SLUG=SLUG)
        if request.POST.get(show) == 'true' and (request.POST.get(label) == ''):
            # Show item, but empty label, was just getting ignored
            return HttpResponseBadRequest("A label is required for {SLUG}".format(SLUG=SLUG))
        if should_edit(SLUG):
            module[SLUG].show = json.loads(request.POST[show])
            module[SLUG].label[lang] = request.POST[label]

    if should_edit("root_module_id"):
        old_root = module['root_module_id']
        if not request.POST.get("root_module_id"):
            module["root_module_id"] = None
        else:
            module["root_module_id"] = request.POST.get("root_module_id")
        if not old_root and module['root_module_id']:
            track_workflow(request.couch_user.username, "User associated module with a parent")
        elif old_root and not module['root_module_id']:
            track_workflow(request.couch_user.username, "User orphaned a child module")

    if should_edit('excl_form_ids') and isinstance(module, ShadowModule):
        excl = request.POST.getlist('excl_form_ids')
        excl.remove('0')  # Placeholder value to make sure excl_form_ids is POSTed when no forms are excluded
        module.excluded_form_ids = excl

    handle_media_edits(request, module, should_edit, resp, lang)
    handle_media_edits(request, module.case_list_form, should_edit, resp, lang, prefix='case_list_form_')
    handle_media_edits(request, module.case_list, should_edit, resp, lang, prefix='case_list-menu_item_')


    app.save(resp)
    resp['case_list-show'] = module.requires_case_details()
    return HttpResponse(json.dumps(resp))
예제 #5
0
                    )
                )
        except etree.XMLSyntaxError as error:
            return json_response(
                {'message': _("There was an issue with your custom instances: {}").format(error.message)},
                status_code=400
            )

        form.custom_instances = [
            CustomInstance(
                instance_id=instance.get("instanceId"),
                instance_path=instance.get("instancePath"),
            ) for instance in instances
        ]

    handle_media_edits(request, form, should_edit, resp, lang)

    app.save(resp)
    notify_form_changed(domain, request.couch_user, app_id, unique_form_id)
    if ajax:
        return HttpResponse(json.dumps(resp))
    else:
        return back_to_main(request, domain, app_id=app_id, unique_form_id=unique_form_id)


@no_conflict_require_POST
@require_can_edit_apps
def new_form(request, domain, app_id, module_id):
    "Adds a form to an app (under a module)"
    app = get_app(domain, app_id)
    lang = request.COOKIES.get('lang', app.langs[0])
예제 #6
0
            request.POST.getlist('form_links_form_ids'),
            [
                json.loads(datum_json) if datum_json else []
                for datum_json in request.POST.getlist('datums_json')
            ],
        )
        form.form_links = [FormLink(
            xpath=link[0],
            form_id=link[1],
            datums=[
                FormDatum(name=datum['name'], xpath=datum['xpath'])
                for datum in link[2]
            ]
        ) for link in form_links]

    handle_media_edits(request, form, should_edit, resp, lang)

    app.save(resp)
    notify_form_changed(domain, request.couch_user, app_id, unique_form_id)
    if ajax:
        return HttpResponse(json.dumps(resp))
    else:
        return back_to_main(request, domain, app_id=app_id, unique_form_id=unique_form_id)


@no_conflict_require_POST
@require_can_edit_apps
def new_form(request, domain, app_id, module_id):
    "Adds a form to an app (under a module)"
    app = get_app(domain, app_id)
    lang = request.COOKIES.get('lang', app.langs[0])
예제 #7
0
파일: forms.py 프로젝트: dimagi/commcare-hq
def _edit_form_attr(request, domain, app_id, form_unique_id, attr):
    """
    Called to edit any (supported) form attribute, given by attr

    """

    ajax = json.loads(request.POST.get('ajax', 'true'))
    resp = {}

    app = get_app(domain, app_id)
    try:
        form = app.get_form(form_unique_id)
    except FormNotFoundException as e:
        if ajax:
            return HttpResponseBadRequest(six.text_type(e))
        else:
            messages.error(request, _("There was an error saving, please try again!"))
            return back_to_main(request, domain, app_id=app_id)
    lang = request.COOKIES.get('lang', app.langs[0])

    def should_edit(attribute):
        return attribute in request.POST

    if 'sha1' in request.POST and (should_edit("xform") or "xform" in request.FILES):
        conflict = _get_xform_conflict_response(form, request.POST['sha1'])
        if conflict is not None:
            return conflict

    if should_edit("name"):
        name = request.POST['name']
        form.name[lang] = name
        if not form.form_type == "shadow_form":
            xform = form.wrapped_xform()
            if xform.exists():
                xform.set_name(name)
                save_xform(app, form, xform.render())
        resp['update'] = {'.variable-form_name': trans(form.name, [lang], use_delim=False)}

    if should_edit('comment'):
        form.comment = request.POST['comment']

    if should_edit("name_enum"):
        name_enum = json.loads(request.POST.get("name_enum"))
        form.name_enum = [MappingItem(i) for i in name_enum]

    if should_edit("xform") or "xform" in request.FILES:
        try:
            # support FILES for upload and POST for ajax post from Vellum
            try:
                xform = request.FILES.get('xform').read()
            except Exception:
                xform = request.POST.get('xform')
            else:
                try:
                    xform = six.text_type(xform, encoding="utf-8")
                except Exception:
                    raise Exception("Error uploading form: Please make sure your form is encoded in UTF-8")
            if request.POST.get('cleanup', False):
                try:
                    # First, we strip all newlines and reformat the DOM.
                    px = parseString(xform.replace('\r\n', '')).toprettyxml()
                    # Then we remove excess newlines from the DOM output.
                    text_re = re.compile(r'>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL)
                    prettyXml = text_re.sub(r'>\g<1></', px)
                    xform = prettyXml
                except Exception:
                    pass
            if xform:
                if isinstance(xform, six.text_type):
                    xform = xform.encode('utf-8')
                save_xform(app, form, xform)
            else:
                raise Exception("You didn't select a form to upload")
        except Exception as e:
            notify_exception(request, six.text_type(e))
            if ajax:
                return HttpResponseBadRequest(six.text_type(e))
            else:
                messages.error(request, six.text_type(e))
    if should_edit("references") or should_edit("case_references"):
        form.case_references = _get_case_references(request.POST)
    if should_edit("show_count"):
        show_count = request.POST['show_count']
        form.show_count = True if show_count == "True" else False
    if should_edit("put_in_root"):
        put_in_root = request.POST['put_in_root']
        form.put_in_root = True if put_in_root == "True" else False
    if should_edit('form_filter'):
        form.form_filter = request.POST['form_filter']
    if should_edit('post_form_workflow'):
        form.post_form_workflow = request.POST['post_form_workflow']
    if should_edit('auto_gps_capture'):
        form.auto_gps_capture = request.POST['auto_gps_capture'] == 'true'
    if should_edit('is_release_notes_form'):
        form.is_release_notes_form = request.POST['is_release_notes_form'] == 'true'
    if should_edit('enable_release_notes'):
        form.enable_release_notes = request.POST['enable_release_notes'] == 'true'
        if not form.is_release_notes_form and form.enable_release_notes:
            return json_response(
                {'message': _("You can't enable a form as release notes without allowing it as "
                    "a release notes form <TODO messaging>")},
                status_code=400
            )
    if should_edit('no_vellum'):
        form.no_vellum = request.POST['no_vellum'] == 'true'
    if (should_edit("form_links_xpath_expressions") and
            should_edit("form_links_form_ids") and
            toggles.FORM_LINK_WORKFLOW.enabled(domain)):
        form_links = zip(
            request.POST.getlist('form_links_xpath_expressions'),
            request.POST.getlist('form_links_form_ids'),
            [
                json.loads(datum_json) if datum_json else []
                for datum_json in request.POST.getlist('datums_json')
            ],
        )
        form.form_links = [FormLink(
            xpath=link[0],
            form_id=link[1],
            datums=[
                FormDatum(name=datum['name'], xpath=datum['xpath'])
                for datum in link[2]
            ]
        ) for link in form_links]

    if should_edit('post_form_workflow_fallback'):
        form.post_form_workflow_fallback = request.POST.get('post_form_workflow_fallback')

    if should_edit('custom_instances'):
        instances = json.loads(request.POST.get('custom_instances'))
        try:  # validate that custom instances can be added into the XML
            for instance in instances:
                etree.fromstring(
                    "<instance id='{}' src='{}' />".format(
                        instance.get('instanceId'),
                        instance.get('instancePath')
                    )
                )
        except etree.XMLSyntaxError as error:
            return json_response(
                {'message': _("There was an issue with your custom instances: {}").format(error.message)},
                status_code=400
            )

        form.custom_instances = [
            CustomInstance(
                instance_id=instance.get("instanceId"),
                instance_path=instance.get("instancePath"),
            ) for instance in instances
        ]

    if should_edit('custom_assertions'):
        assertions = json.loads(request.POST.get('custom_assertions'))
        try:  # validate that custom assertions can be added into the XML
            for assertion in assertions:
                etree.fromstring(
                    '<assertion test="{test}"><text><locale id="abc.def"/>{text}</text></assertion>'.format(
                        **assertion
                    )
                )
        except etree.XMLSyntaxError as error:
            return json_response(
                {'message': _("There was an issue with your custom assertions: {}").format(error.message)},
                status_code=400
            )

        existing_assertions = {assertion.test: assertion for assertion in form.custom_assertions}
        new_assertions = []
        for assertion in assertions:
            try:
                new_assertion = existing_assertions[assertion.get('test')]
                new_assertion.text[lang] = assertion.get('text')
            except KeyError:
                new_assertion = CustomAssertion(
                    test=assertion.get('test'),
                    text={lang: assertion.get('text')}
                )
            new_assertions.append(new_assertion)

        form.custom_assertions = new_assertions

    if should_edit("shadow_parent"):
        form.shadow_parent_form_id = request.POST['shadow_parent']

    if should_edit("custom_icon_form"):
        error_message = handle_custom_icon_edits(request, form, lang)
        if error_message:
            return json_response(
                {'message': error_message},
                status_code=400
            )
    handle_media_edits(request, form, should_edit, resp, lang)

    app.save(resp)
    notify_form_changed(domain, request.couch_user, app_id, form_unique_id)
    if ajax:
        return HttpResponse(json.dumps(resp))
    else:
        return back_to_main(request, domain, app_id=app_id, form_unique_id=form_unique_id)
예제 #8
0
def _edit_form_attr(request, domain, app_id, form_unique_id, attr):
    """
    Called to edit any (supported) form attribute, given by attr

    """

    ajax = json.loads(request.POST.get('ajax', 'true'))
    resp = {}

    app = get_app(domain, app_id)
    try:
        form = app.get_form(form_unique_id)
    except FormNotFoundException as e:
        if ajax:
            return HttpResponseBadRequest(unicode(e))
        else:
            messages.error(request,
                           _("There was an error saving, please try again!"))
            return back_to_main(request, domain, app_id=app_id)
    lang = request.COOKIES.get('lang', app.langs[0])

    def should_edit(attribute):
        return attribute in request.POST

    if should_edit("name"):
        name = request.POST['name']
        form.name[lang] = name
        if not form.form_type == "shadow_form":
            xform = form.wrapped_xform()
            if xform.exists():
                xform.set_name(name)
                save_xform(app, form, xform.render())
        resp['update'] = {
            '.variable-form_name': trans(form.name, [lang], use_delim=False)
        }
    if should_edit('comment'):
        form.comment = request.POST['comment']
    if should_edit("xform") or "xform" in request.FILES:
        try:
            # support FILES for upload and POST for ajax post from Vellum
            try:
                xform = request.FILES.get('xform').read()
            except Exception:
                xform = request.POST.get('xform')
            else:
                try:
                    xform = unicode(xform, encoding="utf-8")
                except Exception:
                    raise Exception(
                        "Error uploading form: Please make sure your form is encoded in UTF-8"
                    )
            if request.POST.get('cleanup', False):
                try:
                    # First, we strip all newlines and reformat the DOM.
                    px = parseString(xform.replace('\r\n', '')).toprettyxml()
                    # Then we remove excess newlines from the DOM output.
                    text_re = re.compile('>\n\s+([^<>\s].*?)\n\s+</',
                                         re.DOTALL)
                    prettyXml = text_re.sub('>\g<1></', px)
                    xform = prettyXml
                except Exception:
                    pass
            if xform:
                save_xform(app, form, xform)
            else:
                raise Exception("You didn't select a form to upload")
        except Exception as e:
            if ajax:
                return HttpResponseBadRequest(unicode(e))
            else:
                messages.error(request, unicode(e))
    if should_edit("references") or should_edit("case_references"):
        form.case_references = _get_case_references(request.POST)
    if should_edit("show_count"):
        show_count = request.POST['show_count']
        form.show_count = True if show_count == "True" else False
    if should_edit("put_in_root"):
        put_in_root = request.POST['put_in_root']
        form.put_in_root = True if put_in_root == "True" else False
    if should_edit('form_filter'):
        form.form_filter = request.POST['form_filter']
    if should_edit('post_form_workflow'):
        form.post_form_workflow = request.POST['post_form_workflow']
    if should_edit('auto_gps_capture'):
        form.auto_gps_capture = request.POST['auto_gps_capture'] == 'true'
    if should_edit('no_vellum'):
        form.no_vellum = request.POST['no_vellum'] == 'true'
    if (should_edit("form_links_xpath_expressions")
            and should_edit("form_links_form_ids")
            and toggles.FORM_LINK_WORKFLOW.enabled(domain)):
        form_links = zip(
            request.POST.getlist('form_links_xpath_expressions'),
            request.POST.getlist('form_links_form_ids'),
            [
                json.loads(datum_json) if datum_json else []
                for datum_json in request.POST.getlist('datums_json')
            ],
        )
        form.form_links = [
            FormLink(xpath=link[0],
                     form_id=link[1],
                     datums=[
                         FormDatum(name=datum['name'], xpath=datum['xpath'])
                         for datum in link[2]
                     ]) for link in form_links
        ]

    if should_edit('post_form_workflow_fallback'):
        form.post_form_workflow_fallback = request.POST.get(
            'post_form_workflow_fallback')

    if should_edit('custom_instances'):
        instances = json.loads(request.POST.get('custom_instances'))
        try:  # validate that custom instances can be added into the XML
            for instance in instances:
                etree.fromstring("<instance id='{}' src='{}' />".format(
                    instance.get('instanceId'), instance.get('instancePath')))
        except etree.XMLSyntaxError as error:
            return json_response(
                {
                    'message':
                    _("There was an issue with your custom instances: {}").
                    format(error.message)
                },
                status_code=400)

        form.custom_instances = [
            CustomInstance(
                instance_id=instance.get("instanceId"),
                instance_path=instance.get("instancePath"),
            ) for instance in instances
        ]
    if should_edit("shadow_parent"):
        form.shadow_parent_form_id = request.POST['shadow_parent']

    if should_edit("custom_icon_form"):
        error_message = handle_custom_icon_edits(request, form, lang)
        if error_message:
            return json_response({'message': error_message}, status_code=400)
    handle_media_edits(request, form, should_edit, resp, lang)

    app.save(resp)
    notify_form_changed(domain, request.couch_user, app_id, form_unique_id)
    if ajax:
        return HttpResponse(json.dumps(resp))
    else:
        return back_to_main(request,
                            domain,
                            app_id=app_id,
                            form_unique_id=form_unique_id)