Exemple #1
0
def revert_to_copy(request, domain, app_id):
    """
    Copies a saved doc back to the original.
    See VersionedDoc.revert_to_copy

    """
    app = get_app(domain, app_id)
    copy = get_app(domain, request.POST['saved_app'])
    if copy.get_doc_type() == 'LinkedApplication' and app.get_doc_type() == 'Application':
        copy.convert_to_application()
    app = app.make_reversion_to_copy(copy)
    app.save()
    messages.success(
        request,
        _("Successfully reverted to version %(old_version)s, now at version %(new_version)s") % {
            'old_version': copy.version,
            'new_version': app.version,
        }
    )
    copy_build_comment_params = {
        "old_version": copy.version,
        "original_comment": copy.build_comment,
    }
    if copy.build_comment:
        copy_build_comment_template = _(
            "Reverted to version {old_version}\n\nPrevious build comments:\n{original_comment}")
    else:
        copy_build_comment_template = _("Reverted to version {old_version}")

    copy = app.make_build(
        comment=copy_build_comment_template.format(**copy_build_comment_params),
        user_id=request.couch_user.get_id,
    )
    copy.save(increment_version=False)
    return back_to_main(request, domain, app_id=app_id)
Exemple #2
0
def revert_to_copy(request, domain, app_id):
    """
    Copies a saved doc back to the original.
    See VersionedDoc.revert_to_copy

    """
    app = get_app(domain, app_id)
    copy = get_app(domain, request.POST['saved_app'])
    app = app.make_reversion_to_copy(copy)
    app.save()
    messages.success(
        request,
        "Successfully reverted to version %s, now at version %s" % (copy.version, app.version)
    )
    if copy.build_comment:
        new_build_comment = "Reverted to version {old_version}\n\n{original_comment}".format(
            old_version=copy.version, original_comment=copy.build_comment)
    else:
        new_build_comment = "Reverted to version {old_version}".format(old_version=copy.version)
    copy = app.make_build(
        comment=new_build_comment,
        user_id=request.couch_user.get_id,
    )
    copy.save(increment_version=False)
    return back_to_main(request, domain, app_id=app_id)
Exemple #3
0
def save_copy(request, domain, app_id):
    """
    Saves a copy of the app to a new doc.
    See VersionedDoc.save_copy

    """
    track_built_app_on_hubspot_v2.delay(request.couch_user)
    comment = request.POST.get('comment')
    app = get_app(domain, app_id)
    try:
        errors = app.validate_app()
    except ModuleIdMissingException:
        # For apps (mainly Exchange apps) that lost unique_id attributes on Module
        app.ensure_module_unique_ids(should_save=True)
        errors = app.validate_app()

    if not errors:
        try:
            user_id = request.couch_user.get_id
            timer = datadog_bucket_timer('commcare.app_build.new_release', tags=[],
                                         timing_buckets=(1, 10, 30, 60, 120, 240))
            with timer:
                copy = app.make_build(
                    comment=comment,
                    user_id=user_id,
                )
                copy.save(increment_version=False)
            CouchUser.get(user_id).set_has_built_app()
        finally:
            # To make a RemoteApp always available for building
            if app.is_remote_app():
                app.save(increment_version=True)

        _track_build_for_app_preview(domain, request.couch_user, app_id, 'User created a build')

    else:
        copy = None
    copy = copy and SavedAppBuild.wrap(copy.to_json()).releases_list_json(
        get_timezone_for_user(request.couch_user, domain)
    )
    lang, langs = get_langs(request, app)
    if copy:
        # Set if build is supported for Java Phones
        j2me_enabled_configs = CommCareBuildConfig.j2me_enabled_config_labels()
        copy['j2me_enabled'] = copy['menu_item_label'] in j2me_enabled_configs

    return json_response({
        "saved_app": copy,
        "error_html": render_to_string("app_manager/partials/build_errors.html", {
            'request': request,
            'app': get_app(domain, app_id),
            'build_errors': errors,
            'domain': domain,
            'langs': langs,
            'lang': lang
        }),
    })
Exemple #4
0
def delete_copy(request, domain, app_id):
    """
    Deletes a saved copy permanently from the database.
    See VersionedDoc.delete_copy

    """
    app = get_app(domain, app_id)
    copy = get_app(domain, request.POST["saved_app"])
    app.delete_copy(copy)
    return json_response({})
Exemple #5
0
def revert_to_copy(request, domain, app_id):
    """
    Copies a saved doc back to the original.
    See VersionedDoc.revert_to_copy

    """
    app = get_app(domain, app_id)
    copy = get_app(domain, request.POST["saved_app"])
    app = app.make_reversion_to_copy(copy)
    app.save()
    messages.success(request, "Successfully reverted to version %s, now at version %s" % (copy.version, app.version))
    return back_to_main(request, domain, app_id=app_id)
Exemple #6
0
def save_copy(request, domain, app_id):
    """
    Saves a copy of the app to a new doc.
    See VersionedDoc.save_copy

    """
    track_built_app_on_hubspot.delay(request.couch_user)
    comment = request.POST.get("comment")
    app = get_app(domain, app_id)
    try:
        errors = app.validate_app()
    except ModuleIdMissingException:
        # For apps (mainly Exchange apps) that lost unique_id attributes on Module
        app.ensure_module_unique_ids(should_save=True)
        errors = app.validate_app()

    if not errors:
        try:
            copy = app.make_build(
                comment=comment,
                user_id=request.couch_user.get_id,
                previous_version=app.get_latest_app(released_only=False),
            )
            copy.save(increment_version=False)
        finally:
            # To make a RemoteApp always available for building
            if app.is_remote_app():
                app.save(increment_version=True)
    else:
        copy = None
    copy = copy and SavedAppBuild.wrap(copy.to_json()).to_saved_build_json(
        get_timezone_for_user(request.couch_user, domain)
    )
    lang, langs = get_langs(request, app)
    return json_response(
        {
            "saved_app": copy,
            "error_html": render_to_string(
                "app_manager/partials/build_errors.html",
                {
                    "app": get_app(domain, app_id),
                    "build_errors": errors,
                    "domain": domain,
                    "langs": langs,
                    "lang": lang,
                },
            ),
        }
    )
Exemple #7
0
    def __init__(self, from_domain, app_id, *args, **kwargs):
        export_zipped_apps_enabled = kwargs.pop('export_zipped_apps_enabled', False)
        super(CopyApplicationForm, self).__init__(*args, **kwargs)
        fields = ['domain', 'name', 'toggles']
        if app_id:
            app = get_app(from_domain, app_id)
            if app:
                self.fields['name'].initial = app.name
        if export_zipped_apps_enabled:
            self.fields['gzip'] = forms.FileField(required=False)
            fields.append('gzip')

        self.helper = FormHelper()
        self.helper.label_class = 'col-sm-3 col-md-4 col-lg-2'
        self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6'
        self.helper.layout = Layout(
            Fieldset(
                _('Copy Application'),
                *fields
            ),
            Hidden('app', app_id),
            hqcrispy.FormActions(
                StrictButton(_('Copy'), type='button', css_class='btn-primary')
            )
        )
Exemple #8
0
 def get_app_name(self, app_id):
     try:
         app = get_app(self.domain, app_id)
     except ResourceNotFound:
         pass
     else:
         return app.name
Exemple #9
0
def edit_app_langs(request, domain, app_id):
    """
    Called with post body:
    {
        langs: ["en", "es", "hin"],
        rename: {
            "hi": "hin",
            "en": "en",
            "es": "es"
        },
        build: ["es", "hin"]
    }
    """
    app = get_app(domain, app_id)
    try:
        langs, rename, build = validate_langs(request, app.langs)
    except AssertionError:
        return HttpResponse(status=400)

    # now do it
    for old, new in rename.items():
        if old != new:
            app.rename_lang(old, new)

    def replace_all(list1, list2):
        if list1 != list2:
            while list1:
                list1.pop()
            list1.extend(list2)
    replace_all(app.langs, langs)
    replace_all(app.build_langs, build)

    app.save()
    return json_response(langs)
Exemple #10
0
def releases_ajax(request, domain, app_id, template='app_manager/partials/releases.html'):
    app = get_app(domain, app_id)
    context = get_apps_base_context(request, domain, app)
    can_send_sms = domain_has_privilege(domain, privileges.OUTBOUND_SMS)
    build_profile_access = domain_has_privilege(domain, privileges.BUILD_PROFILES)

    context.update({
        'release_manager': True,
        'can_send_sms': can_send_sms,
        'has_mobile_workers': get_doc_count_in_domain_by_class(domain, CommCareUser) > 0,
        'sms_contacts': (
            get_sms_autocomplete_context(request, domain)['sms_contacts']
            if can_send_sms else []
        ),
        'build_profile_access': build_profile_access
    })
    if not app.is_remote_app():
        # Multimedia is not supported for remote applications at this time.
        try:
            multimedia_state = app.check_media_state()
            context.update({
                'multimedia_state': multimedia_state,
            })
        except ReportConfigurationNotFoundError:
            pass
    response = render(request, template, context)
    response.set_cookie('lang', encode_if_unicode(context['lang']))
    return response
Exemple #11
0
def copy_app(request, domain):
    app_id = request.POST.get('app')
    app = get_app(domain, app_id)
    form = CopyApplicationForm(
        domain, app, request.POST,
        export_zipped_apps_enabled=toggles.EXPORT_ZIPPED_APPS.enabled(request.user.username)
    )
    if not form.is_valid():
        from corehq.apps.app_manager.views.view_generic import view_generic
        return view_generic(request, domain, app_id=app_id, copy_app_form=form)

    gzip = request.FILES.get('gzip')
    if gzip:
        with zipfile.ZipFile(gzip, 'r', zipfile.ZIP_DEFLATED) as z:
            source = z.read(z.filelist[0].filename)
        app_id_or_source = source
    else:
        app_id_or_source = app_id

    def _inner(request, link_domain, data, master_domain=domain):
        clear_app_cache(request, link_domain)
        if data['toggles']:
            for slug in data['toggles'].split(","):
                set_toggle(slug, link_domain, True, namespace=toggles.NAMESPACE_DOMAIN)
        linked = data.get('linked')
        if linked:
            return _create_linked_app(request, app, link_domain, data['name'])
        else:
            return _copy_app_helper(
                request, master_domain, app_id_or_source, link_domain, data['name'], app_id)

    # having login_and_domain_required validates that the user
    # has access to the domain we're copying the app to
    return login_and_domain_required(_inner)(request, form.cleaned_data['domain'], form.cleaned_data)
Exemple #12
0
 def __getitem__(self, item):
     if not self.has_key(item):
         try:
             self[item] = get_app(app_id=item, domain=self.domain)
         except Http404:
             pass
     return super(AppCache, self).__getitem__(item)
Exemple #13
0
def choose_media(request, domain, app_id):
    # TODO: Add error handling
    app = get_app(domain, app_id)
    media_type = request.POST['media_type']
    media_id = request.POST['id']
    if media_type == 'Image':
        file = CommCareImage.get(media_id)
    elif media_type == 'Audio':
        file = CommCareImage.get(media_id)
    else:
        raise Http404()

    if file is None or not file.is_shared:
        return HttpResponse(json.dumps({
            'match_found': False
        }))

    file.add_domain(domain)
    app.create_mapping(file, request.POST['path'])
    if media_type == 'Image':
        return HttpResponse(json.dumps({
            'match_found': True,
            'image': {'m_id': file._id, 'url': file.url()},
            'file': True
        }))
    elif media_type == 'Audio':
        return HttpResponse(json.dumps({'match_found': True, 'audio': {'m_id': file._id, 'url': file.url()}}))
    else:
        raise Http404()
Exemple #14
0
def new_module(request, domain, app_id):
    "Adds a module to an app"
    app = get_app(domain, app_id)
    lang = request.COOKIES.get('lang', app.langs[0])
    name = request.POST.get('name')
    module_type = request.POST.get('module_type', 'case')
    if module_type == 'case':
        module = app.add_module(Module.new_module(name, lang))
        module_id = module.id
        app.new_form(module_id, "Untitled Form", lang)
        app.save()
        response = back_to_main(request, domain, app_id=app_id, module_id=module_id)
        response.set_cookie('suppress_build_errors', 'yes')
        return response
    elif module_type in MODULE_TYPE_MAP:
        fn = MODULE_TYPE_MAP[module_type][FN]
        validations = MODULE_TYPE_MAP[module_type][VALIDATIONS]
        error = next((v[1] for v in validations if v[0](app)), None)
        if error:
            messages.warning(request, error)
            return back_to_main(request, domain, app_id=app.id)
        else:
            return fn(request, domain, app, name, lang)
    else:
        logger.error('Unexpected module type for new module: "%s"' % module_type)
        return back_to_main(request, domain, app_id=app_id)
Exemple #15
0
def edit_visit_schedule(request, domain, app_id, module_id, form_id):
    app = get_app(domain, app_id)
    module = app.get_module(module_id)
    form = module.get_form(form_id)

    json_loads = json.loads(request.POST.get('schedule'))
    enabled = json_loads.pop('enabled')
    anchor = json_loads.pop('anchor')
    schedule_form_id = json_loads.pop('schedule_form_id')

    if enabled:
        try:
            phase, is_new_phase = module.get_or_create_schedule_phase(anchor=anchor)
        except ScheduleError as e:
            return HttpResponseBadRequest(unicode(e))
        form.schedule_form_id = schedule_form_id
        form.schedule = FormSchedule.wrap(json_loads)
        phase.add_form(form)
    else:
        try:
            form.disable_schedule()
        except ScheduleError:
            pass

    response_json = {}
    app.save(response_json)
    return json_response(response_json)
Exemple #16
0
def download_bulk_ui_translations(request, domain, app_id):
    app = get_app(domain, app_id)
    temp = build_ui_translation_download_file(app)
    filename = '{app_name} v.{app_version} - CommCare Translations'.format(
        app_name=app.name,
        app_version=app.version)
    return export_response(temp, Format.XLS_2007, filename)
Exemple #17
0
def upload_bulk_ui_translations(request, domain, app_id):
    success = False
    try:
        app = get_app(domain, app_id)
        trans_dict, error_properties = process_ui_translation_upload(
            app, request.file
        )
        if error_properties:
            message = _("We found problem with following translations:")
            message += "<br>"
            for prop in error_properties:
                message += "<li>%s</li>" % prop
            messages.error(request, message, extra_tags='html')
        else:
            app.translations = dict(trans_dict)
            app.save()
            success = True
    except Exception:
        notify_exception(request, 'Bulk Upload Translations Error')
        messages.error(request, _("Something went wrong! Update failed. We're looking into it"))

    if success:
        messages.success(request, _("UI Translations Updated!"))

    return HttpResponseRedirect(reverse('app_languages', args=[domain, app_id]))
Exemple #18
0
def get_restore_response(domain, couch_user, app_id=None, since=None, version='1.0',
                         state=None, items=False, force_cache=False,
                         cache_timeout=None, overwrite_cache=False,
                         force_restore_mode=None):
    # not a view just a view util
    if not couch_user.is_commcare_user():
        return HttpResponse("No linked chw found for %s" % couch_user.username,
                            status=401)  # Authentication Failure
    elif domain != couch_user.domain:
        return HttpResponse("%s was not in the domain %s" % (couch_user.username, domain),
                            status=401)

    project = Domain.get_by_name(domain)
    app = get_app(domain, app_id) if app_id else None
    restore_config = RestoreConfig(
        project=project,
        user=couch_user.to_casexml_user(),
        params=RestoreParams(
            sync_log_id=since,
            version=version,
            state_hash=state,
            include_item_count=items,
            force_restore_mode=force_restore_mode,
            app=app,
        ),
        cache_settings=RestoreCacheSettings(
            force_cache=force_cache,
            cache_timeout=cache_timeout,
            overwrite_cache=overwrite_cache
        ),
    )
    return restore_config.get_response()
Exemple #19
0
def validate_form_for_build(request, domain, app_id, unique_form_id, ajax=True):
    app = get_app(domain, app_id)
    try:
        form = app.get_form(unique_form_id)
    except FormNotFoundException:
        # this can happen if you delete the form from another page
        raise Http404()
    errors = form.validate_for_build()
    lang, langs = get_langs(request, app)

    if ajax and "blank form" in [error.get('type') for error in errors]:
        response_html = render_to_string('app_manager/partials/create_form_prompt.html')
    else:
        response_html = render_to_string('app_manager/partials/build_errors.html', {
            'app': app,
            'form': form,
            'build_errors': errors,
            'not_actual_build': True,
            'domain': domain,
            'langs': langs,
            'lang': lang
        })

    if ajax:
        return json_response({
            'error_html': response_html,
        })
    else:
        return HttpResponse(response_html)
Exemple #20
0
def odk_media_qr_code(request, domain, app_id):
    profile = request.GET.get('profile')
    download_target_version = request.GET.get('download_target_version') == 'true'
    qr_code = get_app(domain, app_id).get_odk_qr_code(
        with_media=True, build_profile_id=profile, download_target_version=download_target_version
    )
    return HttpResponse(qr_code, content_type="image/png")
Exemple #21
0
def get_xform_source(request, domain, app_id, module_id, form_id):
    app = get_app(domain, app_id)
    try:
        form = app.get_module(module_id).get_form(form_id)
    except IndexError:
        raise Http404()
    return _get_xform_source(request, app, form)
Exemple #22
0
def validate_module_for_build(request, domain, app_id, module_unique_id, ajax=True):
    app = get_app(domain, app_id)
    try:
        module = app.get_module_by_unique_id(module_unique_id)
    except ModuleNotFoundException:
        try:
            # temporary fallback
            module = app.get_module(module_unique_id)
        except ModuleNotFoundException:
            raise Http404()

    errors = module.validate_for_build()
    lang, langs = get_langs(request, app)

    response_html = render_to_string("app_manager/partials/build_errors.html", {
        'request': request,
        'app': app,
        'build_errors': errors,
        'not_actual_build': True,
        'domain': domain,
        'langs': langs,
        'lang': lang,
    })
    if ajax:
        return json_response({'error_html': response_html})
    return HttpResponse(response_html)
Exemple #23
0
def edit_commcare_profile(request, domain, app_id):
    try:
        settings = json.loads(request.body)
    except TypeError:
        return HttpResponseBadRequest(json.dumps({
            'reason': 'POST body must be of the form:'
            '{"properties": {...}, "features": {...}, "custom_properties": {...}}'
        }))
    app = get_app(domain, app_id)
    changed = defaultdict(dict)
    types = ["features", "properties"]

    if toggles.CUSTOM_PROPERTIES.enabled(domain):
        types.append("custom_properties")

    for settings_type in types:
        if settings_type == "custom_properties":
            app.profile[settings_type] = {}
        for name, value in settings.get(settings_type, {}).items():
            if settings_type not in app.profile:
                app.profile[settings_type] = {}
            app.profile[settings_type][name] = value
            changed[settings_type][name] = value
    response_json = {"status": "ok", "changed": changed}
    app.save(response_json)
    return json_response(response_json)
Exemple #24
0
def patch_xform(request, domain, app_id, unique_form_id):
    patch = request.POST['patch']
    sha1_checksum = request.POST['sha1']
    case_references = _get_case_references(request.POST)

    app = get_app(domain, app_id)
    form = app.get_form(unique_form_id)

    current_xml = form.source
    if hashlib.sha1(current_xml.encode('utf-8')).hexdigest() != sha1_checksum:
        return json_response({'status': 'conflict', 'xform': current_xml})

    dmp = diff_match_patch()
    xform, _ = dmp.patch_apply(dmp.patch_fromText(patch), current_xml)
    save_xform(app, form, xform)
    if "case_references" in request.POST or "references" in request.POST:
        form.case_references = case_references

    response_json = {
        'status': 'ok',
        'sha1': hashlib.sha1(form.source.encode('utf-8')).hexdigest()
    }
    app.save(response_json)
    notify_form_changed(domain, request.couch_user, app_id, unique_form_id)
    return json_response(response_json)
Exemple #25
0
    def post(self, request, domain, app_id, *args, **kwargs):
        profiles = json.loads(request.body).get('profiles')
        app = get_app(domain, app_id)
        build_profiles = {}
        if profiles:
            if app.is_remote_app() and len(profiles) > 1:
                # return bad request if they attempt to save more than one profile to a remote app
                return HttpResponse(status=400)
            for profile in profiles:
                id = profile.get('id')
                if not id:
                    id = uuid.uuid4().hex
                def practice_user_id():
                    if not app.enable_practice_users:
                        return ''
                    try:
                        practice_user_id = profile.get('practice_user_id')
                        if practice_user_id:
                            get_and_assert_practice_user_in_domain(practice_user_id, domain)
                        return practice_user_id
                    except PracticeUserException:
                        return HttpResponse(status=400)

                build_profiles[id] = BuildProfile(
                    langs=profile['langs'], name=profile['name'], practice_mobile_worker_id=practice_user_id())
        app.build_profiles = build_profiles
        app.save()
        return HttpResponse()
Exemple #26
0
def get_questions(domain, app_id, xmlns):
    if not app_id:
        raise QuestionListNotFound(
            _("This form is not associated with an app")
        )
    try:
        app = get_app(domain, app_id)
    except Http404:
        raise QuestionListNotFound(
            _("No app could be found")
        )
    if not isinstance(app, Application):
        raise QuestionListNotFound(
            _("Remote apps are not supported")
        )

    form = app.get_form_by_xmlns(xmlns)
    if not form:
        if xmlns == 'http://code.javarosa.org/devicereport':
            raise QuestionListNotFound(
                _("This is a Device Report")
            )
        else:
            raise QuestionListNotFound(
                _("We could not find the question list "
                  "associated with this form")
            )
    # Search for 'READABLE FORMS TEST' for more info
    # to bootstrap a test and have it print out your form xml
    # uncomment this line. Ghetto but it works.
    # print form.wrapped_xform().render()
    return get_questions_from_xform_node(form.wrapped_xform(), app.langs)
Exemple #27
0
def odk_install(request, domain, app_id, with_media=False):
    download_target_version = request.GET.get('download_target_version') == 'true'
    app = get_app(domain, app_id)
    qr_code_view = "odk_qr_code" if not with_media else "odk_media_qr_code"
    build_profile_id = request.GET.get('profile')
    profile_url = app.odk_profile_url if not with_media else app.odk_media_profile_url
    kwargs = []
    if build_profile_id is not None:
        kwargs.append('profile={profile}'.format(profile=build_profile_id))
    if download_target_version:
        kwargs.append('download_target_version=true')
    if kwargs:
        profile_url += '?' + '&'.join(kwargs)
    context = {
        "domain": domain,
        "app": app,
        "qr_code": reverse(qr_code_view,
                           args=[domain, app_id],
                           params={
                               'profile': build_profile_id,
                               'download_target_version': 'true' if download_target_version else 'false',
                           }),
        "profile_url": profile_url,
    }
    return render(request, "app_manager/odk_install.html", context)
Exemple #28
0
def release_build(request, domain, app_id, saved_app_id):
    is_released = request.POST.get('is_released') == 'true'
    if not is_released:
        if LatestEnabledBuildProfiles.objects.filter(build_id=saved_app_id).exists():
            return json_response({'error': _('Please disable any enabled profiles to un-release this build.')})
    ajax = request.POST.get('ajax') == 'true'
    saved_app = get_app(domain, saved_app_id)
    if saved_app.copy_of != app_id:
        raise Http404
    saved_app.is_released = is_released
    saved_app.is_auto_generated = False
    saved_app.save(increment_version=False)
    from corehq.apps.app_manager.signals import app_post_release
    app_post_release.send(Application, application=saved_app)

    if is_released:
        if saved_app.build_profiles and domain_has_privilege(domain, privileges.BUILD_PROFILES):
            create_build_files_for_all_app_profiles.delay(domain, saved_app_id)
        _track_build_for_app_preview(domain, request.couch_user, app_id, 'User starred a build')

    if ajax:
        return json_response({
            'is_released': is_released,
            'latest_released_version': get_latest_released_app_version(domain, app_id)
        })
    else:
        return HttpResponseRedirect(reverse('release_manager', args=[domain, app_id]))
Exemple #29
0
def task_creation(request, domain, app_id, module_id, form_id):
    '''
    This view is meant to be a run as a one-off script to support a specific
    app that Jeremy is writing. Running this script subsequent times on the
    same form will not have adverse affects.
    :param request:
    :param domain:
    :param app_id:
    :param module_id:
    :param form_id:
    :return:
    '''
    if request.method == 'POST':

        html_form = TaskCreationForm(request.POST)
        if html_form.is_valid():

            questions = html_form.cleaned_data['question_ids'].split()
            form = get_app(domain, app_id).modules[int(module_id)].forms[int(form_id)]
            # Make changes to the form
            message = _ucla_form_modifier(form, questions)
            return HttpResponse(message, content_type="text/plain")

        return HttpResponse("Soemthing was wrong with the form you submitted. Your CommCare form is unchanged.", content_type="text/plain")

    elif request.method == 'GET':
        html_form = TaskCreationForm()
        response = HttpResponse()
        response.write('<form action="'+reverse('ucla_task_creation', args=(domain, app_id, module_id, form_id))+'" method="post">')
        response.write(html_form.as_p())
        response.write('<p><input type="submit" value="Process Form"></p>')
        response.write("</form>")
        return response
    else:
        return HttpResponse("GET or POST only.", content_type="text/plain")
Exemple #30
0
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])
    name = request.POST.get('name')
    form = app.new_form(module_id, name, lang)

    blank_form = render_to_string("app_manager/blank_form.xml", context={
        'xmlns': str(uuid.uuid4()).upper(),
        'name': form.name[lang],
        'lang': lang,
    })
    form.source = blank_form

    if toggles.APP_MANAGER_V2.enabled(domain):
        case_action = request.POST.get('case_action', 'none')
        if case_action == 'update':
            form.requires = 'case'
            form.actions.update_case = UpdateCaseAction(
                condition=FormActionCondition(type='always'))

    app.save()
    # add form_id to locals()
    form_id = form.id
    response = back_to_main(request, domain, app_id=app_id, module_id=module_id,
                            form_id=form_id)
    return response
Exemple #31
0
def validate_form_for_build(request,
                            domain,
                            app_id,
                            unique_form_id,
                            ajax=True):
    app = get_app(domain, app_id)
    try:
        form = app.get_form(unique_form_id)
    except FormNotFoundException:
        # this can happen if you delete the form from another page
        raise Http404()
    errors = form.validate_for_build()
    lang, langs = get_langs(request, app)

    if ajax and "blank form" in [error.get('type') for error in errors]:
        response_html = (
            "" if toggles.APP_MANAGER_V2.enabled(domain) else render_to_string(
                'app_manager/v1/partials/create_form_prompt.html'))
    else:
        response_html = render_to_string(
            get_app_manager_template(
                domain,
                'app_manager/v1/partials/build_errors.html',
                'app_manager/v2/partials/build_errors.html',
            ), {
                'request': request,
                'app': app,
                'form': form,
                'build_errors': errors,
                'not_actual_build': True,
                'domain': domain,
                'langs': langs,
                'lang': lang
            })

    if ajax:
        return json_response({
            'error_html': response_html,
        })
    else:
        return HttpResponse(response_html)
Exemple #32
0
    def testPruneAutoGeneratedBuilds(self, mock):
        # Build #1, manually generated
        app = import_app(self._yesno_source, self.domain)
        for module in app.modules:
            module.get_or_create_unique_id()
        app.save()
        build1 = app.make_build()
        build1.save()
        self.assertFalse(build1.is_auto_generated)

        # Build #2, auto-generated
        app.save()
        autogenerate_build(app, "username")
        build_ids = get_build_ids(app.domain, app.id)
        self.assertEqual(len(build_ids), 2)
        self.assertEqual(build_ids[1], build1.id)
        build2 = get_app(app.domain, build_ids[0])
        self.assertTrue(build2.is_auto_generated)

        # First prune: delete nothing because the auto build is the most recent
        prune_auto_generated_builds(self.domain, app.id)
        self.assertEqual(len(get_build_ids(app.domain, app.id)), 2)

        # Build #3, manually generated
        app.save()
        build3 = app.make_build()
        build3.save()

        # Release the auto-generated build and prune again, should still delete nothing
        build2.is_released = True
        build2.save()
        prune_auto_generated_builds(self.domain, app.id)
        self.assertEqual(len(get_build_ids(app.domain, app.id)), 3)

        # Un-release the auto-generated build and prune again, which should delete it
        build2.is_released = False
        build2.save()
        prune_auto_generated_builds(self.domain, app.id)
        build_ids = get_build_ids(app.domain, app.id)
        self.assertEqual(len(build_ids), 2)
        self.assertNotIn(build2.id, build_ids)
Exemple #33
0
def release_build(request, domain, app_id, saved_app_id):
    is_released = request.POST.get('is_released') == 'true'
    if not is_released:
        if (LatestEnabledBuildProfiles.objects.filter(build_id=saved_app_id,
                                                      active=True).exists()
                or AppReleaseByLocation.objects.filter(build_id=saved_app_id,
                                                       active=True).exists()):
            return json_response({
                'error':
                _('Please disable any enabled profiles/location restriction '
                  'to un-release this build.')
            })
    ajax = request.POST.get('ajax') == 'true'
    saved_app = get_app(domain, saved_app_id)
    if saved_app.copy_of != app_id:
        raise Http404
    saved_app.is_released = is_released
    saved_app.last_released = datetime.datetime.utcnow(
    ) if is_released else None
    saved_app.is_auto_generated = False
    saved_app.save(increment_version=False)
    from corehq.apps.app_manager.signals import app_post_release
    app_post_release.send(Application, application=saved_app)

    if is_released:
        if saved_app.build_profiles and domain_has_privilege(
                domain, privileges.BUILD_PROFILES):
            create_build_files_for_all_app_profiles.delay(domain, saved_app_id)
        _track_build_for_app_preview(domain, request.couch_user, app_id,
                                     'User starred a build')

    if ajax:
        return json_response({
            'is_released':
            is_released,
            'latest_released_version':
            get_latest_released_app_version(domain, app_id)
        })
    else:
        return HttpResponseRedirect(
            reverse('release_manager', args=[domain, app_id]))
def get_releases_context(request, domain, app_id):
    app = get_app(domain, app_id)
    can_send_sms = domain_has_privilege(domain, privileges.OUTBOUND_SMS)
    build_profile_access = domain_has_privilege(domain, privileges.BUILD_PROFILES)
    prompt_settings_form = PromptUpdateSettingsForm.from_app(app, request_user=request.couch_user)

    context = {
        'release_manager': True,
        'can_send_sms': can_send_sms,
        'can_view_cloudcare': has_privilege(request, privileges.CLOUDCARE),
        'has_mobile_workers': get_doc_count_in_domain_by_class(domain, CommCareUser) > 0,
        'latest_released_version': get_latest_released_app_version(domain, app_id),
        'sms_contacts': (
            get_sms_autocomplete_context(request, domain)['sms_contacts']
            if can_send_sms else []
        ),
        'build_profile_access': build_profile_access,
        'application_profile_url': reverse(LanguageProfilesView.urlname, args=[domain, app_id]),
        'lastest_j2me_enabled_build': CommCareBuildConfig.latest_j2me_enabled_config().label,
        'latest_build_id': get_latest_build_id(domain, app_id),
        'prompt_settings_url': reverse(PromptSettingsUpdateView.urlname, args=[domain, app_id]),
        'prompt_settings_form': prompt_settings_form,
        'full_name': request.couch_user.full_name,
        'can_manage_releases': can_manage_releases(request.couch_user, request.domain, app_id)
    }
    if not app.is_remote_app():
        context.update({
            'enable_update_prompts': app.enable_update_prompts,
        })
        if len(app.modules) == 0:
            context.update({'intro_only': True})

        # Multimedia is not supported for remote applications at this time.
        try:
            multimedia_state = app.check_media_state()
            context.update({
                'multimedia_state': multimedia_state,
            })
        except ReportConfigurationNotFoundError:
            pass
    return context
Exemple #35
0
    def _get_cases_for_apps(self, apps_by_type, as_dict=True):
        used_case_types = set()
        case_types_by_app = collections.defaultdict(list)
        for app_type, apps in apps_by_type.items():
            for app_choice in apps:
                if not app_choice.id == self.UNKNOWN_SOURCE:
                    app = get_app(self.domain, app_choice.id)
                    case_types = []
                    if hasattr(app, 'modules'):
                        # Add regular case types
                        case_types = set([
                            module.case_type for module in app.modules
                            if module.case_type
                        ])

                        # Add user case if any module uses it
                        if any(
                                map(lambda module: module.uses_usercase(),
                                    app.modules)):
                            case_types.add(USERCASE_TYPE)

                        used_case_types = used_case_types.union(case_types)
                        case_types = map(
                            lambda c: RMIDataChoice(
                                id=c, text=c, data=app_choice.data),
                            case_types)
                        if as_dict:
                            case_types = map(lambda c: c._asdict(), case_types)
                    case_types_by_app[app_choice.id] = case_types

        all_case_types = CaseAccessors(self.domain).get_case_types()
        unknown_case_types = all_case_types.difference(used_case_types)
        unknown_case_types = map(
            lambda c: RMIDataChoice(id=c, text=c, data={
                'unknown': True,
            }), unknown_case_types)
        if as_dict:
            unknown_case_types = map(lambda c: c._asdict(), unknown_case_types)
        case_types_by_app[self.UNKNOWN_SOURCE] = unknown_case_types

        return case_types_by_app
Exemple #36
0
def copy_app(request, domain):
    app_id = request.POST.get('app')
    app = get_app(domain, app_id)
    form = CopyApplicationForm(
        domain,
        app,
        request.POST,
        export_zipped_apps_enabled=toggles.EXPORT_ZIPPED_APPS.enabled(
            request.user.username))
    if not form.is_valid():
        from corehq.apps.app_manager.views.view_generic import view_generic
        return view_generic(request, domain, app_id=app_id, copy_app_form=form)

    gzip = request.FILES.get('gzip')
    if gzip:
        with zipfile.ZipFile(gzip, 'r', zipfile.ZIP_DEFLATED) as z:
            source = z.read(z.filelist[0].filename)
        app_id_or_source = source
    else:
        app_id_or_source = app_id

    def _inner(request, link_domain, data, master_domain=domain):
        clear_app_cache(request, link_domain)
        if data['toggles']:
            for slug in data['toggles'].split(","):
                set_toggle(slug,
                           link_domain,
                           True,
                           namespace=toggles.NAMESPACE_DOMAIN)
        linked = data.get('linked')
        if linked:
            return _create_linked_app(request, app, link_domain, data['name'])
        else:
            return _copy_app_helper(request, master_domain, app_id_or_source,
                                    link_domain, data['name'], app_id)

    # having login_and_domain_required validates that the user
    # has access to the domain we're copying the app to
    return login_and_domain_required(_inner)(request,
                                             form.cleaned_data['domain'],
                                             form.cleaned_data)
Exemple #37
0
def rearrange(request, domain, app_id, key):
    """
    This function handles any request to switch two items in a list.
    Key tells us the list in question and must be one of
    'forms', 'modules', 'detail', or 'langs'. The two POST params
    'to' and 'from' give us the indicies of the items to be rearranged.

    """
    app = get_app(domain, app_id)
    ajax = json.loads(request.POST.get('ajax', 'false'))
    i, j = (int(x) for x in (request.POST['to'], request.POST['from']))
    resp = {}
    module_id = None

    try:
        if "forms" == key:
            to_module_id = int(request.POST['to_module_id'])
            from_module_id = int(request.POST['from_module_id'])
            try:
                app.rearrange_forms(to_module_id, from_module_id, i, j)
            except ConflictingCaseTypeError:
                messages.warning(request, CASE_TYPE_CONFLICT_MSG, extra_tags="html")
        elif "modules" == key:
            app.rearrange_modules(i, j)
    except IncompatibleFormTypeException:
        messages.error(request, _(
            'The form can not be moved into the desired module.'
        ))
        return back_to_main(request, domain, app_id=app_id, module_id=module_id)
    except (RearrangeError, ModuleNotFoundException):
        messages.error(request, _(
            'Oops. '
            'Looks like you got out of sync with us. '
            'The sidebar has been updated, so please try again.'
        ))
        return back_to_main(request, domain, app_id=app_id, module_id=module_id)
    app.save(resp)
    if ajax:
        return HttpResponse(json.dumps(resp))
    else:
        return back_to_main(request, domain, app_id=app_id, module_id=module_id)
Exemple #38
0
    def __init__(self, from_domain, app_id, *args, **kwargs):
        export_zipped_apps_enabled = kwargs.pop('export_zipped_apps_enabled',
                                                False)
        super(CopyApplicationForm, self).__init__(*args, **kwargs)
        fields = ['domain', 'name']
        if app_id:
            app = get_app(from_domain, app_id)
            if app:
                self.fields['name'].initial = app.name
        if export_zipped_apps_enabled:
            self.fields['gzip'] = forms.FileField(required=False)
            fields.append('gzip')

        self.helper = FormHelper()
        self.helper.label_class = 'col-sm-3 col-md-4 col-lg-2'
        self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6'
        self.helper.layout = Layout(
            Fieldset(_('Copy Application'), *fields), Hidden('app', app_id),
            hqcrispy.FormActions(
                StrictButton(_('Copy'), type='submit',
                             css_class='btn-primary')))
Exemple #39
0
def get_correct_xmlns(xform_instance):
    if xform_instance.build_id is None:
        return None
    build = get_app(xform_instance.domain, xform_instance.build_id)
    # TODO: What if the app has been deleted?

    previously_fixed_forms_in_build = get_previously_fixed_forms(build)
    if len(previously_fixed_forms_in_build) == 1:
        return previously_fixed_forms_in_build[0].xmlns
    elif len(previously_fixed_forms_in_build) == 0:
        if get_forms_without_xmlns(build):
            # We don't expect this to ever happen
            raise BuildHasFormsWithUndefinedXmlns()
        else:
            matching_forms = find_matching_forms_by_name(xform_instance, build)
            if len(matching_forms) == 1:
                return matching_forms[0].xmlns
            else:
                raise CantMatchAForm()
    else:
        raise MultiplePreviouslyFixedForms(xform_instance.build_id, xform_instance.app_id)
Exemple #40
0
def pull_missing_multimedia_for_app_and_notify(domain, app_id, email):
    app = get_app(domain, app_id)
    subject = _(
        "Update Status for linked app %s missing multimedia pull") % app.name
    try:
        pull_missing_multimedia_for_app(app)
    except MultimediaMissingError as e:
        message = str(e)
    except Exception:
        # Send an email but then crash the process
        # so we know what the error was
        send_html_email_async.delay(
            subject, email,
            _("Something went wrong while pulling multimedia for your linked app. "
              "Our team has been notified and will monitor the situation. "
              "Please try again, and if the problem persists report it as an issue."
              ))
        raise
    else:
        message = _("Multimedia was successfully updated for the linked app.")
    send_html_email_async.delay(subject, email, message)
Exemple #41
0
def copy_form(request, domain, app_id, module_id, form_id):
    app = get_app(domain, app_id)
    to_module_id = int(request.POST['to_module_id'])
    try:
        app.copy_form(int(module_id), int(form_id), to_module_id)
    except ConflictingCaseTypeError:
        messages.warning(request, CASE_TYPE_CONFLICT_MSG, extra_tags="html")
        app.save()
    except BlankXFormError:
        # don't save!
        messages.error(request, _('We could not copy this form, because it is blank.'
                              'In order to copy this form, please add some questions first.'))
    except IncompatibleFormTypeException:
        # don't save!
        messages.error(request, _('This form could not be copied because it '
                              'is not compatible with the selected module.'))
    else:
        app.save()

    return back_to_main(request, domain, app_id=app_id, module_id=module_id,
                        form_id=form_id)
Exemple #42
0
def upload_bulk_app_translations(request, domain, app_id):
    validate = request.POST.get('validate')
    app = get_app(domain, app_id)
    workbook, msgs = get_app_translation_workbook(request.file)
    if workbook:
        if validate:
            msgs = validate_bulk_app_translation_upload(
                app, workbook, request.user.email, request.file,
                request.POST.get('language'))
        else:
            msgs = process_bulk_app_translation_upload(app, workbook)
            app.save()
    for msg in msgs:
        # Add the messages to the request object.
        # msg[0] should be a function like django.contrib.messages.error .
        # msg[1] should be a string.
        msg[0](request, msg[1])

    # In v2, languages is the default tab on the settings page
    view_name = 'app_settings'
    return HttpResponseRedirect(reverse(view_name, args=[domain, app_id]))
Exemple #43
0
def odk_install(request, domain, app_id, with_media=False):
    app = get_app(domain, app_id)
    qr_code_view = "odk_qr_code" if not with_media else "odk_media_qr_code"
    build_profile_id = request.GET.get('profile')
    profile_url = app.odk_profile_display_url if not with_media else app.odk_media_profile_display_url
    if build_profile_id is not None:
        profile_url += '?profile={profile}'.format(profile=build_profile_id)
    context = {
        "domain": domain,
        "app": app,
        "qr_code": reverse(qr_code_view,
                           args=[domain, app_id],
                           params={'profile': build_profile_id}),
        "profile_url": profile_url,
    }
    template = get_app_manager_template(
        domain,
        "app_manager/v1/odk_install.html",
        "app_manager/v2/odk_install.html",
    )
    return render(request, template, context)
Exemple #44
0
def validate_module_for_build(request, domain, app_id, module_id, ajax=True):
    app = get_app(domain, app_id)
    try:
        module = app.get_module(module_id)
    except ModuleNotFoundException:
        raise Http404()
    errors = module.validate_for_build()
    lang, langs = get_langs(request, app)

    response_html = render_to_string(
        'app_manager/partials/build_errors.html', {
            'app': app,
            'build_errors': errors,
            'not_actual_build': True,
            'domain': domain,
            'langs': langs,
            'lang': lang
        })
    if ajax:
        return json_response({'error_html': response_html})
    return HttpResponse(response_html)
Exemple #45
0
def patch_xform(request, domain, app_id, form_unique_id):
    patch = request.POST['patch']
    sha1_checksum = request.POST['sha1']
    case_references = _get_case_references(request.POST)

    app = get_app(domain, app_id)
    form = app.get_form(form_unique_id)

    conflict = _get_xform_conflict_response(form, sha1_checksum)
    if conflict is not None:
        return conflict

    xml = apply_patch(patch, form.source)
    xml = save_xform(app, form, xml.encode('utf-8'))
    if "case_references" in request.POST or "references" in request.POST:
        form.case_references = case_references

    response_json = {'status': 'ok', 'sha1': hashlib.sha1(xml).hexdigest()}
    app.save(response_json)
    notify_form_changed(domain, request.couch_user, app_id, form_unique_id)
    return json_response(response_json)
Exemple #46
0
def drop_user_case(request, domain, app_id):
    app = get_app(domain, app_id)
    for module in app.get_modules():
        for form in module.get_forms():
            if form.form_type == 'module_form':
                if 'usercase_update' in form.actions and form.actions[
                        'usercase_update'].update:
                    form.actions['usercase_update'].update = {}
                if 'usercase_preload' in form.actions and form.actions[
                        'usercase_preload'].preload:
                    form.actions['usercase_preload'].preload = {}
            else:
                for action in list(form.actions.load_update_cases):
                    if action.auto_select and action.auto_select.mode == AUTO_SELECT_USERCASE:
                        form.actions.load_update_cases.remove(action)
    app.save()
    messages.success(
        request,
        _('You have successfully removed User Case properties from this application.'
          ))
    return back_to_main(request, domain, app_id=app_id)
def multimedia_list_download(request, domain, app_id):
    app = get_app(domain, app_id)
    include_audio = request.GET.get("audio", True)
    include_images = request.GET.get("images", True)
    strip_jr = request.GET.get("strip_jr", True)
    filelist = []
    for m in app.get_modules():
        for f in m.get_forms():
            validate_xform(domain, f.source)
            parsed = XForm(f.source)
            if include_images:
                filelist.extend(parsed.image_references)
            if include_audio:
                filelist.extend(parsed.audio_references)

    if strip_jr:
        filelist = [s.replace("jr://file/", "") for s in filelist if s]
    response = HttpResponse()
    set_file_download(response, 'list.txt')
    response.write("\n".join(sorted(set(filelist))))
    return response
Exemple #48
0
def task_creation(request, domain, app_id, module_id, form_id):
    '''
    This view is meant to be a run as a one-off script to support a specific
    app that Jeremy is writing. Running this script subsequent times on the
    same form will not have adverse affects.
    :param request:
    :param domain:
    :param app_id:
    :param module_id:
    :param form_id:
    :return:
    '''
    if request.method == 'POST':

        html_form = TaskCreationForm(request.POST)
        if html_form.is_valid():

            questions = html_form.cleaned_data['question_ids'].split()
            form = get_app(domain,
                           app_id).modules[int(module_id)].forms[int(form_id)]
            # Make changes to the form
            message = _ucla_form_modifier(form, questions)
            return HttpResponse(message, content_type="text/plain")

        return HttpResponse(
            "Soemthing was wrong with the form you submitted. Your CommCare form is unchanged.",
            content_type="text/plain")

    elif request.method == 'GET':
        html_form = TaskCreationForm()
        response = HttpResponse()
        response.write('<form action="' + reverse(
            'ucla_task_creation', args=(domain, app_id, module_id, form_id)) +
                       '" method="post">')
        response.write(html_form.as_p())
        response.write('<p><input type="submit" value="Process Form"></p>')
        response.write("</form>")
        return response
    else:
        return HttpResponse("GET or POST only.", content_type="text/plain")
Exemple #49
0
def get_releases_context(request, domain, app_id):
    app = get_app(domain, app_id)
    context = get_apps_base_context(request, domain, app)
    can_send_sms = domain_has_privilege(domain, privileges.OUTBOUND_SMS)
    build_profile_access = domain_has_privilege(domain,
                                                privileges.BUILD_PROFILES)

    context.update({
        'release_manager':
        True,
        'can_send_sms':
        can_send_sms,
        'has_mobile_workers':
        get_doc_count_in_domain_by_class(domain, CommCareUser) > 0,
        'sms_contacts': (get_sms_autocomplete_context(
            request, domain)['sms_contacts'] if can_send_sms else []),
        'build_profile_access':
        build_profile_access,
        'application_profile_url':
        reverse(LanguageProfilesView.urlname, args=[domain, app_id]),
        'lastest_j2me_enabled_build':
        CommCareBuildConfig.latest_j2me_enabled_config().label,
        'fetchLimit':
        request.GET.get('limit', DEFAULT_FETCH_LIMIT),
        'latest_build_id':
        get_latest_build_id(domain, app_id)
    })
    if not app.is_remote_app():
        if toggles.APP_MANAGER_V2.enabled(request.user.username) and len(
                app.modules) == 0:
            context.update({'intro_only': True})
        # Multimedia is not supported for remote applications at this time.
        try:
            multimedia_state = app.check_media_state()
            context.update({
                'multimedia_state': multimedia_state,
            })
        except ReportConfigurationNotFoundError:
            pass
    return context
Exemple #50
0
def upload_bulk_ui_translations(request, domain, app_id):
    def _html_message(header_text, messages):
        message = header_text + "<br>"
        for prop in messages:
            message += "<li>%s</li>" % prop
        return message

    success = False
    try:
        app = get_app(domain, app_id)
        trans_dict, error_properties, warnings = process_ui_translation_upload(
            app, request.file)
        if error_properties:
            message = _html_message(
                _("Upload failed. We found problems with the following translations:"
                  ), error_properties)
            messages.error(request, message, extra_tags='html')
        else:
            # update translations only if there were no errors
            app.translations = dict(trans_dict)
            app.save()
            success = True

        if warnings:
            message = _html_message(
                _("Upload succeeded, but we found following issues for some properties"
                  ), warnings)
            messages.warning(request, message, extra_tags='html')

    except Exception:
        notify_exception(request, 'Bulk Upload Translations Error')
        messages.error(
            request,
            _("Something went wrong! Update failed. We're looking into it"))

    if success:
        messages.success(request, _("UI Translations Updated!"))

    return HttpResponseRedirect(reverse('app_languages', args=[domain,
                                                               app_id]))
Exemple #51
0
def download_bulk_app_translations(request, domain, app_id):
    lang = request.GET.get('lang')
    skip_blacklisted = request.GET.get('skipbl', 'false') == 'true'
    app = get_app(domain, app_id)
    single_sheet = request.GET.get('format') == "single"
    headers = get_bulk_app_sheet_headers(app, single_sheet=single_sheet,
                                         lang=lang, eligible_for_transifex_only=skip_blacklisted)
    if single_sheet:
        sheets = get_bulk_app_single_sheet_by_name(app, lang, skip_blacklisted)
    else:
        sheets = get_bulk_app_sheets_by_name(app, lang=lang, eligible_for_transifex_only=skip_blacklisted)

    temp = io.BytesIO()
    data = [(k, v) for k, v in sheets.items()]
    export_raw(headers, data, temp)
    filename = '{app_name} v.{app_version} - App Translations{lang}{transifex_only}'.format(
        app_name=app.name,
        app_version=app.version,
        lang=' ' + lang if lang else '',
        transifex_only=' (Transifex only)' if skip_blacklisted else '',
    )
    return export_response(temp, Format.XLS_2007, filename)
Exemple #52
0
def copy_form(request, domain, app_id, form_unique_id):
    app = get_app(domain, app_id)
    form = app.get_form(form_unique_id)
    module = form.get_module()
    to_module_id = int(request.POST['to_module_id'])
    to_module = app.get_module(to_module_id)
    new_form = None
    try:
        new_form = app.copy_form(module.id, form.id, to_module.id)
        if module['case_type'] != to_module['case_type']:
            messages.warning(request, CASE_TYPE_CONFLICT_MSG, extra_tags="html")
        app.save()
    except IncompatibleFormTypeException:
        # don't save!
        messages.error(request, _('This form could not be copied because it '
                                  'is not compatible with the selected module.'))
    else:
        app.save()

    if new_form:
        return back_to_main(request, domain, app_id=app_id, form_unique_id=new_form.unique_id)
    return HttpResponseRedirect(reverse('view_form', args=(domain, app._id, form.unique_id)))
Exemple #53
0
def multimedia_ajax(request, domain, app_id):
    app = get_app(domain, app_id)
    if app.get_doc_type() == 'Application':
        try:
            multimedia_state = app.check_media_state()
        except ReportConfigurationNotFoundError:
            return JsonResponse(
                {
                    "message":
                    _("One of the Report menus is misconfigured, please try again after they are fixed"
                      )
                },
                status=500)
        context = {
            'multimedia_state': multimedia_state,
            'domain': domain,
            'app': app,
        }
        return render(request, "app_manager/partials/multimedia_ajax.html",
                      context)
    else:
        raise Http404()
Exemple #54
0
def get_form_datums(request, domain, app_id):
    from corehq.apps.app_manager.suite_xml.sections.entries import EntriesHelper
    form_id = request.GET.get('form_id')
    app = get_app(domain, app_id)
    form = app.get_form(form_id)

    def make_datum(datum):
        return {'name': datum.datum.id, 'case_type': datum.case_type}

    helper = EntriesHelper(app)
    datums = []
    root_module = form.get_module().root_module
    if root_module:
        datums.extend([
            make_datum(datum) for datum in helper.get_datums_meta_for_form_generic(root_module.get_form(0))
            if datum.requires_selection
        ])
    datums.extend([
        make_datum(datum) for datum in helper.get_datums_meta_for_form_generic(form)
        if datum.requires_selection
    ])
    return json_response(datums)
Exemple #55
0
def validate_form_for_build(request,
                            domain,
                            app_id,
                            form_unique_id,
                            ajax=True):
    app = get_app(domain, app_id)
    try:
        form = app.get_form(form_unique_id)
    except FormNotFoundException:
        # this can happen if you delete the form from another page
        raise Http404()
    errors = form.validate_for_build()
    lang, langs = get_langs(request, app)

    if ajax and "blank form" in [error.get('type') for error in errors
                                 ] and not form.form_type == "shadow_form":
        response_html = ""
    else:
        if form.form_type == "shadow_form":
            # Don't display the blank form error if its a shadow form
            errors = [e for e in errors if e['type'] != "blank form"]
        response_html = render_to_string(
            "app_manager/partials/build_errors.html", {
                'request': request,
                'app': app,
                'form': form,
                'build_errors': errors,
                'not_actual_build': True,
                'domain': domain,
                'langs': langs,
                'lang': lang
            })

    if ajax:
        return json_response({
            'error_html': response_html,
        })
    else:
        return HttpResponse(response_html)
Exemple #56
0
def _get_latest_enabled_build(domain, username, app_id, profile_id,
                              location_flag_enabled):
    """
    :return: enabled build for the app for a location or profile on basis of feature flag enabled with
    location flag taking precedence
    """
    latest_enabled_build = None
    if location_flag_enabled:
        user = CommCareUser.get_by_username(
            normalize_username(username, domain))
        user_location_id = user.location_id
        if user_location_id:
            parent_app_id = get_app(domain, app_id).copy_of
            latest_enabled_build = get_latest_app_release_by_location(
                domain, user_location_id, parent_app_id)
    if not latest_enabled_build:
        # Fall back to the old logic to support migration
        # ToDo: Remove this block once migration is complete
        if profile_id and toggles.RELEASE_BUILDS_PER_PROFILE.enabled(domain):
            latest_enabled_build = get_latest_enabled_build_for_profile(
                domain, profile_id)
    return latest_enabled_build
Exemple #57
0
def get_apps_modules_by_id(domain):
    """
    Return a dictionary of {
        <app id>: {
            'name': <app name>,
            'modules': {
                <module id>: {'name': <module name>}
            }
        }
    }
    """
    apps = {}
    for app_id in get_app_ids_in_domain(domain):
        app = get_app(domain, app_id)
        modules = {}
        for module in app.get_modules():
            modules[module.unique_id] = {'name': module.default_name(app)}
        apps[app_id] = {
            'name': app.name,
            'modules': modules
        }
    return apps
Exemple #58
0
def edit_report_module(request, domain, app_id, module_id):
    """
    Overwrite module case details. Only overwrites components that have been
    provided in the request. Components are short, long, filter, parent_select,
    and sort_elements.
    """
    params = json_request(request.POST)
    app = get_app(domain, app_id)
    module = app.get_module(module_id)
    assert isinstance(module, ReportModule)
    module.name = params['name']

    try:
        module.report_configs = [ReportAppConfig.wrap(spec) for spec in params['reports']]
    except Exception:
        notify_exception(
            request,
            message="Something went wrong while editing report modules",
            details={'domain': domain, 'app_id': app_id, }
        )
        return HttpResponseBadRequest(_("There was a problem processing your request."))

    if (feature_previews.MODULE_FILTER.enabled(domain) and
            app.enable_module_filtering):
        module['module_filter'] = request.POST.get('module_filter')
    module.media_image.update(params['multimedia']['mediaImage'])
    module.media_audio.update(params['multimedia']['mediaAudio'])

    try:
        app.save()
    except Exception:
        notify_exception(
            request,
            message="Something went wrong while saving app {} while editing report modules".format(app_id),
            details={'domain': domain, 'app_id': app_id, }
        )
        return HttpResponseBadRequest(_("There was a problem processing your request."))

    return json_response('success')
Exemple #59
0
def choose_media(request, domain, app_id):
    # TODO: Add error handling
    app = get_app(domain, app_id)
    media_type = request.POST['media_type']
    media_id = request.POST['id']
    if media_type == 'Image':
        file = CommCareImage.get(media_id)
    elif media_type == 'Audio':
        file = CommCareImage.get(media_id)
    else:
        raise Http404()

    if file is None or not file.is_shared:
        return HttpResponse(json.dumps({'match_found': False}))

    file.add_domain(domain)
    app.create_mapping(file, request.POST['path'])
    if media_type == 'Image':
        return HttpResponse(
            json.dumps({
                'match_found': True,
                'image': {
                    'm_id': file._id,
                    'url': file.url()
                },
                'file': True
            }))
    elif media_type == 'Audio':
        return HttpResponse(
            json.dumps({
                'match_found': True,
                'audio': {
                    'm_id': file._id,
                    'url': file.url()
                }
            }))
    else:
        raise Http404()
Exemple #60
0
    def handle(self, **options):
        logger.setLevel('DEBUG')
        app_ids_by_domain = defaultdict(set)
        self.force = options["force"]
        self.dry = "DRY RUN " if options["dry_run"] else ""
        self.fail_hard = options["fail_hard"]
        self.fup_caseref = options["fix_user_props_caseref"]
        self.fix_user_props = options["fix_user_properties"] or self.fup_caseref
        self.migrate_usercase = options["usercase"]
        for ident in options["app_id_or_domain"]:
            if not (self.migrate_usercase or self.fix_user_props):
                try:
                    app = Application.get(ident)
                    app_ids_by_domain[app.domain].add(ident)
                    continue
                except ResourceNotFound:
                    pass
            app_ids_by_domain[ident].update(get_app_ids_in_domain(ident))

        for domain, app_ids in sorted(app_ids_by_domain.items()):
            logger.info('migrating %s: %s apps', domain, len(app_ids))
            for app_id in app_ids:
                try:
                    app = get_app(domain, app_id)
                    if app.doc_type == "Application":
                        if self.fix_user_props:
                            self.fix_user_properties(app)
                        else:
                            self.migrate_app(app)
                    else:
                        logger.info("Skipping %s/%s because it is a %s",
                                    domain, app_id, app.doc_type)
                except Exception as e:
                    logger.exception("skipping app %s/%s", domain, app_id)
                    if self.fail_hard:
                        raise e

        logger.info('done with migrate_app_to_cmitfb %s', self.dry)