예제 #1
0
    def dispatch(self, request, *args, **kwargs):
        try:
            self.first_app_id = self.kwargs["first_app_id"]
            self.second_app_id = self.kwargs["second_app_id"]
            self.first_app = Application.get(self.first_app_id)
            self.second_app = Application.get(self.second_app_id)
        except (ResourceNotFound, KeyError):
            raise Http404()

        return super(AppDiffView, self).dispatch(request, *args, **kwargs)
예제 #2
0
    def test_last_modified_bulk(self):
        lm = self.app.last_modified
        Application.save_docs([self.app])
        app = Application.get(self.app._id)
        self.assertGreater(app.last_modified, lm)

        lm = self.app.last_modified
        Application.bulk_save([self.app])
        app = Application.get(self.app._id)
        self.assertGreater(app.last_modified, lm)
    def handle(self, *args, **options):
        app_ids = []
        try:
            Application.get(args[0])
            app_ids = [args[0]]
        except ResourceNotFound:
            app_ids = get_app_ids_in_domain(args[0])
            logger.info('migrating {} apps in domain {}'.format(len(app_ids), args[0]))

        for app_id in app_ids:
            logger.info('migrating app {}'.format(app_id))
            self.migrate_app(app_id)

        logger.info('done with migrate_app_to_cmitfb')
    def test_app_icon_permissions(self):
        LOGO_HOME = u'hq_logo_android_home'
        LOGO_LOGIN = u'hq_logo_android_login'

        advanced_sub = Subscription.new_domain_subscription(
            self.account, self.domain.name, self.advanced_plan,
            web_user=self.admin_user.username
        )
        with open(os.path.join(os.path.dirname(__file__), 'data', 'app-commcare-icon-standard.json')) as f:
            standard_source = json.load(f)
        with open(os.path.join(os.path.dirname(__file__), 'data', 'app-commcare-icon-build.json')) as f:
            build_source = json.load(f)

        app_standard = Application.wrap(standard_source)
        app_standard.save()
        self.assertEqual(self.domain.name, app_standard.domain)

        app_build = Application.wrap(build_source)
        app_build.save()
        self.assertEqual(self.domain.name, app_build.domain)

        self.assertTrue(LOGO_HOME in app_standard.logo_refs.keys())
        self.assertTrue(LOGO_LOGIN in app_standard.logo_refs.keys())
        self.assertTrue(LOGO_HOME in app_build.logo_refs.keys())
        self.assertTrue(LOGO_LOGIN in app_build.logo_refs.keys())

        advanced_sub.cancel_subscription(web_user=self.admin_user.username)

        app_standard = Application.get(app_standard._id)
        app_build = Application.get(app_build._id)

        self.assertFalse(LOGO_HOME in app_standard.logo_refs.keys())
        self.assertFalse(LOGO_LOGIN in app_standard.logo_refs.keys())
        self.assertFalse(LOGO_HOME in app_build.logo_refs.keys())
        self.assertFalse(LOGO_LOGIN in app_build.logo_refs.keys())

        Subscription.new_domain_subscription(
            self.account, self.domain.name, self.advanced_plan,
            web_user=self.admin_user.username
        )

        app_standard = Application.get(app_standard._id)
        app_build = Application.get(app_build._id)

        self.assertTrue(LOGO_HOME in app_standard.logo_refs.keys())
        self.assertTrue(LOGO_LOGIN in app_standard.logo_refs.keys())
        self.assertTrue(LOGO_HOME in app_build.logo_refs.keys())
        self.assertTrue(LOGO_LOGIN in app_build.logo_refs.keys())
예제 #5
0
파일: views.py 프로젝트: mchampanis/core-hq
def case_list(request, domain):
    
    apps = filter(lambda app: app.doc_type == "Application",
                  ApplicationBase.view('app_manager/applications_brief', 
                                       startkey=[domain], endkey=[domain, {}]))
    
    user_id = request.REQUEST.get("user_id", request.couch_user.get_id)
    app_id = request.REQUEST.get("app_id", "")
    module_id = int(request.REQUEST.get("module_id", "0"))
    language = request.REQUEST.get("language", "en")
    
    if not app_id and apps:
        app_id = apps[0].get_id
    
    if app_id:
        app = Application.get(app_id)
        case_short = app.modules[module_id].get_detail("case_short")
        case_long = app.modules[module_id].get_detail("case_long")
    else:
        case_short=""
        case_long=""
    
    return render_to_response(request, "cloudcare/list_cases.html", 
                              {"domain": domain,
                               "language": language,
                               "user_id": user_id,
                               "apps": apps,
                               "case_short": json.dumps(case_short._doc),
                               "case_long": json.dumps(case_long._doc),
                               "cases": json.dumps(get_owned_cases(domain, user_id),
                                                   default=json_handler)})
예제 #6
0
    def handle(self, path, app_id, **options):
        if options['deploy'] and not options['user']:
            raise CommandError('Deploy argument requires a user')
        elif options['deploy']:
            user = CouchUser.get_by_username(options['user'])
            if not user:
                raise CommandError("Couldn't find user with username {}".format(options['user']))

        app = Application.get(app_id)
        for module_dir in os.listdir(path):
            module_index, name = module_dir.split(' - ')
            module = app.get_module(int(module_index))
            for form_name in os.listdir(os.path.join(path, module_dir)):
                form_index, name = form_name.split(' - ')
                form = module.get_form(int(form_index))
                with open(os.path.join(path, module_dir, form_name), 'rb') as f:
                    save_xform(app, form, f.read())

        app.save()
        print('successfully updated {}'.format(app.name))
        if options['deploy']:
            # make build and star it
            comment = options.get('comment', 'form changes from {0}'.format(datetime.utcnow().strftime(SERVER_DATETIME_FORMAT_NO_SEC)))
            copy = app.make_build(
                comment=comment,
                user_id=user._id,
            )
            copy.is_released = True
            copy.save(increment_version=False)
            print('successfully released new version')
예제 #7
0
def form_context(request, domain, app_id, module_id, form_id):
    app = Application.get(app_id)
    form_url = "%s%s" % (get_url_base(), reverse('download_xform', args=[domain, app_id, module_id, form_id]))
    case_id = request.GET.get('case_id')

    try:
        form = app.get_module(module_id).get_form(form_id).name.values()[0]
    except (FormNotFoundException, ModuleNotFoundException):
        raise Http404()

    # make the name for the session we will use with the case and form
    session_name = u'{app} > {form}'.format(
        app=app.name,
        form=form,
    )
    if case_id:
        session_name = u'{0} - {1}'.format(session_name, CommCareCase.get(case_id).name)

    delegation = request.GET.get('task-list') == 'true'
    offline = request.GET.get('offline') == 'true'
    session_helper = SessionDataHelper(domain, request.couch_user, case_id, delegation=delegation, offline=offline)
    return json_response(session_helper.get_full_context(
        {'form_url': form_url,},
        {'session_name': session_name, 'app_id': app._id}
    ))
예제 #8
0
 def app(self):
     try:
         app = Application.get(self.app_id)
         assert app.doc_type is 'Application'
         return app
     except (ResourceNotFound, AssertionError):
         return None
    def test_update_user_restore(self, mock):
        # updating user restore should result in version change in restore resource
        #   so that CommCare mobile will refetch the resource
        turn_on_demo_mode(self.user, self.domain)
        app = self.factory.app
        app.practice_mobile_worker_id = self.user._id
        app.save()

        self.assertXmlPartialEqual(
            self._get_restore_resource(self.user.demo_restore_id),
            app.create_suite(),
            "./user-restore"
        )

        version_before = self.user.demo_restore_id
        turn_off_demo_mode(self.user)
        turn_on_demo_mode(self.user, self.domain)
        version_after = self.user.demo_restore_id
        self.assertNotEqual(version_before, version_after)

        # refetch so that memoized app.get_practice_user gets busted`
        app = Application.get(app._id)
        app.build_spec.version = '2.30.0'  # for some reason, this gets set to an old version, after refetch
        self.assertXmlPartialEqual(
            self._get_restore_resource(version_after),
            app.create_suite(),
            "./user-restore"
        )
예제 #10
0
def create_data_source_from_app(request, domain):
    if request.method == 'POST':
        form = ConfigurableDataSourceFromAppForm(domain, request.POST)
        if form.is_valid():
            # save config
            app_source = form.app_source_helper.get_app_source(form.cleaned_data)
            app = Application.get(app_source.application)
            if app_source.source_type == 'case':
                data_source = get_case_data_source(app, app_source.source)
                data_source.save()
                messages.success(request, _(u"Data source created for '{}'".format(app_source.source)))
            else:
                assert app_source.source_type == 'form'
                xform = Form.get_form(app_source.source)
                data_source = get_form_data_source(app, xform)
                data_source.save()
                messages.success(request, _(u"Data source created for '{}'".format(xform.default_name())))

            return HttpResponseRedirect(reverse('edit_configurable_data_source', args=[domain, data_source._id]))
    else:
        form = ConfigurableDataSourceFromAppForm(domain)
    context = _shared_context(domain)
    context['sources_map'] = form.app_source_helper.all_sources
    context['form'] = form
    return render(request, 'userreports/data_source_from_app.html', context)
예제 #11
0
    def __init__(self, app_id, source_type, report_source_id, *args, **kwargs):
        super(ConfigureNewReportBase, self).__init__(*args, **kwargs)

        assert source_type in ['case', 'form']
        self.source_type = source_type
        self.report_source_id = report_source_id
        self.app = Application.get(app_id)
        self.domain = self.app.domain

        self.ds_builder = DataSourceBuilder(
            self.domain, self.app, self.source_type, self.report_source_id
        )
        self.data_source_properties = self.ds_builder.data_source_properties

        # NOTE: The corresponding knockout view model is defined in:
        #       templates/userreports/partials/report_builder_configure_report.html
        self.helper = FormHelper()
        self.helper.form_class = "form-horizontal"
        self.helper.attrs['data_bind'] = "submit: submitHandler"
        self.helper.form_id = "report-config-form"

        self.helper.layout = crispy.Layout(
            self.top_fieldset,
            FormActions(
                crispy.ButtonHolder(
                    crispy.Submit(
                        'submit',
                        _(self.button_text)
                    )
                ),
            ),
        )
예제 #12
0
파일: views.py 프로젝트: dimagi/commcare-hq
    def post(self, request, domain, *args, **kwargs):
        data = json.loads(request.body)

        subscription = get_subscription_by_url(domain, data['target_url'])
        if subscription:
            # https://zapier.com/developer/documentation/v2/rest-hooks/
            # Generally, subscription URLs should be unique.
            # Return a 409 status code if this criteria isn't met (IE: there is a uniqueness conflict).
            return HttpResponse(status=409)

        if data['event'] == EventTypes.NEW_FORM:
            application = Application.get(data['application'])
            if not application or not application.get_forms_by_xmlns(data['form']):
                return HttpResponse(status=400)
            subscription = ZapierSubscription.objects.create(
                domain=domain,
                user_id=str(request.couch_user.get_id),
                event_name=data['event'],
                url=data['target_url'],
                application_id=data['application'],
                form_xmlns=data['form'],
            )
        elif data['event'] in CASE_TYPE_REPEATER_CLASS_MAP:
            subscription = ZapierSubscription.objects.create(
                domain=domain,
                user_id=str(request.couch_user.get_id),
                event_name=data['event'],
                url=data['target_url'],
                case_type=data['case_type'],
            )
        else:
            return HttpResponseBadRequest()

        # respond with the ID so that zapier can use it to unsubscribe
        return json_response({'id': subscription.id})
예제 #13
0
    def page_context(self):
        try:
            self.first_app = Application.get(self.first_app_id)
            self.second_app = Application.get(self.second_app_id)
        except (ResourceNotFound, KeyError):
            raise Http404()

        for app in (self.first_app, self.second_app):
            if not self.request.couch_user.is_member_of(app.domain):
                raise Http404()

        return {
            "app": self.first_app,
            "other_app": self.second_app,
            "files": {None: self.app_diffs},
        }
예제 #14
0
    def handle(self, linked_app_id, linked_domain, master_domain, **options):
        try:
            linked_app = Application.get(linked_app_id)
        except ResourceNotFound:
            print('No downstream app found for ID {} '.format(linked_app_id))
            return

        if linked_app.domain != linked_domain:
            print("Project space in the app found from ID {} does not match the linked project space "
                  "that was given.".format(linked_app_id))
            return

        confirm = input(
            """
            Found {} in project space {} linked to project space {}.
            Are you sure you want to un-link these apps? [y/n]
            """.format(linked_app.name, linked_domain, master_domain)
        )
        if confirm.lower() != 'y':
            return

        print('Unlinking apps')
        linked_app.convert_to_application()
        linked_app.save()
        self.hide_domain_link_history(linked_domain, linked_app_id, master_domain)
        print('Operation completed')
예제 #15
0
    def clean(self):
        cleaned_data = self.cleaned_data
        sm = cleaned_data["share_multimedia"]
        license = cleaned_data["license"]
        app_ids = self._get_apps_to_publish()

        if sm and license not in self.dom.most_restrictive_licenses(apps_to_check=app_ids):
            license_choices = [LICENSES[l] for l in self.dom.most_restrictive_licenses(apps_to_check=app_ids)]
            msg = render_to_string('domain/partials/restrictive_license.html', {'licenses': license_choices})
            self._errors["license"] = self.error_class([msg])

            del cleaned_data["license"]

        sr = cleaned_data["share_reminders"]
        if sr:  # check that the forms referenced by the events in each reminders exist in the project
            referenced_forms = CaseReminderHandler.get_referenced_forms(domain=self.dom.name)
            if referenced_forms:
                apps = [Application.get(app_id) for app_id in app_ids]
                app_forms = [f.unique_id for forms in [app.get_forms() for app in apps] for f in forms]
                nonexistent_forms = filter(lambda f: f not in app_forms, referenced_forms)
                nonexistent_forms = [FormBase.get_form(f) for f in nonexistent_forms]
                if nonexistent_forms:
                    msg = """
                        Your reminders reference forms that are not being published.
                        Make sure the following forms are being published: %s
                    """ % str([f.default_name() for f in nonexistent_forms]).strip('[]')
                    self._errors["share_reminders"] = self.error_class([msg])

        return cleaned_data
예제 #16
0
    def clean(self):
        """
        Raise a validation error if there are already 5 data sources and this
        report won't be able to use one of the existing ones.
        """
        cleaned_data = super(DataSourceForm, self).clean()
        source_type = cleaned_data.get('source_type')
        report_source = cleaned_data.get('report_source')
        app_id = cleaned_data.get('application')

        if report_source and source_type and app_id:

            app = Application.get(app_id)
            ds_builder = DataSourceBuilder(self.domain, app, source_type, report_source)

            existing_sources = DataSourceConfiguration.by_domain(self.domain)
            if len(existing_sources) >= 5:
                if not ds_builder.get_existing_match():
                    raise forms.ValidationError(_(
                        "Too many data sources!\n"
                        "Creating this report would cause you to go over the maximum "
                        "number of data sources allowed in this domain. The current "
                        "limit is 5. "
                        "To continue, delete all of the reports using a particular "
                        "data source (or the data source itself) and try again. "
                    ))

        return cleaned_data
예제 #17
0
파일: views.py 프로젝트: tsinkala/core-hq
def form_context(request, domain, app_id, module_id, form_id):
    app = Application.get(app_id)
    form_url = "%s%s" % (get_url_base(), reverse('download_xform', args=[domain, app_id, module_id, form_id]))
    case_id = request.GET.get('case_id')
    delegation = request.GET.get('task-list') == 'true'
    return json_response(
        touchforms_api.get_full_context(domain, request.couch_user, 
                                        app, form_url, case_id, delegation=delegation))
예제 #18
0
파일: views.py 프로젝트: mchampanis/core-hq
def form_context(request, domain, app_id, module_id, form_id):
    app = Application.get(app_id)
    module = app.get_module(module_id)
    form = module.get_form(form_id)
    case_id = request.REQUEST.get("case_id")
    return json_response(
        touchforms_api.get_full_context(domain, request.couch_user, 
                                        app, module, form, case_id))
예제 #19
0
    def test_xform_pillow_couch(self):
        form = self._make_form()
        kafka_seq = self._get_kafka_seq()
        producer.send_change(topics.FORM, doc_to_change(form.to_json()).metadata)
        self.assertFalse(self.app.has_submissions)

        self.pillow.process_changes(since=kafka_seq, forever=False)
        self.assertTrue(Application.get(self.app._id).has_submissions)
    def test_app_icon_permissions(self):
        LOGO_HOME = 'hq_logo_android_home'
        LOGO_LOGIN = '******'

        advanced_sub = self._subscribe_to_advanced()

        with open(os.path.join(os.path.dirname(__file__), 'data', 'app-commcare-icon-standard.json')) as f:
            standard_source = json.load(f)
        with open(os.path.join(os.path.dirname(__file__), 'data', 'app-commcare-icon-build.json')) as f:
            build_source = json.load(f)

        app_standard = Application.wrap(standard_source)
        app_standard.save()
        self.assertEqual(self.project.name, app_standard.domain)

        app_build = Application.wrap(build_source)
        app_build.save()
        self.assertEqual(self.project.name, app_build.domain)

        self.assertTrue(LOGO_HOME in app_standard.logo_refs)
        self.assertTrue(LOGO_LOGIN in app_standard.logo_refs)
        self.assertTrue(LOGO_HOME in app_build.logo_refs)
        self.assertTrue(LOGO_LOGIN in app_build.logo_refs)

        community_sub = advanced_sub.change_plan(DefaultProductPlan.get_default_plan_version())

        app_standard = Application.get(app_standard._id)
        app_build = Application.get(app_build._id)

        self.assertFalse(LOGO_HOME in app_standard.logo_refs)
        self.assertFalse(LOGO_LOGIN in app_standard.logo_refs)
        self.assertFalse(LOGO_HOME in app_build.logo_refs)
        self.assertFalse(LOGO_LOGIN in app_build.logo_refs)

        community_sub.change_plan(
            DefaultProductPlan.get_default_plan_version(edition=SoftwarePlanEdition.ADVANCED)
        )

        app_standard = Application.get(app_standard._id)
        app_build = Application.get(app_build._id)

        self.assertTrue(LOGO_HOME in app_standard.logo_refs)
        self.assertTrue(LOGO_LOGIN in app_standard.logo_refs)
        self.assertTrue(LOGO_HOME in app_build.logo_refs)
        self.assertTrue(LOGO_LOGIN in app_build.logo_refs)
예제 #21
0
def filter_cases(request, domain, app_id, module_id):
    app = Application.get(app_id)
    module = app.get_module(module_id)
    delegation = request.GET.get('task-list') == 'true'
    auth_cookie = request.COOKIES.get('sessionid')

    suite_gen = SuiteGenerator(app)
    xpath = suite_gen.get_filter_xpath(module, delegation=delegation)
    extra_instances = [{'id': inst.id, 'src': inst.src}
                       for inst in suite_gen.get_instances_for_module(module, additional_xpaths=[xpath])]

    # touchforms doesn't like this to be escaped
    xpath = HTMLParser.HTMLParser().unescape(xpath)
    if delegation:
        case_type = DELEGATION_STUB_CASE_TYPE
    else:
        case_type = module.case_type

    if xpath:
        # if we need to do a custom filter, send it to touchforms for processing
        additional_filters = {
            "properties/case_type": case_type,
            "footprint": True
        }

        helper = SessionDataHelper(domain, request.couch_user)
        result = helper.filter_cases(xpath, additional_filters, DjangoAuth(auth_cookie),
                                     extra_instances=extra_instances)
        if result.get('status', None) == 'error':
            return HttpResponseServerError(
                result.get("message", _("Something went wrong filtering your cases.")))

        case_ids = result.get("cases", [])
    else:
        # otherwise just use our built in api with the defaults
        case_ids = [res.id for res in get_filtered_cases(
            domain, status=CASE_STATUS_OPEN, case_type=case_type,
            user_id=request.couch_user._id, ids_only=True
        )]

    cases = [CommCareCase.wrap(doc) for doc in iter_docs(CommCareCase.get_db(), case_ids)]
    # refilter these because we might have accidentally included footprint cases
    # in the results from touchforms. this is a little hacky but the easiest
    # (quick) workaround. should be revisted when we optimize the case list.
    cases = filter(lambda c: c.type == case_type, cases)
    cases = [c.get_json(lite=True) for c in cases if c]
    parents = []
    if delegation:
        for case in cases:
            parent_id = case['indices']['parent']['case_id']
            parents.append(CommCareCase.get(parent_id))
        return json_response({
            'cases': cases,
            'parents': parents
        })
    else:
        return json_response(cases)
예제 #22
0
 def filename(self):
     file_ext = Format.from_format(self.format).extension
     filename = "%s.%s" % (self.export_id, file_ext)
     try:
         app = Application.get(self.export_id)
         if app:
             filename = "%s-%s.%s" %(app.name, app.get_id, file_ext)
     except Exception:
         pass
     return filename
예제 #23
0
    def test_broken_build(self):
        client = Client()
        url = '/a/{domain}/apps/download/{build_id}/suite.xml'.format(
            domain=self.build.domain,
            build_id=self.build.get_id,
        )
        self.build = Application.get(self.build.get_id)
        self.assertEqual(self.build.build_broken, False)

        # delete the file and do it again, and assert the build is broken
        self.assertIn('files/suite.xml', self.build._attachments)
        self.build.delete_attachment('files/suite.xml')
        self.assertNotIn('files/suite.xml', self.build._attachments)

        self.build = Application.get(self.build.get_id)
        response = client.get(url)
        self.assertEqual(response.status_code, 404)
        self.build = Application.get(self.build.get_id)
        self.assertEqual(self.build.build_broken, True)
예제 #24
0
 def ensure_prerequisites(self, domain, app_id, version_number, test_run):
     self.domain = domain
     self.app_id = app_id
     self.version_number = version_number
     self.test_run = test_run == 'yes'
     _notify_parsed_args(domain, app_id, version_number, test_run)
     app = Application.get(self.app_id)
     if app.domain != self.domain:
         raise CommandError('Domain not same as from app id')
     self.setup()
예제 #25
0
def _get_app_by_name(domain, name):
    app = Application.view('app_manager/applications_brief',
                                 startkey=[domain, name, {}],
                                 endkey=[domain, name],
                                 descending=True,
                                 limit=1).one()
    if app:
        return Application.get(app['_id'])
    else:
        raise ResourceNotFound(_("Not found application by name: %s") % name)
예제 #26
0
 def testCreateJadJar(self, mock):
     self.app.build_spec = BuildSpec(**self.build1)
     self.app.create_build_files(save=True)
     self.app.save(increment_version=False)
     # get a fresh one from the db to make sure attachments aren't cached
     # since that's closer to the real situation
     self.app = Application.get(self.app._id)
     self.app.create_jadjar_from_build_files(save=True)
     self.app.save(increment_version=False)
     self._check_has_build_files(self.app, self.jad_jar_paths)
예제 #27
0
파일: views.py 프로젝트: ekush/commcare-hq
def filter_cases(request, domain, app_id, module_id, parent_id=None):
    app = Application.get(app_id)
    module = app.get_module(module_id)
    auth_cookie = request.COOKIES.get('sessionid')

    suite_gen = SuiteGenerator(app)
    xpath = SuiteGenerator.get_filter_xpath(module)
    extra_instances = [{'id': inst.id, 'src': inst.src}
                       for inst in suite_gen.get_instances_for_module(module, additional_xpaths=[xpath])]

    # touchforms doesn't like this to be escaped
    xpath = HTMLParser.HTMLParser().unescape(xpath)
    case_type = module.case_type

    if xpath:
        # if we need to do a custom filter, send it to touchforms for processing
        additional_filters = {
            "properties/case_type": case_type,
            "footprint": True
        }

        helper = SessionDataHelper(domain, request.couch_user)
        result = helper.filter_cases(xpath, additional_filters, DjangoAuth(auth_cookie),
                                     extra_instances=extra_instances)
        if result.get('status', None) == 'error':
            code = result.get('code', 500)
            message = result.get('message', _("Something went wrong filtering your cases."))
            if code == 500:
                notify_exception(None, message=message)
            return json_response(message, status_code=code)

        case_ids = result.get("cases", [])
    else:
        # otherwise just use our built in api with the defaults
        case_ids = [res.id for res in get_filtered_cases(
            domain,
            status=CASE_STATUS_OPEN,
            case_type=case_type,
            user_id=request.couch_user._id,
            footprint=True,
            ids_only=True,
        )]

    cases = [CommCareCase.wrap(doc) for doc in iter_docs(CommCareCase.get_db(), case_ids)]

    if parent_id:
        cases = filter(lambda c: c.parent and c.parent.case_id == parent_id, cases)

    # refilter these because we might have accidentally included footprint cases
    # in the results from touchforms. this is a little hacky but the easiest
    # (quick) workaround. should be revisted when we optimize the case list.
    cases = filter(lambda c: c.type == case_type, cases)
    cases = [c.get_json(lite=True) for c in cases if c]

    return json_response(cases)
예제 #28
0
    def test_two_forms_with_same_app(self):
        """Ensures two forms submitted to the same app does not error"""
        kafka_seq = self._get_kafka_seq()

        self._make_form()

        # confirm change made it to kafka
        self.assertFalse(self.app.has_submissions)

        self.pillow.process_changes(since=kafka_seq, forever=False)
        newly_saved_app = Application.get(self.app._id)
        self.assertTrue(newly_saved_app.has_submissions)
        # Ensure that the app has been saved
        self.assertNotEqual(self.app._rev, newly_saved_app._rev)

        self._make_form()
        self.pillow.process_changes(since=kafka_seq, forever=False)
        self.assertTrue(Application.get(self.app._id).has_submissions)
        # Ensure that the app has not been saved twice
        self.assertEqual(Application.get(self.app._id)._rev, newly_saved_app._rev)
예제 #29
0
파일: forms.py 프로젝트: jmaina/commcare-hq
 def clean(self):
     cleaned_data = super(ConfigurableDataSourceFromAppForm, self).clean()
     app = Application.get(cleaned_data['app_id'])
     if cleaned_data['case_type'] not in app.get_case_types():
         raise ValidationError(_('Case type {} not found in application {}!'.format(
             cleaned_data['case_type'],
             app.name,
         )))
     # set the app property on the form so we don't have to go back to the DB for it
     # there may be a better way to do this.
     self.app = app
     return cleaned_data
예제 #30
0
파일: forms.py 프로젝트: jmaina/commcare-hq
 def clean(self):
     cleaned_data = super(ConfigurableFormDataSourceFromAppForm, self).clean()
     app = Application.get(cleaned_data['app_id'])
     form = Form.get_form(cleaned_data['form_id'])
     if form.get_app()._id != app._id:
         raise ValidationError(_('Form name {} not found in application {}').format(
             form.default_name(),
             app.name
         ))
     self.app = app
     self.form = form
     return cleaned_data
예제 #31
0
    def __call__(self, item, context=None):
        xforms_ids = CommCareCase.objects.get_case_xform_ids(item['_id'])
        forms = XFormInstance.objects.get_forms(xforms_ids, item['domain'])
        f_forms = [f for f in forms if f.xmlns == self.xmlns]
        s_forms = sorted(f_forms, key=lambda x: x.received_on)

        if len(s_forms) > 0:
            latest_form = s_forms[-1]
        else:
            latest_form = None
        path_to_action_plan = 'form/action_plan/%s/action_plan' % self.section

        if latest_form:
            action_plans = latest_form.get_data(path_to_action_plan)
            if action_plans:
                action_plan_for_question = None
                for action_plan in action_plans:
                    if action_plan.get('incorrect_questions', '') == self.question_id:
                        action_plan_for_question = action_plan
                        break
                if action_plan_for_question:
                    incorrect_question = action_plan_for_question.get('incorrect_questions', '')
                    responsible = ', '.join(
                        [
                            item.get(x.strip(), '---') for x in
                            action_plan_for_question.get('action_plan_input', {}).get('responsible', '').split(',')
                        ]
                    )
                    support = ', '.join(
                        [
                            item.get(x.strip(), '---') for x in
                            action_plan_for_question.get('action_plan_input', {}).get('support', '').split(',')
                        ]
                    )
                    application = Application.get(latest_form.app_id)
                    form = application.get_forms_by_xmlns(self.xmlns)[0]
                    question_list = application.get_questions(self.xmlns)
                    questions = {x['value']: x for x in question_list}
                    return {
                        'form_name': form.name['en'],
                        'section': self.section,
                        'timeEnd': latest_form.metadata.timeEnd,
                        'gap': questions.get('data/code_to_text/%s' % incorrect_question, {}).get('label', '---'),
                        'intervention_action': action_plan_for_question.get('intervention_action', '---'),
                        'responsible': responsible,
                        'support': support,
                        'deadline': action_plan_for_question.get('DEADLINE', '---'),
                        'notes': action_plan_for_question.get('notes', '---'),
                    }
예제 #32
0
    def obj_get_list(self, bundle, **kwargs):
        """
            https://zapier.com/developer/documentation/v2/trigger-fields-custom/
            Zapier custom fields allow to show default form properties, even if there are no forms submitted.
            It also allows to assign label to json property.
            Format of custom field:
            {
                "type": "unicode",
                "key": "json_key",
                "label": "Label", // optional
                "help_text": "Helps to explain things to users." // optional
            }
        """
        application_id = bundle.request.GET.get('application_id')
        xmlns = bundle.request.GET.get('xmlns')
        if not application_id or not xmlns:
            return []

        try:
            app = Application.get(application_id)
        except ResourceNotFound:
            raise NotFound

        form = app.get_form_by_xmlns(xmlns)
        custom_fields = []

        for idx, question in enumerate(form.get_questions(app.langs)):
            if self._has_default_label(question):
                label = question['label'].split('/')[-1]
            else:
                label = question['label']

            custom_fields.append(
                CustomField(
                    dict(type='unicode',
                         key=self._build_key(question['hashtagValue']),
                         label=label)))

        for form_property in MAIN_FORM_TABLE_PROPERTIES:
            if form_property.is_advanced:
                continue
            custom_fields.append(
                CustomField(
                    dict(type='unicode',
                         key='__'.join(
                             [node.name for node in form_property.item.path]),
                         label=form_property.label,
                         help_text=form_property.help_text)))
        return custom_fields
예제 #33
0
    def test_deletes_module_child_removed(self):
        # Create new module
        handle_shadow_child_modules(
            self.app,
            self.app.get_module_by_unique_id(self.shadow_module.unique_id))

        # Change child module's parent
        app = Application.get(self.app.get_id)
        app.modules[1].root_module_id = None
        app.save()

        # The new shadow module should be deleted, since it is no longer needed
        handle_shadow_child_modules(
            app, app.get_module_by_unique_id(self.shadow_module.unique_id))
        self.assertEqual(len(app.modules), 3)
예제 #34
0
def export_gzip(req, domain, app_id):
    app_json = get_app(domain, app_id)
    fd, fpath = tempfile.mkstemp()
    with os.fdopen(fd, 'w') as tmp:
        with zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED) as z:
            z.writestr('application.json', app_json.export_json())

    wrapper = FileWrapper(open(fpath))
    response = HttpResponse(wrapper, content_type='application/zip')
    response['Content-Length'] = os.path.getsize(fpath)
    app = Application.get(app_id)
    set_file_download(response, '{domain}-{app_name}-{app_version}.zip'.format(
        app_name=slugify(app.name), app_version=slugify(unicode(app.version)), domain=domain
    ))
    return response
예제 #35
0
    def test_form_pillow_non_existant_build_id(self):
        consumer = get_test_kafka_consumer(topics.FORM, topics.FORM_SQL)
        kafka_seq = self._get_kafka_seq()

        form = self._make_form(build_id='not-here')

        # confirm change made it to kafka
        message = next(consumer)
        change_meta = change_meta_from_kafka_message(message.value)
        self.assertEqual(form.form_id, change_meta.document_id)
        self.assertEqual(self.domain, change_meta.domain)
        self.assertFalse(self.app.has_submissions)

        self.pillow.process_changes(since=kafka_seq, forever=False)
        self.assertFalse(Application.get(self.app._id).has_submissions)
예제 #36
0
    def handle(self, master_id, linked_id, **options):
        print("Linking apps")
        master_app = Application.get(master_id)
        master_version = get_latest_released_app_version(master_app.domain, master_id)
        if not master_version:
            raise CommandError(
                "Creating linked app failed."
                " Unable to get latest released version of your app."
                " Make sure you have at least one released build."
            )

        linked_app = LinkedApplication.get(linked_id)

        link_app(linked_app, master_app.domain, master_id)
        update_linked_app(linked_app, 'system')
예제 #37
0
 def create_build_files_if_necessary_handling_conflicts(is_retry=False):
     try:
         try:
             # look for file guaranteed to exist if profile is created
             request.app.fetch_attachment(
                 'files/{id}/profile.xml'.format(id=build_profile),
                 return_bytes=True)
         except ResourceNotFound:
             request.app.create_build_files(build_profile_id=build_profile)
             request.app.save()
     except ResourceConflict:
         if is_retry:
             raise
         request.app = Application.get(request.app.get_id)
         create_build_files_if_necessary_handling_conflicts(True)
예제 #38
0
def toggle_build_profile(request, domain, build_id, build_profile_id):
    build = Application.get(build_id)
    action = request.GET.get('action')
    if action and action == 'enable' and not build.is_released:
        messages.error(request, _("Release the build first. Can not enable profiles for unreleased versions"))
        return HttpResponseRedirect(reverse('download_index', args=[domain, build_id]))
    latest_enabled_build_profile = LatestEnabledBuildProfiles.objects.filter(
        app_id=build.copy_of,
        build_profile_id=build_profile_id
    ).order_by('-version').first()
    if action == 'enable' and latest_enabled_build_profile:
        if latest_enabled_build_profile.version > build.version:
            messages.error(request, _(
                "Latest version available for this profile is {}, which is "
                "higher than this version. Disable any higher versions first.".format(
                    latest_enabled_build_profile.version
                )))
            return HttpResponseRedirect(reverse('download_index', args=[domain, build_id]))
    if action == 'enable':
        build_profile = LatestEnabledBuildProfiles.objects.create(
            app_id=build.copy_of,
            version=build.version,
            build_profile_id=build_profile_id,
            build_id=build_id
        )
        build_profile.expire_cache(domain)
    elif action == 'disable':
        build_profile = LatestEnabledBuildProfiles.objects.filter(
            app_id=build.copy_of,
            version=build.version,
            build_profile_id=build_profile_id,
            build_id=build_id
        ).first()
        build_profile.delete()
        build_profile.expire_cache(domain)
    latest_enabled_build_profile = LatestEnabledBuildProfiles.objects.filter(
        app_id=build.copy_of,
        build_profile_id=build_profile_id
    ).order_by('-version').first()
    if latest_enabled_build_profile:
        messages.success(request, _("Latest version for profile {} is now {}").format(
            build.build_profiles[build_profile_id].name, latest_enabled_build_profile.version
        ))
    else:
        messages.success(request, _("Latest release now available for profile {}").format(
            build.build_profiles[build_profile_id].name
        ))
    return HttpResponseRedirect(reverse('download_index', args=[domain, build_id]))
예제 #39
0
    def obj_get_list(self, bundle, **kwargs):
        application_id = bundle.request.GET.get('application_id')
        if not application_id:
            raise NotFound('application_id parameter required')

        results = []
        application = Application.get(docid=application_id)
        if not application:
            return []
        forms_objects = application.get_forms(bare=False)

        for form_object in forms_objects:
            form = form_object['form']
            module = form_object['module']
            form_name = '{} > {} > {}'.format(application.name, module.default_name(), form.default_name())
            results.append(Form(form_xmlns=form.xmlns, form_name=form_name))
        return results
예제 #40
0
    def handle(self, app_id, path, **options):
        # setup directory
        if not os.path.exists(path):
            os.mkdir(path)

        app = Application.get(app_id)
        for module_index, module in enumerate(app.get_modules()):
            module_dir_name = '{index} - {name}'.format(index=module_index, name=unicode_slug(module.default_name()))
            module_dir = os.path.join(path, module_dir_name)
            if not os.path.exists(module_dir):
                os.mkdir(module_dir)
            for form_index, form in enumerate(module.get_forms()):
                form_name = ('{index} - {name}.xml'.format(index=form_index, name=unicode_slug(form.default_name())))
                form_path = os.path.join(module_dir, form_name)
                with open(form_path, 'w') as f:
                    f.write(form.source.encode('utf-8'))
                    print('wrote {}'.format(form_path))
예제 #41
0
    def test_form_pillow_mismatch_domains(self):
        consumer = get_test_kafka_consumer(topics.FORM, topics.FORM_SQL)
        kafka_seq = self._get_kafka_seq()
        self.app.domain = 'not-this-domain'
        self.app.save()

        form = self._make_form()

        # confirm change made it to kafka
        message = consumer.next()
        change_meta = change_meta_from_kafka_message(message.value)
        self.assertEqual(form.form_id, change_meta.document_id)
        self.assertEqual(self.domain, change_meta.domain)
        self.assertFalse(self.app.has_submissions)

        self.pillow.process_changes(since=kafka_seq, forever=False)
        self.assertFalse(Application.get(self.app._id).has_submissions)
예제 #42
0
def form_context(request, domain, app_id, module_id, form_id):
    app = Application.get(app_id)
    form_url = "%s%s" % (get_url_base(),
                         reverse('download_xform',
                                 args=[domain, app_id, module_id, form_id]))
    case_id = request.GET.get('case_id')
    instance_id = request.GET.get('instance_id')
    try:
        form = app.get_module(module_id).get_form(form_id)
    except (FormNotFoundException, ModuleNotFoundException):
        raise Http404()

    form_name = form.name.values()[0]

    # make the name for the session we will use with the case and form
    session_name = u'{app} > {form}'.format(
        app=app.name,
        form=form_name,
    )
    if case_id:
        session_name = u'{0} - {1}'.format(session_name,
                                           CommCareCase.get(case_id).name)

    root_context = {
        'form_url': form_url,
    }
    if instance_id:
        try:
            root_context['instance_xml'] = XFormInstance.get_db(
            ).fetch_attachment(instance_id, ATTACHMENT_NAME)
        except ResourceNotFound:
            raise Http404()

    session_extras = {'session_name': session_name, 'app_id': app._id}
    session_extras.update(
        get_cloudcare_session_data(domain, form, request.couch_user))

    delegation = request.GET.get('task-list') == 'true'
    offline = request.GET.get('offline') == 'true'
    session_helper = SessionDataHelper(domain,
                                       request.couch_user,
                                       case_id,
                                       delegation=delegation,
                                       offline=offline)
    return json_response(
        session_helper.get_full_context(root_context, session_extras))
예제 #43
0
파일: views.py 프로젝트: ekush/commcare-hq
 def post(self, request, *args, **kwargs):
     if self.create_export_form.is_valid():
         app_id = self.create_export_form.cleaned_data['application']
         form_unique_id = self.create_export_form.cleaned_data['form']
         return HttpResponseRedirect(
             reverse(
                 CreateCustomFormExportView.urlname,
                 args=[self.domain],
             ) + ('?export_tag="%(export_tag)s"&app_id=%(app_id)s' % {
                 'app_id': app_id,
                 'export_tag': [
                     form for form in Application.get(app_id).get_forms()
                     if form.get_unique_id() == form_unique_id
                 ][0].xmlns,
             })
         )
     return self.get(self.request, *args, **kwargs)
예제 #44
0
def _create_linked_app(request, app_id, build_id, from_domain, to_domain,
                       link_app_name):
    # Linked apps can only be created from released versions
    error = None
    if from_domain == to_domain:
        error = _(
            "You may not create a linked app in the same domain as its master app."
        )
    elif build_id:
        from_app = Application.get(build_id)
        if not from_app.is_released:
            error = _(
                "Make sure the version you are copying from is released.")
    else:
        from_app = get_latest_released_app(from_domain, app_id)
        if not from_app:
            error = _("Unable to get latest released version of your app."
                      " Make sure you have at least one released build.")

    if error:
        messages.error(request,
                       _("Creating linked app failed. {}").format(error))
        return HttpResponseRedirect(
            reverse_util('app_settings', params={}, args=[from_domain,
                                                          app_id]))

    linked_app = create_linked_app(from_domain, from_app.master_id, to_domain,
                                   link_app_name)
    try:
        update_linked_app(linked_app,
                          request.couch_user.get_id,
                          master_build=from_app)
    except AppLinkError as e:
        linked_app.delete()
        messages.error(request, str(e))
        return HttpResponseRedirect(
            reverse_util('app_settings',
                         params={},
                         args=[from_domain, from_app.master_id]))

    messages.success(request, _('Application successfully copied and linked.'))
    return HttpResponseRedirect(
        reverse_util('app_settings',
                     params={},
                     args=[to_domain, linked_app.get_id]))
예제 #45
0
def get_form_source_download_url(xform):
    """Returns the download url for the form source for a submitted XForm
    """
    if not xform.build_id:
        return None

    from corehq.apps.app_manager.models import Application
    app = Application.get(xform.build_id)
    try:
        form = app.get_forms_by_xmlns(xform.xmlns)[0]
    except KeyError:
        return None

    return reverse("app_download_file", args=[
        xform.domain,
        xform.build_id,
        app.get_form_filename(module=form.get_module(), form=form),
    ])
예제 #46
0
    def test_deletes_module_source_changed(self):
        # Create new module
        handle_shadow_child_modules(
            self.app,
            self.app.get_module_by_unique_id(self.shadow_module.unique_id))

        # Change parent shadow module's source
        app = Application.get(self.app.get_id)
        new_module = Module.new_module("name", "en")
        app.add_module(new_module)
        app.get_module_by_unique_id(self.shadow_module.unique_id
                                    ).source_module_id = new_module.unique_id
        app.save()
        self.assertEqual(len(app.modules), 5)

        # Child shadow module should be removed
        handle_shadow_child_modules(
            app, app.get_module_by_unique_id(self.shadow_module.unique_id))
        self.assertEqual(len(app.modules), 4)
예제 #47
0
    def rows(self):
        rows = []
        selected_app = self.request_params.get(SelectApplicationField.slug, '')
        UNKNOWN = _("unknown")
        for user in self.users:
            last_seen = self.table_cell(-1, _("Never"))
            app_name = "---"
            is_unknown = True
            key = make_form_couch_key(self.domain, user_id=user.get('user_id'))
            data = XFormInstance.view("reports_forms/all_forms",
                startkey=key+[{}],
                endkey=key,
                include_docs=True,
                descending=True,
                reduce=False,
                limit=1,
            ).first()

            if data:
                last_seen = util.format_relative_date(data.received_on)

                if data.version != '1':
                    build_id = data.version
                else:
                    build_id = UNKNOWN

                form_data = data.get_form
                try:
                    app_name = form_data['meta']['appVersion']['#text']
                except KeyError:
                    try:
                        app = Application.get(data.app_id)
                        is_unknown = False
                        if selected_app and selected_app != data.app_id:
                            continue
                        app_name = "%s [%s]" % (app.name, build_id)
                    except Exception:
                        app_name = UNKNOWN
            if is_unknown and selected_app:
                continue
            row = [user.get('username_in_report'), last_seen, app_name]
            rows.append(row)
        return rows
예제 #48
0
파일: forms.py 프로젝트: ekush/commcare-hq
 def _bootstrap(self, existing_report):
     """
     Use an existing report to initialize some of the instance variables of this
     form. This method is used when editing an existing report.
     """
     self.report_name = existing_report.title
     self.source_type = {
         "CommCareCase": "case",
         "XFormInstance": "form"
     }[existing_report.config.referenced_doc_type]
     self.report_source_id = existing_report.config.meta.build.source_id
     app_id = existing_report.config.meta.build.app_id
     if app_id:
         self.app = Application.get(app_id)
     else:
         raise BadBuilderConfigError(
             _("Report builder data source doesn't reference an application. "
               "It is likely this report has been customized and it is no longer editable. "
               ))
예제 #49
0
    def clean(self):
        cleaned_data = self.cleaned_data
        sm = cleaned_data["share_multimedia"]
        license = cleaned_data["license"]
        app_ids = self._get_apps_to_publish()

        if sm and license not in self.dom.most_restrictive_licenses(
                apps_to_check=app_ids):
            license_choices = [
                LICENSES[l] for l in self.dom.most_restrictive_licenses(
                    apps_to_check=app_ids)
            ]
            msg = render_to_string('domain/partials/restrictive_license.html',
                                   {'licenses': license_choices})
            self._errors["license"] = self.error_class([msg])

            del cleaned_data["license"]

        sr = cleaned_data["share_reminders"]
        if sr:  # check that the forms referenced by the events in each reminders exist in the project
            referenced_forms = CaseReminderHandler.get_referenced_forms(
                domain=self.dom.name)
            if referenced_forms:
                apps = [Application.get(app_id) for app_id in app_ids]
                app_forms = [
                    f.unique_id for forms in [app.get_forms() for app in apps]
                    for f in forms
                ]
                nonexistent_forms = filter(lambda f: f not in app_forms,
                                           referenced_forms)
                nonexistent_forms = [
                    FormBase.get_form(f) for f in nonexistent_forms
                ]
                if nonexistent_forms:
                    msg = """
                        Your reminders reference forms that are not being published.
                        Make sure the following forms are being published: %s
                    """ % str([f.default_name()
                               for f in nonexistent_forms]).strip('[]')
                    self._errors["share_reminders"] = self.error_class([msg])

        return cleaned_data
예제 #50
0
    def testRevertToCopy(self, mock):
        old_name = 'old name'
        new_name = 'new name'
        app = Application.wrap(self._yesno_source)
        app.name = old_name
        app.save()

        copy = app.make_build()
        copy.save()

        self.assertEqual(copy.name, old_name)

        app.name = new_name
        app.save()
        app = Application.get(app.get_id)
        self.assertEqual(app.name, new_name)

        app = app.make_reversion_to_copy(copy)
        app.save()
        self.assertEqual(app.name, old_name)
예제 #51
0
    def migrate_app(self, app_id):
        app = Application.get(app_id)
        if app.vellum_case_management:
            logger.info('already migrated app {}'.format(app_id))
            return

        modules = [m for m in app.modules if m.module_type == 'basic']
        for module in modules:
            forms = [f for f in module.forms if f.doc_type == 'Form']
            for form in forms:
                preload = form.actions.case_preload.preload
                if preload:
                    xform = XForm(form.source)
                    xform.add_case_preloads(preload)
                    save_xform(app, form, ET.tostring(xform.xml))
                    form.actions.load_from_form = form.actions.case_preload
                    form.actions.case_preload = PreloadAction()

        app.vellum_case_management = True
        app.save()
예제 #52
0
    def post(self, request, domain, *args, **kwargs):
        data = json.loads(request.body)
        application = Application.get(docid=data['application'])
        if not application or not application.get_form_by_xmlns(data['form']):
            return HttpResponse(status=400)

        subscription = get_subscription_by_url(domain, data['target_url'])
        if subscription:
            # https://zapier.com/developer/documentation/v2/rest-hooks/
            # Generally, subscription URLs should be unique.
            # Return a 409 status code if this criteria isn't met (IE: there is a uniqueness conflict).
            return HttpResponse(status=409)

        ZapierSubscription.objects.create(domain=domain,
                                          user_id=str(
                                              request.couch_user.get_id),
                                          event_name=data['event'],
                                          url=data['target_url'],
                                          application_id=data['application'],
                                          form_xmlns=data['form'])
        return HttpResponse('OK')
예제 #53
0
    def handle(self, *args, **options):
        if len(args) != 2:
            raise CommandError('Usage: %s\n%s' % (self.args, self.help))
        if options['deploy'] and not options['user']:
            raise CommandError('Deploy argument requires a user')
        elif options['deploy']:
            user = CouchUser.get_by_username(options['user'])
            if not user:
                raise CommandError(
                    "Couldn't find user with username {}".format(
                        options['user']))

        # todo: would be nice if this worked off remote servers too
        path, app_id = args

        app = Application.get(app_id)
        for module_dir in os.listdir(path):
            module_index, name = module_dir.split(' - ')
            module = app.get_module(int(module_index))
            for form_name in os.listdir(os.path.join(path, module_dir)):
                form_index, name = form_name.split(' - ')
                form = module.get_form(int(form_index))
                with open(os.path.join(path, module_dir, form_name)) as f:
                    save_xform(app, form, f.read())

        app.save()
        print 'successfully updated {}'.format(app.name)
        if options['deploy']:
            # make build and star it
            comment = options.get(
                'comment', 'form changes from {0}'.format(
                    datetime.utcnow().strftime(SERVER_DATETIME_FORMAT_NO_SEC)))
            copy = app.make_build(
                comment=comment,
                user_id=user._id,
                previous_version=app.get_latest_app(released_only=False),
            )
            copy.is_released = True
            copy.save(increment_version=False)
            print 'successfully released new version'
예제 #54
0
    def migrate_app(self, app_id):
        app = Application.get(app_id)
        if app.vellum_case_management:
            logger.info('already migrated app {}'.format(app_id))
            return

        modules = [m for m in app.modules if m.module_type == 'basic']
        for module in modules:
            forms = [f for f in module.forms if f.doc_type == 'Form']
            for form in forms:
                preload = form.actions.case_preload.preload
                if preload:
                    if form.requires == 'case':
                        xform = XForm(form.source)
                        xform.add_case_preloads(preload)
                        save_xform(app, form, ET.tostring(xform.xml))
                        form.case_references = {"load": {path: [case_property]
                            for path, case_property in preload.iteritems()}}
                    form.actions.case_preload = PreloadAction()

        app.vellum_case_management = True
        app.save()
 def handle(self, add_on_name, *args, **options):
     add_to_toggle = options.get('add_to_toggle')
     if add_to_toggle:
         add_to_toggle = find_static_toggle(add_to_toggle)
         if not add_to_toggle:
             raise CommandError('Toggle %s not found.' % add_to_toggle)
     with open("apps_with_feature_%s.csv" % add_on_name, "w", encoding='utf-8') as csvfile:
         writer = csv.DictWriter(csvfile,
                                 fieldnames=[
                                     'domain', 'application_id', 'app_name',
                                     'all_add_ons_enabled', 'status'
                                 ])
         writer.writeheader()
         for domain_obj in self._iter_domains(options):
             application_ids = get_app_ids_in_domain(domain_obj.name)
             for application_id in application_ids:
                 application = Application.get(application_id)
                 if not application.is_remote_app():
                     all_add_ons_enabled = toggles.ENABLE_ALL_ADD_ONS.enabled(domain_obj.name)
                     if add_on_name in application.add_ons or all_add_ons_enabled:
                         try:
                             writer.writerow({
                                 'domain': domain_obj.name.encode('utf-8'),
                                 'application_id': application.get_id,
                                 'app_name': application.name.encode('utf-8'),
                                 'all_add_ons_enabled': all_add_ons_enabled,
                                 'status': application.add_ons.get(add_on_name)
                             })
                             if add_to_toggle:
                                 add_to_toggle.set(domain_obj.name, True, NAMESPACE_DOMAIN)
                         except UnicodeEncodeError:
                             print('encode error')
                             print({
                                 'domain': domain_obj.name,
                                 'application_id': application.get_id,
                                 'app_name': application.name,
                                 'all_add_ons_enabled': all_add_ons_enabled,
                                 'status': application.add_ons.get(add_on_name)
                             })
예제 #56
0
    def test_fix_xforms_with_missing_xmlns_task_fixed(self):
        """Tests the ability to fix xforms with the periodic cron task
        """

        good_form, bad_form, good_xform, bad_xforms = self.build_app_with_bad_form()
        # Fix bad builds
        for bad_xform in bad_xforms:
            app = Application.get(bad_xform.build_id)
            for form in app.get_forms():
                if form.xmlns == 'undefined':
                    form.xmlns = 'my-fixed-xmlns'
            app.save()

        self._refresh_pillow()

        with tempdir() as tmp:
            with patch('corehq.apps.cleanup.tasks.UNDEFINED_XMLNS_LOG_DIR', tmp):
                with patch('corehq.apps.cleanup.tasks.mail_admins_async') as mocked_mail:
                    stats, log_file_path = fix_xforms_with_missing_xmlns()
                    self.assertTrue(mocked_mail.delay.called)

        self.assertTrue(stats['fixed'][DOMAIN], len(bad_xforms))
예제 #57
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)
예제 #58
0
def form_context(request, domain, app_id, module_id, form_id):
    app = Application.get(app_id)
    form_url = '{}{}'.format(
        settings.CLOUDCARE_BASE_URL or get_url_base(),
        reverse('download_xform', args=[domain, app_id, module_id, form_id]))
    case_id = request.GET.get('case_id')
    instance_id = request.GET.get('instance_id')
    try:
        form = app.get_module(module_id).get_form(form_id)
    except (FormNotFoundException, ModuleNotFoundException):
        raise Http404()

    form_name = list(form.name.values())[0]

    # make the name for the session we will use with the case and form
    session_name = '{app} > {form}'.format(
        app=app.name,
        form=form_name,
    )

    if case_id:
        case = CaseAccessors(domain).get_case(case_id)
        session_name = '{0} - {1}'.format(session_name, case.name)
예제 #59
0
    def test_update_user_restore(self, mock):
        # updating user restore should result in version change in restore resource
        #   so that CommCare mobile will refetch the resource
        turn_on_demo_mode(self.user, self.domain)
        app = self.factory.app
        app.practice_mobile_worker_id = self.user._id
        app.save()

        self.assertXmlPartialEqual(
            self._get_restore_resource(self.user.demo_restore_id),
            app.create_suite(), "./user-restore")

        version_before = self.user.demo_restore_id
        turn_off_demo_mode(self.user)
        turn_on_demo_mode(self.user, self.domain)
        version_after = self.user.demo_restore_id
        self.assertNotEqual(version_before, version_after)

        # refetch so that memoized app.get_practice_user gets busted`
        app = Application.get(app._id)
        app.build_spec.version = '2.30.0'  # for some reason, this gets set to an old version, after refetch
        self.assertXmlPartialEqual(self._get_restore_resource(version_after),
                                   app.create_suite(), "./user-restore")
예제 #60
0
    def obj_get_list(self, bundle, **kwargs):
        application_id = bundle.request.GET.get('application_id')
        if not application_id:
            raise NotFound('application_id parameter required')

        domain = kwargs['domain']
        couch_user = CouchUser.from_django_user(bundle.request.user)
        if not domain_has_privilege(domain, privileges.ZAPIER_INTEGRATION) or not couch_user.is_member_of(domain):
            raise ImmediateHttpResponse(
                HttpForbidden('You are not allowed to get list of forms for this domain')
            )

        results = []
        application = Application.get(docid=application_id)
        if not application:
            return []
        forms_objects = application.get_forms(bare=False)
        for form_object in forms_objects:
            form = form_object['form']
            module = form_object['module']
            form_name = '{} > {} > {}'.format(application.name, module.name['en'], form.name['en'])
            results.append(Form(form_xmlns=form.xmlns, form_name=form_name))
        return results