def show(slug, request, app, module=None, form=None):
    if slug not in _ADD_ONS:
        raise AddOnNotFoundException(slug)
    add_on = _ADD_ONS[slug]

    # Do not show if there's a required privilege missing
    if not add_on.has_privilege(request):
        return False

    # Show if flag to enable all toggles is on
    if toggles.ENABLE_ALL_ADD_ONS.enabled_for_request(request):
        return True

    if _grandfathered(slug, app):
        return True

    # Show if add-on has been enabled for app
    show = slug in app.add_ons and app.add_ons[slug]

    # Show if add-on is also a feature preview this domain has on
    # (that has not been turned off for this app specifically)
    if slug not in app.add_ons:
        previews = feature_previews.previews_dict(app.domain)
        if slug in previews:
            show = show or previews[slug]

    # Show if add-on is being used by the current form/module
    if form:
        show = show or add_on.used_in_form(form)
    elif module:
        show = show or add_on.used_in_module(module)

    return show
Beispiel #2
0
def show(slug, request, app, module=None, form=None):
    if slug not in _ADD_ONS:
        raise AddOnNotFoundException(slug)
    add_on = _ADD_ONS[slug]

    # Do not show if there's a required privilege missing
    if not add_on.has_privilege(request):
        return False

    # Show if flag to enable all toggles is on
    if toggles.ENABLE_ALL_ADD_ONS.enabled_for_request(request):
        return True

    if _grandfathered(slug, app):
        return True

    # Show if add-on has been enabled for app
    show = slug in app.add_ons and app.add_ons[slug]

    # Show if add-on is also a feature preview this domain has on
    # (that has not been turned off for this app specifically)
    if slug not in app.add_ons:
        previews = feature_previews.previews_dict(app.domain)
        if slug in previews:
            show = show or previews[slug]

    # Show if add-on is being used by the current form/module
    if form:
        show = show or add_on.used_in_form(form)
    elif module:
        show = show or add_on.used_in_module(module)

    return show
Beispiel #3
0
def bug_report(req):
    report = dict([(key, req.POST.get(key, '')) for key in (
        'subject',
        'username',
        'domain',
        'url',
        'message',
        'app_id',
        'cc',
        'email',
        '500traceback',
        'sentry_id',
    )])

    report['user_agent'] = req.META['HTTP_USER_AGENT']
    report['datetime'] = datetime.utcnow()

    try:
        couch_user = req.couch_user
        full_name = couch_user.full_name
        if couch_user.is_commcare_user():
            email = report['email']
        else:
            email = couch_user.get_email()
    except Exception:
        full_name = None
        email = report['email']
    report['full_name'] = full_name
    report['email'] = email or report['username']

    if report['domain']:
        domain = report['domain']
    elif len(couch_user.domains) == 1:
        # This isn't a domain page, but the user has only one domain, so let's use that
        domain = couch_user.domains[0]
    else:
        domain = "<no domain>"

    message = (u"username: {username}\n"
               u"full name: {full_name}\n"
               u"domain: {domain}\n"
               u"url: {url}\n"
               u"datetime: {datetime}\n"
               u"User Agent: {user_agent}\n").format(**report)

    domain_object = Domain.get_by_name(domain) if report['domain'] else None
    if domain_object:
        current_project_description = domain_object.project_description if domain_object else None
        new_project_description = req.POST.get('project_description')
        if (domain_object and req.couch_user.is_domain_admin(domain=domain)
                and new_project_description
                and current_project_description != new_project_description):

            domain_object.project_description = new_project_description
            domain_object.save()

        matching_subscriptions = Subscription.objects.filter(
            is_active=True,
            subscriber__domain=domain,
        )
        if len(matching_subscriptions) >= 1:
            software_plan = matching_subscriptions[0].plan_version
        else:
            software_plan = u'domain has no active subscription'

        message += ((
            u"software plan: {software_plan}\n"
            u"Is self start: {self_started}\n"
            u"Feature Flags: {feature_flags}\n"
            u"Feature Previews: {feature_previews}\n"
            u"Is scale backend: {scale_backend}\n"
            u"Has Support Hand-off Info: {has_handoff_info}\n"
            u"Internal Project Information: {internal_info_link}\n"
            u"Project description: {project_description}\n"
            u"Sentry Error: {sentry_error}\n").format(
                software_plan=software_plan,
                self_started=domain_object.internal.self_started,
                feature_flags=toggles.toggles_dict(username=report['username'],
                                                   domain=domain).keys(),
                feature_previews=feature_previews.previews_dict(domain).keys(),
                scale_backend=should_use_sql_backend(domain),
                has_handoff_info=bool(domain_object.internal.partner_contact),
                internal_info_link=reverse('domain_internal_settings',
                                           args=[domain],
                                           absolute=True),
                project_description=domain_object.project_description,
                sentry_error='{}{}'.format(
                    getattr(settings, 'SENTRY_QUERY_URL'),
                    report['sentry_id'])))

    subject = u'{subject} ({domain})'.format(subject=report['subject'],
                                             domain=domain)
    cc = report['cc'].strip().split(",")
    cc = filter(None, cc)

    if full_name and not any([c in full_name for c in '<>"']):
        reply_to = u'"{full_name}" <{email}>'.format(**report)
    else:
        reply_to = report['email']

    # if the person looks like a commcare user, fogbugz can't reply
    # to their email, so just use the default
    if settings.HQ_ACCOUNT_ROOT in reply_to:
        reply_to = settings.SERVER_EMAIL

    message += u"Message:\n\n{message}\n".format(message=report['message'])
    if req.POST.get('five-hundred-report'):
        extra_message = ("This messge was reported from a 500 error page! "
                         "Please fix this ASAP (as if you wouldn't anyway)...")
        traceback_info = cache.cache.get(report['500traceback'])
        cache.cache.delete(report['500traceback'])
        traceback_info = "Traceback of this 500: \n%s" % traceback_info
        message = "%s \n\n %s \n\n %s" % (message, extra_message,
                                          traceback_info)

    email = EmailMessage(subject=subject,
                         body=message,
                         to=settings.BUG_REPORT_RECIPIENTS,
                         headers={'Reply-To': reply_to},
                         cc=cc)

    uploaded_file = req.FILES.get('report_issue')
    if uploaded_file:
        filename = uploaded_file.name
        content = uploaded_file.read()
        email.attach(filename=filename, content=content)

    # only fake the from email if it's an @dimagi.com account
    if re.search('@dimagi\.com$', report['username']):
        email.from_email = report['username']
    else:
        email.from_email = settings.CCHQ_BUG_REPORT_EMAIL

    email.send(fail_silently=False)

    if req.POST.get('five-hundred-report'):
        messages.success(
            req,
            "Your CommCare HQ Issue Report has been sent. We are working quickly to resolve this problem."
        )
        return HttpResponseRedirect(reverse('homepage'))

    return HttpResponse()
Beispiel #4
0
def form_designer(request, domain, app_id, module_id=None, form_id=None):
    def _form_uses_case(module, form):
        return module and module.case_type and form.requires_case()

    def _form_is_basic(form):
        return form.doc_type == 'Form'

    def _form_too_large(app, form):
        # form less than 0.1MB, anything larger starts to have
        # performance issues with fullstory
        return app.blobs['{}.xml'.format(
            form.unique_id)]['content_length'] > 102400

    meta = get_meta(request)
    track_entered_form_builder_on_hubspot.delay(request.couch_user,
                                                request.COOKIES, meta)

    app = get_app(domain, app_id)
    module = None

    try:
        module = app.get_module(module_id)
    except ModuleNotFoundException:
        return bail(request, domain, app_id, not_found="module")
    try:
        form = module.get_form(form_id)
    except IndexError:
        return bail(request, domain, app_id, not_found="form")

    if form.no_vellum:
        messages.warning(
            request,
            _("You tried to edit this form in the Form Builder. "
              "However, your administrator has locked this form against editing "
              "in the form builder, so we have redirected you to "
              "the form's front page instead."))
        return back_to_main(request,
                            domain,
                            app_id=app_id,
                            unique_form_id=form.unique_id)

    include_fullstory = False
    vellum_plugins = ["modeliteration", "itemset", "atwho"]
    if (toggles.COMMTRACK.enabled(domain)):
        vellum_plugins.append("commtrack")
    if toggles.VELLUM_SAVE_TO_CASE.enabled(domain):
        vellum_plugins.append("saveToCase")
    if (_form_uses_case(module, form) and _form_is_basic(form)):
        vellum_plugins.append("databrowser")

    vellum_features = toggles.toggles_dict(username=request.user.username,
                                           domain=domain)
    vellum_features.update(feature_previews.previews_dict(domain))
    include_fullstory = not _form_too_large(app, form)
    vellum_features.update({
        'group_in_field_list':
        app.enable_group_in_field_list,
        'image_resize':
        app.enable_image_resize,
        'markdown_in_groups':
        app.enable_markdown_in_groups,
        'lookup_tables':
        domain_has_privilege(domain, privileges.LOOKUP_TABLES),
        'templated_intents':
        domain_has_privilege(domain, privileges.TEMPLATED_INTENTS),
        'custom_intents':
        domain_has_privilege(domain, privileges.CUSTOM_INTENTS),
        'rich_text':
        True,
    })

    has_schedule = (getattr(module, 'has_schedule', False)
                    and getattr(form, 'schedule', False)
                    and form.schedule.enabled)
    scheduler_data_nodes = []
    if has_schedule:
        scheduler_data_nodes = [
            SCHEDULE_CURRENT_VISIT_NUMBER,
            SCHEDULE_NEXT_DUE,
            SCHEDULE_UNSCHEDULED_VISIT,
            SCHEDULE_GLOBAL_NEXT_VISIT_DATE,
        ]
        scheduler_data_nodes.extend([
            u"next_{}".format(f.schedule_form_id)
            for f in form.get_phase().get_forms()
            if getattr(f, 'schedule', False) and f.schedule.enabled
        ])

    if tours.VELLUM_CASE_MANAGEMENT.is_enabled(
            request.user) and form.requires_case():
        request.guided_tour = tours.VELLUM_CASE_MANAGEMENT.get_tour_data()

    context = get_apps_base_context(request, domain, app)
    context.update(locals())
    context.update({
        'vellum_debug':
        settings.VELLUM_DEBUG,
        'nav_form':
        form,
        'formdesigner':
        True,
        'include_fullstory':
        include_fullstory,
        'notifications_enabled':
        request.user.is_superuser,
        'notify_facility':
        get_facility_for_form(domain, app_id, form.unique_id),
    })
    notify_form_opened(domain, request.couch_user, app_id, form.unique_id)

    domain_obj = Domain.get_by_name(domain)
    context.update({
        'show_live_preview':
        should_show_preview_app(
            request,
            app,
            request.couch_user.username,
        ),
        'can_preview_form':
        request.couch_user.has_permission(domain, 'edit_data'),
    })

    core = {
        'dataSourcesEndpoint':
        reverse('get_form_data_schema',
                kwargs={
                    'domain': domain,
                    'form_unique_id': form.get_unique_id()
                }),
        'dataSource': [
            # DEPRECATED. Use dataSourcesEndpoint
            {
                'key': 'fixture',
                'name': 'Fixtures',
                'endpoint': reverse('fixture_metadata',
                                    kwargs={'domain': domain}),
            },
        ],
        'form':
        form.source,
        'formId':
        form.get_unique_id(),
        'formName':
        trans(form.name, app.langs),
        'saveType':
        'patch',
        'saveUrl':
        reverse('edit_form_attr',
                args=[domain, app.id,
                      form.get_unique_id(), 'xform']),
        'patchUrl':
        reverse('patch_xform', args=[domain, app.id,
                                     form.get_unique_id()]),
        'allowedDataNodeReferences': [
            "meta/deviceID",
            "meta/instanceID",
            "meta/username",
            "meta/userID",
            "meta/timeStart",
            "meta/timeEnd",
            "meta/location",
        ] + scheduler_data_nodes,
        'activityUrl':
        reverse('ping'),
        'sessionid':
        request.COOKIES.get('sessionid'),
        'externalLinks': {
            'changeSubscription':
            reverse("domain_subscription_view", kwargs={'domain': domain}),
        },
        'invalidCaseProperties': ['name'],
    }

    if toggles.APP_MANAGER_V2.enabled(request.user.username):
        if form.get_action_type() == 'open':
            core.update({
                'defaultHelpTextTemplateId': '#fd-hq-helptext-registration',
                'formIconClass': 'fcc fcc-app-createform',
            })
        elif form.get_action_type() == 'close':
            core.update({
                'defaultHelpTextTemplateId': '#fd-hq-helptext-close',
                'formIconClass': 'fcc fcc-app-completeform',
            })
        elif form.get_action_type() == 'update':
            core.update({
                'defaultHelpTextTemplateId': '#fd-hq-helptext-followup',
                'formIconClass': 'fcc fcc-app-updateform',
            })
        else:
            core.update({
                'defaultHelpTextTemplateId': '#fd-hq-helptext-survey',
                'formIconClass': 'fa fa-file-o',
            })

    vellum_options = {
        'core': core,
        'plugins': vellum_plugins,
        'features': vellum_features,
        'intents': {
            'templates': next(app_callout_templates),
        },
        'javaRosa': {
            'langs': app.langs,
            'displayLanguage': context['lang'],
        },
        'uploader': {
            'uploadUrls': {
                'image': reverse("hqmedia_uploader_image",
                                 args=[domain, app.id]),
                'audio': reverse("hqmedia_uploader_audio",
                                 args=[domain, app.id]),
                'video': reverse("hqmedia_uploader_video",
                                 args=[domain, app.id]),
                'text': reverse("hqmedia_uploader_text", args=[domain,
                                                               app.id]),
            },
            'objectMap': app.get_object_map(),
            'sessionid': request.COOKIES.get('sessionid'),
        },
    }
    context.update({
        'vellum_options': vellum_options,
        'CKEDITOR_BASEPATH': "app_manager/js/vellum/lib/ckeditor/",
    })

    if not settings.VELLUM_DEBUG:
        context.update({'requirejs_url': "app_manager/js/vellum/src"})
    elif settings.VELLUM_DEBUG == "dev-min":
        context.update({'requirejs_url': "formdesigner/_build/src"})
    else:
        context.update({'requirejs_url': "formdesigner/src"})
    context.update({
        'requirejs_args':
        'version={}{}'.format(
            cachebuster("app_manager/js/vellum/src/main-components.js"),
            cachebuster("app_manager/js/vellum/src/local-deps.js")),
    })

    template = get_app_manager_template(
        request.user,
        'app_manager/v1/form_designer.html',
        'app_manager/v2/form_designer.html',
    )

    response = render(request, template, context)
    return response
Beispiel #5
0
def bug_report(req):
    report = dict([(key, req.POST.get(key, '')) for key in (
        'subject',
        'username',
        'domain',
        'url',
        'message',
        'app_id',
        'cc',
        'email',
        '500traceback',
    )])

    domain_object = Domain.get_by_name(report['domain'])
    current_project_description = domain_object.project_description
    new_project_description = req.POST.get('project_description')
    if (req.couch_user.is_domain_admin(domain=report['domain'])
            and new_project_description
            and current_project_description != new_project_description):

        domain_object.project_description = new_project_description
        domain_object.save()

    report['user_agent'] = req.META['HTTP_USER_AGENT']
    report['datetime'] = datetime.utcnow()
    report['feature_flags'] = toggles.toggles_dict(
        username=report['username'], domain=report['domain']).keys()
    report['feature_previews'] = feature_previews.previews_dict(
        report['domain']).keys()
    report['scale_backend'] = should_use_sql_backend(
        report['domain']) if report['domain'] else False
    report['project_description'] = domain_object.project_description

    try:
        couch_user = req.couch_user
        full_name = couch_user.full_name
        if couch_user.is_commcare_user():
            email = report['email']
        else:
            email = couch_user.get_email()
    except Exception:
        full_name = None
        email = report['email']
    report['full_name'] = full_name
    report['email'] = email or report['username']

    matching_subscriptions = Subscription.objects.filter(
        is_active=True,
        subscriber__domain=report['domain'],
    )

    if len(matching_subscriptions) >= 1:
        report['software_plan'] = matching_subscriptions[0].plan_version
    else:
        report['software_plan'] = u'domain has no active subscription'

    subject = u'{subject} ({domain})'.format(**report)
    message = (u"username: {username}\n"
               u"full name: {full_name}\n"
               u"domain: {domain}\n"
               u"software plan: {software_plan}\n"
               u"url: {url}\n"
               u"datetime: {datetime}\n"
               u"User Agent: {user_agent}\n"
               u"Feature Flags: {feature_flags}\n"
               u"Feature Previews: {feature_previews}\n"
               u"Is scale backend: {scale_backend}\n"
               u"Project description: {project_description}\n"
               u"Message:\n\n"
               u"{message}\n").format(**report)
    cc = report['cc'].strip().split(",")
    cc = filter(None, cc)

    if full_name and not any([c in full_name for c in '<>"']):
        reply_to = u'"{full_name}" <{email}>'.format(**report)
    else:
        reply_to = report['email']

    # if the person looks like a commcare user, fogbugz can't reply
    # to their email, so just use the default
    if settings.HQ_ACCOUNT_ROOT in reply_to:
        reply_to = settings.SERVER_EMAIL

    if req.POST.get('five-hundred-report'):
        extra_message = ("This messge was reported from a 500 error page! "
                         "Please fix this ASAP (as if you wouldn't anyway)...")
        traceback_info = cache.cache.get(report['500traceback'])
        cache.cache.delete(report['500traceback'])
        traceback_info = "Traceback of this 500: \n%s" % traceback_info
        message = "%s \n\n %s \n\n %s" % (message, extra_message,
                                          traceback_info)

    email = EmailMessage(subject=subject,
                         body=message,
                         to=settings.BUG_REPORT_RECIPIENTS,
                         headers={'Reply-To': reply_to},
                         cc=cc)

    uploaded_file = req.FILES.get('report_issue')
    if uploaded_file:
        filename = uploaded_file.name
        content = uploaded_file.read()
        email.attach(filename=filename, content=content)

    # only fake the from email if it's an @dimagi.com account
    if re.search('@dimagi\.com$', report['username']):
        email.from_email = report['username']
    else:
        email.from_email = settings.CCHQ_BUG_REPORT_EMAIL

    email.send(fail_silently=False)

    if req.POST.get('five-hundred-report'):
        messages.success(
            req,
            "Your CommCare HQ Issue Report has been sent. We are working quickly to resolve this problem."
        )
        return HttpResponseRedirect(reverse('homepage'))

    return HttpResponse()
Beispiel #6
0
def get_toggles_previews(domain):
    return {
        'toggles': list(toggles.toggles_dict(domain=domain)),
        'previews': list(feature_previews.previews_dict(domain=domain))
    }
Beispiel #7
0
def form_designer(request, domain, app_id, module_id=None, form_id=None):
    def _form_uses_case(module, form):
        return module and module.case_type and form.requires_case()

    def _form_is_basic(form):
        return form.doc_type == 'Form'

    def _form_too_large(app, form):
        # form less than 0.1MB, anything larger starts to have
        # performance issues with fullstory
        return app.blobs['{}.xml'.format(
            form.unique_id)]['content_length'] > 102400

    meta = get_meta(request)
    track_entered_form_builder_on_hubspot.delay(request.couch_user,
                                                request.COOKIES, meta)

    app = get_app(domain, app_id)
    module = None

    try:
        module = app.get_module(module_id)
    except ModuleNotFoundException:
        return bail(request, domain, app_id, not_found="module")
    try:
        form = module.get_form(form_id)
    except IndexError:
        return bail(request, domain, app_id, not_found="form")

    if form.no_vellum:
        messages.warning(
            request,
            _("You tried to edit this form in the Form Builder. "
              "However, your administrator has locked this form against editing "
              "in the form builder, so we have redirected you to "
              "the form's front page instead."))
        return back_to_main(request,
                            domain,
                            app_id=app_id,
                            unique_form_id=form.unique_id)

    include_fullstory = False
    vellum_plugins = ["modeliteration", "itemset", "atwho"]
    if (toggles.COMMTRACK.enabled(domain)):
        vellum_plugins.append("commtrack")
    if toggles.VELLUM_SAVE_TO_CASE.enabled(domain):
        vellum_plugins.append("saveToCase")
    if (_form_uses_case(module, form) and _form_is_basic(form)):
        vellum_plugins.append("databrowser")

    vellum_features = toggles.toggles_dict(username=request.user.username,
                                           domain=domain)
    vellum_features.update(feature_previews.previews_dict(domain))
    include_fullstory = not _form_too_large(app, form)
    vellum_features.update({
        'group_in_field_list':
        app.enable_group_in_field_list,
        'image_resize':
        app.enable_image_resize,
        'markdown_in_groups':
        app.enable_markdown_in_groups,
        'lookup_tables':
        domain_has_privilege(domain, privileges.LOOKUP_TABLES),
        'templated_intents':
        domain_has_privilege(domain, privileges.TEMPLATED_INTENTS),
        'custom_intents':
        domain_has_privilege(domain, privileges.CUSTOM_INTENTS),
        'rich_text':
        True,
    })

    has_schedule = (getattr(module, 'has_schedule', False)
                    and getattr(form, 'schedule', False)
                    and form.schedule.enabled)
    scheduler_data_nodes = []
    if has_schedule:
        scheduler_data_nodes = [
            SCHEDULE_CURRENT_VISIT_NUMBER,
            SCHEDULE_NEXT_DUE,
            SCHEDULE_UNSCHEDULED_VISIT,
            SCHEDULE_GLOBAL_NEXT_VISIT_DATE,
        ]
        scheduler_data_nodes.extend([
            u"next_{}".format(f.schedule_form_id)
            for f in form.get_phase().get_forms()
            if getattr(f, 'schedule', False) and f.schedule.enabled
        ])

    if tours.VELLUM_CASE_MANAGEMENT.is_enabled(
            request.user) and form.requires_case():
        request.guided_tour = tours.VELLUM_CASE_MANAGEMENT.get_tour_data()

    vellum_base = 'corehq/apps/app_manager/static/app_manager/js/'
    vellum_dir = 'vellum'
    if isdir(join(vellum_base, 'vellum_beta')):
        vellum_dir = 'vellum_beta'

    context = get_apps_base_context(request, domain, app)
    context.update(locals())
    context.update({
        'vellum_debug':
        settings.VELLUM_DEBUG,
        'nav_form':
        form,
        'vellum_style_path':
        'app_manager/js/{}/style.css'.format(vellum_dir),
        'vellum_ckeditor_path':
        'app_manager/js/{}/lib/ckeditor/'.format(vellum_dir),
        'vellum_js_path':
        'app_manager/js/{}/src'.format(vellum_dir),
        'vellum_main_components_path':
        'app_manager/js/{}/src/main-components.js'.format(vellum_dir),
        'vellum_local_deps_path':
        'app_manager/js/{}/src/local-deps.js'.format(vellum_dir),
        'formdesigner':
        True,
        'multimedia_object_map':
        app.get_object_map(),
        'sessionid':
        request.COOKIES.get('sessionid'),
        'features':
        vellum_features,
        'plugins':
        vellum_plugins,
        'app_callout_templates':
        next(app_callout_templates),
        'scheduler_data_nodes':
        scheduler_data_nodes,
        'include_fullstory':
        include_fullstory,
        'notifications_enabled':
        request.user.is_superuser,
        'notify_facility':
        get_facility_for_form(domain, app_id, form.unique_id),
    })
    notify_form_opened(domain, request.couch_user, app_id, form.unique_id)

    domain_obj = Domain.get_by_name(domain)
    context.update({
        'show_live_preview':
        should_show_preview_app(
            request,
            app,
            request.couch_user.username,
        ),
        'can_preview_form':
        request.couch_user.has_permission(domain, 'edit_data')
    })

    template = get_app_manager_template(
        domain,
        'app_manager/v1/form_designer.html',
        'app_manager/v2/form_designer.html',
    )

    response = render(request, template, context)
    return response
Beispiel #8
0
def bug_report(req):
    report = dict([(key, req.POST.get(key, '')) for key in (
        'subject',
        'username',
        'domain',
        'url',
        'message',
        'app_id',
        'cc',
        'email',
        '500traceback',
    )])

    report['user_agent'] = req.META['HTTP_USER_AGENT']
    report['datetime'] = datetime.utcnow()
    report['feature_flags'] = toggles.toggles_dict(username=report['username'],
                                                   domain=report['domain']).keys()
    report['feature_previews'] = feature_previews.previews_dict(report['domain']).keys()

    try:
        couch_user = CouchUser.get_by_username(report['username'])
        full_name = couch_user.full_name
        if couch_user.is_commcare_user():
            email = report['email']
        else:
            email = couch_user.get_email()
    except Exception:
        full_name = None
        email = report['email']
    report['full_name'] = full_name
    report['email'] = email or report['username']

    matching_subscriptions = Subscription.objects.filter(
        is_active=True,
        subscriber__domain=report['domain'],
    )

    if len(matching_subscriptions) >= 1:
        report['software_plan'] = matching_subscriptions[0].plan_version
    else:
        report['software_plan'] = u'domain has no active subscription'

    subject = u'{subject} ({domain})'.format(**report)
    message = (
        u"username: {username}\n"
        u"full name: {full_name}\n"
        u"domain: {domain}\n"
        u"software plan: {software_plan}\n"
        u"url: {url}\n"
        u"datetime: {datetime}\n"
        u"User Agent: {user_agent}\n"
        u"Feature Flags: {feature_flags}\n"
        u"Feature Previews: {feature_previews}\n"
        u"Message:\n\n"
        u"{message}\n"
        ).format(**report)
    cc = report['cc'].strip().split(",")
    cc = filter(None, cc)

    if full_name and not any([c in full_name for c in '<>"']):
        reply_to = u'"{full_name}" <{email}>'.format(**report)
    else:
        reply_to = report['email']

    # if the person looks like a commcare user, fogbugz can't reply
    # to their email, so just use the default
    if settings.HQ_ACCOUNT_ROOT in reply_to:
        reply_to = settings.SERVER_EMAIL

    if req.POST.get('five-hundred-report'):
        extra_message = ("This messge was reported from a 500 error page! "
                         "Please fix this ASAP (as if you wouldn't anyway)...")
        traceback_info = cache.cache.get(report['500traceback'])
        cache.cache.delete(report['500traceback'])
        traceback_info = "Traceback of this 500: \n%s" % traceback_info
        message = "%s \n\n %s \n\n %s" % (message, extra_message, traceback_info)

    email = EmailMessage(
        subject=subject,
        body=message,
        to=settings.BUG_REPORT_RECIPIENTS,
        headers={'Reply-To': reply_to},
        cc=cc
    )

    uploaded_file = req.FILES.get('report_issue')
    if uploaded_file:
        filename = uploaded_file.name
        content = uploaded_file.read()
        email.attach(filename=filename, content=content)

    # only fake the from email if it's an @dimagi.com account
    if re.search('@dimagi\.com$', report['username']):
        email.from_email = report['username']
    else:
        email.from_email = settings.CCHQ_BUG_REPORT_EMAIL

    email.send(fail_silently=False)

    if req.POST.get('five-hundred-report'):
        messages.success(req,
            "Your CommCare HQ Issue Report has been sent. We are working quickly to resolve this problem.")
        return HttpResponseRedirect(reverse('homepage'))

    return HttpResponse()
Beispiel #9
0
def form_designer(request, domain, app_id, module_id=None, form_id=None,
                  is_user_registration=False):
    meta = get_meta(request)
    track_entered_form_builder_on_hubspot.delay(request.couch_user, request.COOKIES, meta)

    app = get_app(domain, app_id)
    module = None

    if is_user_registration:
        form = app.get_user_registration()
    else:
        try:
            module = app.get_module(module_id)
        except ModuleNotFoundException:
            return bail(request, domain, app_id, not_found="module")
        try:
            form = module.get_form(form_id)
        except IndexError:
            return bail(request, domain, app_id, not_found="form")

    if form.no_vellum:
        messages.warning(request, _(
            "You tried to edit this form in the Form Builder. "
            "However, your administrator has locked this form against editing "
            "in the form builder, so we have redirected you to "
            "the form's front page instead."
        ))
        return back_to_main(request, domain, app_id=app_id,
                            unique_form_id=form.unique_id)

    vellum_plugins = ["modeliteration", "itemset", "atwho"]
    if (toggles.COMMTRACK.enabled(domain)):
        vellum_plugins.append("commtrack")
    if toggles.VELLUM_SAVE_TO_CASE.enabled(domain):
        vellum_plugins.append("saveToCase")
    if toggles.VELLUM_EXPERIMENTAL_UI.enabled(domain) and module and module.case_type:
        vellum_plugins.append("databrowser")

    vellum_features = toggles.toggles_dict(username=request.user.username,
                                           domain=domain)
    vellum_features.update(feature_previews.previews_dict(domain))
    vellum_features.update({
        'group_in_field_list': app.enable_group_in_field_list,
        'image_resize': app.enable_image_resize,
        'markdown_in_groups': app.enable_markdown_in_groups,
        'lookup_tables': domain_has_privilege(domain, privileges.LOOKUP_TABLES),
        'templated_intents': domain_has_privilege(domain, privileges.TEMPLATED_INTENTS),
        'custom_intents': domain_has_privilege(domain, privileges.CUSTOM_INTENTS),
    })

    has_schedule = (
        getattr(module, 'has_schedule', False) and
        getattr(form, 'schedule', False) and form.schedule.enabled
    )
    scheduler_data_nodes = []
    if has_schedule:
        scheduler_data_nodes = [
            SCHEDULE_CURRENT_VISIT_NUMBER,
            SCHEDULE_NEXT_DUE,
            SCHEDULE_UNSCHEDULED_VISIT,
            SCHEDULE_GLOBAL_NEXT_VISIT_DATE,
        ]
        scheduler_data_nodes.extend([
            u"next_{}".format(f.schedule_form_id)
            for f in form.get_phase().get_forms()
            if getattr(f, 'schedule', False) and f.schedule.enabled
        ])


    context = get_apps_base_context(request, domain, app)
    context.update(locals())
    context.update({
        'vellum_debug': settings.VELLUM_DEBUG,
        'nav_form': form if not is_user_registration else '',
        'formdesigner': True,
        'multimedia_object_map': app.get_object_map(),
        'sessionid': request.COOKIES.get('sessionid'),
        'features': vellum_features,
        'plugins': vellum_plugins,
        'app_callout_templates': next(app_callout_templates),
        'scheduler_data_nodes': scheduler_data_nodes,
        'no_header': True,
    })
    return render(request, 'app_manager/form_designer.html', context)
Beispiel #10
0
def form_designer(request, domain, app_id, module_id=None, form_id=None):

    def _form_uses_case(module, form):
        return module and module.case_type and form.requires_case()

    def _form_is_basic(form):
        return form.doc_type == 'Form'

    def _form_too_large(app, form):
        # form less than 0.1MB, anything larger starts to have
        # performance issues with fullstory
        return app.blobs['{}.xml'.format(form.unique_id)]['content_length'] > 102400

    meta = get_meta(request)
    track_entered_form_builder_on_hubspot.delay(request.couch_user, request.COOKIES, meta)

    app = get_app(domain, app_id)
    module = None

    try:
        module = app.get_module(module_id)
    except ModuleNotFoundException:
        return bail(request, domain, app_id, not_found="module")
    try:
        form = module.get_form(form_id)
    except IndexError:
        return bail(request, domain, app_id, not_found="form")

    if form.no_vellum:
        messages.warning(request, _(
            "You tried to edit this form in the Form Builder. "
            "However, your administrator has locked this form against editing "
            "in the form builder, so we have redirected you to "
            "the form's front page instead."
        ))
        return back_to_main(request, domain, app_id=app_id,
                            unique_form_id=form.unique_id)

    include_fullstory = False
    vellum_plugins = ["modeliteration", "itemset", "atwho"]
    if (toggles.COMMTRACK.enabled(domain)):
        vellum_plugins.append("commtrack")
    if toggles.VELLUM_SAVE_TO_CASE.enabled(domain):
        vellum_plugins.append("saveToCase")
    if (_form_uses_case(module, form) and _form_is_basic(form)):
        vellum_plugins.append("databrowser")

    vellum_features = toggles.toggles_dict(username=request.user.username,
                                           domain=domain)
    vellum_features.update(feature_previews.previews_dict(domain))
    include_fullstory = not _form_too_large(app, form)
    vellum_features.update({
        'group_in_field_list': app.enable_group_in_field_list,
        'image_resize': app.enable_image_resize,
        'markdown_in_groups': app.enable_markdown_in_groups,
        'lookup_tables': domain_has_privilege(domain, privileges.LOOKUP_TABLES),
        'templated_intents': domain_has_privilege(domain, privileges.TEMPLATED_INTENTS),
        'custom_intents': domain_has_privilege(domain, privileges.CUSTOM_INTENTS),
        'rich_text': True,
    })

    has_schedule = (
        getattr(module, 'has_schedule', False) and
        getattr(form, 'schedule', False) and form.schedule.enabled
    )
    scheduler_data_nodes = []
    if has_schedule:
        scheduler_data_nodes = [
            SCHEDULE_CURRENT_VISIT_NUMBER,
            SCHEDULE_NEXT_DUE,
            SCHEDULE_UNSCHEDULED_VISIT,
            SCHEDULE_GLOBAL_NEXT_VISIT_DATE,
        ]
        scheduler_data_nodes.extend([
            u"next_{}".format(f.schedule_form_id)
            for f in form.get_phase().get_forms()
            if getattr(f, 'schedule', False) and f.schedule.enabled
        ])

    if tours.VELLUM_CASE_MANAGEMENT.is_enabled(request.user) and form.requires_case():
        request.guided_tour = tours.VELLUM_CASE_MANAGEMENT.get_tour_data()

    context = get_apps_base_context(request, domain, app)
    context.update(locals())
    context.update({
        'vellum_debug': settings.VELLUM_DEBUG,
        'nav_form': form,
        'formdesigner': True,
        'multimedia_object_map': app.get_object_map(),
        'sessionid': request.COOKIES.get('sessionid'),
        'features': vellum_features,
        'plugins': vellum_plugins,
        'app_callout_templates': next(app_callout_templates),
        'scheduler_data_nodes': scheduler_data_nodes,
        'include_fullstory': include_fullstory,
        'notifications_enabled': request.user.is_superuser,
        'notify_facility': get_facility_for_form(domain, app_id, form.unique_id),
    })
    notify_form_opened(domain, request.couch_user, app_id, form.unique_id)

    live_preview_ab = ab_tests.ABTest(ab_tests.LIVE_PREVIEW, request)
    domain_obj = Domain.get_by_name(domain)
    context.update({
        'live_preview_ab': live_preview_ab.context,
        'is_onboarding_domain': domain_obj.is_onboarding_domain,
        'show_live_preview': (
            toggles.PREVIEW_APP.enabled(domain)
            or toggles.PREVIEW_APP.enabled(request.couch_user.username)
            or (domain_obj.is_onboarding_domain
                and live_preview_ab.version == ab_tests.LIVE_PREVIEW_ENABLED)
        )
    })

    response = render(request, 'app_manager/v1/form_designer.html', context)
    live_preview_ab.update_response(response)
    return response
Beispiel #11
0
def get_enabled_previews(domain):
    return list(feature_previews.previews_dict(domain=domain))