def get_apps_modules(domain, current_app_id=None, current_module_id=None, app_doc_types=('Application',)): """ Returns a domain's Applications and their modules. If current_app_id and current_module_id are given, "is_current" is set to True for them. The interface uses this to select the current app and module by default. Linked and remote apps are omitted. Use the app_doc_types parameter to change this behaviour. (Deleted apps are not returned because the underlying Couch view doesn't include them.) """ return [ { 'app_id': app.id, 'name': app.name, 'is_current': app.id == current_app_id, 'modules': [{ 'module_id': module.id, 'name': clean_trans(module.name, app.langs), 'is_current': module.unique_id == current_module_id, } for module in app.modules] } for app in get_apps_in_domain(domain) # No linked, deleted or remote apps. (Use app.doc_type not # app.get_doc_type() so that the suffix isn't dropped.) if app.doc_type in app_doc_types ]
def get_apps_modules(domain, current_app_id=None, current_module_id=None, app_doc_types=('Application',)): """ Returns a domain's Applications and their modules. If current_app_id and current_module_id are given, "is_current" is set to True for them. The interface uses this to select the current app and module by default. Linked and remote apps are omitted. Use the app_doc_types parameter to change this behaviour. (Deleted apps are not returned because the underlying Couch view doesn't include them.) """ return [ { 'app_id': app.id, 'name': app.name, 'is_current': app.id == current_app_id, 'modules': [{ 'module_id': module.id, 'name': clean_trans(module.name, app.langs), 'is_current': module.unique_id == current_module_id, } for module in app.get_modules()] } for app in get_apps_in_domain(domain) # No linked, deleted or remote apps. (Use app.doc_type not # app.get_doc_type() so that the suffix isn't dropped.) if app.doc_type in app_doc_types ]
def all_media(self, lang=None): kwargs = self.get_media_ref_kwargs() media = [] media.extend(self.menu_media(self, lang=lang)) # Registration from case list if self.case_list_form.form_id: media.extend(self.menu_media(self.case_list_form, lang=lang)) # Case list menu item if hasattr(self, 'case_list') and self.case_list.show: media.extend(self.menu_media(self.case_list, lang=lang)) for name, details, display in self.get_details(): # Case list lookup - not language-specific if display and details.display == 'short' and details.lookup_enabled and details.lookup_image: media.append( ApplicationMediaReference(details.lookup_image, media_class=CommCareImage, is_menu_media=True, **kwargs)) # Print template - not language-specific if display and details.display == 'long' and details.print_template: media.append( ApplicationMediaReference(details.print_template['path'], media_class=CommCareMultimedia, **kwargs)) # Icon-formatted columns for column in details.get_columns(): if column.format == 'enum-image': for map_item in column.enum: icon = clean_trans(map_item.value, [lang] + self.get_app().langs) if icon: media.append( ApplicationMediaReference( icon, media_class=CommCareImage, is_menu_media=True, **kwargs)) return media
def get_casedb_schema(form): """Get case database schema definition for vellum to display as an external data source. This lists all case types and their properties for the given app. """ app = form.get_app() subsets = [] if form.requires_case() and not form.get_module().search_config.data_registry: subsets.extend(_get_case_schema_subsets(app, form.get_module().case_type)) parent_select = getattr(form.get_module(), 'parent_select', None) if parent_select and parent_select.active and parent_select.relationship is None: # for child modules that use parent select where the parent is not a 'related' case # See toggles.NON_PARENT_MENU_SELECTION parent_module = app.get_module_by_unique_id(parent_select.module_id) source = clean_trans(parent_module.name, app.langs) subsets.extend(_get_case_schema_subsets(app, parent_module.case_type, source=source)) if is_usercase_in_use(app.domain): subsets.append({ "id": USERCASE_TYPE, "name": "user", "key": "@case_type", "structure": {p: {} for p in get_usercase_properties(app)[USERCASE_TYPE]}, }) return { "id": "casedb", "uri": "jr://instance/casedb", "name": "case", "path": "/casedb/case", "structure": {}, "subsets": subsets, }
def trans(d): return clean_trans(d, langs)
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)
def get_session_schema(form): """Get form session schema definition """ from corehq.apps.app_manager.suite_xml.sections.entries import EntriesHelper app = form.get_app() structure = {} datums = EntriesHelper(app).get_datums_meta_for_form_generic(form) datums = [ d for d in datums if d.requires_selection and d.case_type and not d.is_new_case_id ] def _get_structure(datum, data_registry, source=None): id_source = f":{slugify(source)}" if source else "" return { "reference": { "hashtag": f'#registry_case{id_source}' if data_registry else f"#case{id_source}", "source": "registry" if data_registry else "casedb", "subset": f"case{id_source}", "key": "@case_id", }, } unrelated_parents = set() for datum in datums: if not datum.module_id: continue module = app.get_module_by_unique_id(datum.module_id) parent_select_active = hasattr( module, 'parent_select') and module.parent_select.active if parent_select_active and module.parent_select.relationship is None: # for child modules that use parent select where the parent is not a 'related' case # See toggles.NON_PARENT_MENU_SELECTION unrelated_parents.add(module.parent_select.module_id) data_structure = {} for i, datum in enumerate(reversed(datums)): if isinstance(datum.datum, InstanceDatum): continue module_id = datum.module_id module = app.get_module_by_unique_id(module_id) if module_id else None data_registry = module.search_config.data_registry if module else None if i == 0: # always add the datum for this module data_structure[datum.datum.id] = _get_structure( datum, data_registry) else: if module and module_id in unrelated_parents: source = clean_trans( module.name, app.langs ) # ensure that this structure reference is unique data_structure[datum.datum.id] = _get_structure( datum, data_registry, source) if data_structure: structure["data"] = { "merge": True, "structure": data_structure, } if is_usercase_in_use(app.domain): structure["context"] = { "merge": True, "structure": { "userid": { "reference": { "hashtag": "#user", "source": "casedb", "subset": USERCASE_TYPE, "subset_key": "@case_type", "subset_filter": True, "key": "hq_user_id", }, }, }, } return { "id": "commcaresession", "uri": "jr://instance/session", "name": "Session", "path": "/session", "structure": structure, }