示例#1
0
 def page_context(self):
     app_names = {app.id: app.name for app in get_brief_apps_in_domain(self.domain, include_remote=True)}
     query = LatestEnabledBuildProfiles.objects
     app_id = self.request.GET.get('app_id')
     if app_id:
         query = query.filter(app_id=app_id)
     else:
         query = query.filter(app_id__in=app_names.keys())
     version = self.request.GET.get('version')
     if version:
         query = query.filter(version=version)
     build_profile_id = self.request.GET.get('build_profile_id')
     if build_profile_id:
         query = query.filter(build_profile_id=build_profile_id)
     status = self.request.GET.get('status')
     if status:
         if status == 'active':
             query = query.filter(active=True)
         elif status == 'inactive':
             query = query.filter(active=False)
     app_releases_by_app_profile = [release.to_json(app_names) for release in query.order_by('-version')]
     return {
         'manage_releases_by_app_profile_form': self.form,
         'app_releases_by_app_profile': app_releases_by_app_profile,
         'selected_build_details': ({'id': version, 'text': version} if version else None),
         'initial_app_profile_details': self._get_initial_app_profile_details(self.domain, version, app_id,
                                                                              build_profile_id),
     }
示例#2
0
 def test_get_brief_apps_exclude_remote(self):
     apps = get_brief_apps_in_domain(self.domain, include_remote=False)
     self.assertEqual(len(apps), 1)
     normal_app, = apps
     expected_normal_app, _ = sorted(self.apps, key=lambda app: app.is_remote_app())
     brief_app = self._make_app_brief(expected_normal_app)
     self.assert_docs_equal(normal_app, brief_app)
示例#3
0
    def page_context(self):
        app_names = {app.id: app.name for app in get_brief_apps_in_domain(self.domain, include_remote=True)}
        q = AppReleaseByLocation.objects.filter(domain=self.domain)
        location_id_slug = self.request.GET.get('location_id')
        location_id = None
        if location_id_slug:
            location_id = self.form.extract_location_id(location_id_slug)
            if location_id:
                q = q.filter(location_id=location_id)
        if self.request.GET.get('app_id'):
            q = q.filter(app_id=self.request.GET.get('app_id'))
        version = self.request.GET.get('version')
        if version:
            q = q.filter(version=version)
        status = self.request.GET.get('status')
        if status:
            if status == 'active':
                q = q.filter(active=True)
            elif status == 'inactive':
                q = q.filter(active=False)

        app_releases_by_location = [release.to_json() for release in q.order_by('-version')]
        for r in app_releases_by_location:
            r['app'] = app_names.get(r['app'], r['app'])
        return {
            'manage_releases_by_location_form': self.form,
            'app_releases_by_location': app_releases_by_location,
            'selected_build_details': ({'id': version, 'text': version} if version else None),
            'selected_location_details': ({'id': location_id_slug,
                                           'text': self._location_path_display(location_id)}
                                          if location_id else None),
        }
    def _form_rows(self, domain):
        time_filter = form_es.submitted
        datespan = DateSpan(datetime.now() - timedelta(days=self.window),
                            datetime.utcnow())
        apps = get_brief_apps_in_domain(domain.name)
        apps = {a.id: a.name for a in apps}

        users_filter = form_es.user_id(
            EMWF.user_es_query(
                domain.name,
                ['t__0'],  # All mobile workers
                self.couch_user).values_list('_id', flat=True))
        query = (form_es.FormES().domain(domain.name).filter(
            time_filter(gte=datespan.startdate,
                        lt=datespan.enddate_adjusted)).filter(users_filter))
        rows = []
        for hit in query.run().hits:
            username = hit['form']['meta']['username']
            submitted = self._format_date(
                datetime.strptime(hit['received_on'][:19],
                                  '%Y-%m-%dT%H:%M:%S'))
            rows.append([
                hit['form']['@name'],
                submitted,
                apps[hit['app_id']] if hit['app_id'] in
                apps else 'App not found',
                username,
            ] + self._domain_properties(domain))
        return rows
示例#5
0
    def __init__(self, domain, *args, **kwargs):
        super(AppTranslationsForm, self).__init__(*args, **kwargs)
        self.domain = domain
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.label_class = 'col-sm-3 col-md-4 col-lg-2'
        self.helper.field_class = 'col-sm-4 col-md-5 col-lg-3'

        self.fields['app_id'].choices = tuple((app.id, app.name) for app in get_brief_apps_in_domain(domain))
        if settings.TRANSIFEX_DETAILS:
            self.fields['transifex_project_slug'].choices = (
                tuple((slug, slug)
                      for slug in settings.TRANSIFEX_DETAILS.get('project').get(domain))
            )
        self.helper.layout = Layout(
            'app_id',
            'version',
            'use_version_postfix',
            'transifex_project_slug',
            'source_lang',
            'target_lang',
            'action',
            'lock_translations',
            'perform_translated_check',
            hqcrispy.FormActions(
                twbscrispy.StrictButton(
                    ugettext_lazy("Submit"),
                    type="submit",
                    css_class="btn btn-primary btn-lg disable-on-submit",
                )
            )
        )
示例#6
0
def _is_remote_app_conversion(domain, app_id, export_type):
    if app_id and export_type == FORM_EXPORT:
        app = get_app(domain, app_id)
        return app.is_remote_app()
    elif export_type == CASE_EXPORT:
        apps = get_brief_apps_in_domain(domain, include_remote=True)
        return any(map(lambda app: app.is_remote_app(), apps))
示例#7
0
    def page_context(self):
        app_names = {app.id: app.name for app in get_brief_apps_in_domain(self.domain, include_remote=True)}
        q = AppReleaseByLocation.objects.filter(domain=self.domain)
        location_id_slug = self.request.GET.get('location_id')
        location_id = None
        if location_id_slug:
            location_id = self.manage_releases_form.extract_location_id(location_id_slug)
            if location_id:
                q = q.filter(location_id=location_id)
        if self.request.GET.get('app_id'):
            q = q.filter(app_id=self.request.GET.get('app_id'))
        version = self.request.GET.get('version')
        if version:
            q = q.filter(version=version)

        app_releases_by_location = [release.to_json() for release in q]
        for r in app_releases_by_location:
            r['app'] = app_names.get(r['app'], r['app'])
        return {
            'manage_releases_form': self.manage_releases_form,
            'app_releases_by_location': app_releases_by_location,
            'selected_build_details': ({'id': version, 'text': version} if version else None),
            'selected_location_details': ({'id': location_id_slug,
                                           'text': self._location_path_display(location_id)}
                                          if location_id else None),
        }
示例#8
0
 def test_get_brief_apps_in_domain(self):
     apps = get_brief_apps_in_domain(self.domain)
     self.assertEqual(len(apps), 2)
     normal_app, remote_app = sorted(apps, key=lambda app: app.is_remote_app())
     expected_normal_app, expected_remote_app = sorted(self.apps, key=lambda app: app.is_remote_app())
     self.assert_docs_equal(remote_app, self._make_app_brief(expected_remote_app))
     self.assert_docs_equal(normal_app, self._make_app_brief(expected_normal_app))
示例#9
0
    def __init__(self, domain, *args, **kwargs):
        super(AddTransifexBlacklistForm, self).__init__(*args, **kwargs)
        self.helper = hqcrispy.HQFormHelper()

        self.fields['app_id'].choices = tuple(
            (app.id, app.name) for app in get_brief_apps_in_domain(domain))
        form_fields = [
            hqcrispy.Field('app_id'),
            hqcrispy.Field('module_id'),
            hqcrispy.Field('field_type'),
            hqcrispy.Field('field_name'),
            hqcrispy.Field('display_text'),
            hqcrispy.Field('domain'),
            hqcrispy.Field('action'),
            hqcrispy.FormActions(
                twbscrispy.StrictButton(
                    ugettext_lazy("Add"),
                    type="submit",
                    css_class="btn-primary disable-on-submit",
                ))
        ]
        self.helper.layout = crispy.Layout(
            crispy.Fieldset(ugettext_lazy("Add translation to blacklist"),
                            *form_fields), )
        self.fields['action'].initial = 'blacklist'
        self.fields['domain'].initial = domain
示例#10
0
 def page_context(self):
     if (not self.can_restrict_access_by_location
         and any(not role.permissions.access_all_locations
                 for role in self.user_roles)
     ):
         messages.warning(self.request, _(
             "This project has user roles that restrict data access by "
             "organization, but the software plan no longer supports that. "
             "Any users assigned to roles that are restricted in data access "
             "by organization can no longer access this project.  Please "
             "update the existing roles."))
     return {
         'user_roles': self.user_roles,
         'can_edit_roles': self.can_edit_roles,
         'default_role': UserRole.get_default(),
         'report_list': get_possible_reports(self.domain),
         'web_apps_list': get_cloudcare_apps(self.domain),
         'apps_list': get_brief_apps_in_domain(self.domain),
         'invitations': self.invitations,
         'requests': DomainRequest.by_domain(self.domain) if self.request.couch_user.is_domain_admin else [],
         'admins': WebUser.get_admins_by_domain(self.domain),
         'domain_object': self.domain_object,
         'uses_locations': self.domain_object.uses_locations,
         'can_restrict_access_by_location': self.can_restrict_access_by_location,
         'landing_page_choices': self.landing_page_choices,
         'show_integration': (
             toggles.OPENMRS_INTEGRATION.enabled(self.domain) or
             toggles.DHIS2_INTEGRATION.enabled(self.domain)
         ),
     }
示例#11
0
    def __init__(self, domain, *args, **kwargs):
        super(AddTransifexBlacklistForm, self).__init__(*args, **kwargs)
        self.helper = hqcrispy.HQFormHelper()

        self.fields['app_id'].choices = tuple((app.id, app.name) for app in get_brief_apps_in_domain(domain))
        form_fields = [
            hqcrispy.Field('app_id'),
            hqcrispy.Field('module_id'),
            hqcrispy.Field('field_type'),
            hqcrispy.Field('field_name'),
            hqcrispy.Field('display_text'),
            hqcrispy.Field('domain'),
            hqcrispy.Field('action'),
            hqcrispy.FormActions(
                twbscrispy.StrictButton(
                    ugettext_lazy("Add"),
                    type="submit",
                    css_class="btn-primary disable-on-submit",
                )
            )
        ]
        self.helper.layout = crispy.Layout(
            crispy.Fieldset(
                ugettext_lazy("Add translation to blacklist"),
                *form_fields
            ),
        )
        self.fields['action'].initial = 'blacklist'
        self.fields['domain'].initial = domain
示例#12
0
    def __init__(self, domain, *args, **kwargs):
        super(AppTranslationsForm, self).__init__(*args, **kwargs)
        self.domain = domain
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.label_class = 'col-sm-4 col-md-4 col-lg-3'
        self.helper.field_class = 'col-sm-6 col-md-6 col-lg-5'

        self.fields['app_id'].choices = tuple(
            (app.id, app.name) for app in get_brief_apps_in_domain(domain))
        projects = TransifexProject.objects.filter(domain=domain).all()
        if projects:
            self.fields['transifex_project_slug'].choices = (tuple(
                (project.slug, project) for project in projects))
        form_fields = self.form_fields()
        form_fields.append(
            hqcrispy.Field(
                StrictButton(
                    ugettext_lazy("Submit"),
                    type="submit",
                    css_class="btn btn-primary btn-lg disable-on-submit",
                    onclick="return confirm('%s')" %
                    ugettext_lazy("Please confirm that you want to proceed?")))
        )
        self.helper.layout = crispy.Layout(*form_fields)
        self.fields['action'].initial = self.form_action
示例#13
0
def _is_remote_app_conversion(domain, app_id, export_type):
    if app_id and export_type == FORM_EXPORT:
        app = get_app(domain, app_id)
        return app.is_remote_app()
    elif export_type == CASE_EXPORT:
        apps = get_brief_apps_in_domain(domain, include_remote=True)
        return any(map(lambda app: app.is_remote_app(), apps))
示例#14
0
    def __init__(self, domain, *args, **kwargs):
        super(AppTranslationsForm, self).__init__(*args, **kwargs)
        self.domain = domain
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.label_class = 'col-sm-4 col-md-4 col-lg-3'
        self.helper.field_class = 'col-sm-6 col-md-6 col-lg-5'

        self.fields['app_id'].choices = tuple((app.id, app.name) for app in get_brief_apps_in_domain(domain))
        projects = TransifexProject.objects.filter(domain=domain).all()
        if projects:
            self.fields['transifex_project_slug'].choices = (
                tuple((project.slug, project) for project in projects)
            )
        form_fields = self.form_fields()
        form_fields.append(hqcrispy.Field(StrictButton(
            ugettext_lazy("Submit"),
            type="submit",
            css_class="btn btn-primary btn-lg disable-on-submit",
            onclick="return confirm('%s')" % ugettext_lazy("Please confirm that you want to proceed?")
        )))
        self.helper.layout = crispy.Layout(
            *form_fields
        )
        self.fields['action'].initial = self.form_action
示例#15
0
    def _get_apps(self, restore_state, restore_user):
        app_aware_sync_app = restore_state.params.app

        if app_aware_sync_app:
            apps = [app_aware_sync_app]
        elif (toggles.ROLE_WEBAPPS_PERMISSIONS.enabled(restore_user.domain)
              and restore_state.params.device_id
              and "WebAppsLogin" in restore_state.params.device_id):
            # Only sync reports for apps the user has access to if this is a restore from webapps
            role = restore_user.get_role(restore_user.domain)
            if role:
                allowed_app_ids = [
                    app['_id']
                    for app in get_brief_apps_in_domain(restore_user.domain)
                    if role.permissions.view_web_app(app)
                ]
                apps = get_apps_by_id(restore_user.domain, allowed_app_ids)
            else:
                # If there is no role, allow access to all apps
                apps = get_apps_in_domain(restore_user.domain,
                                          include_remote=False)
        else:
            apps = get_apps_in_domain(restore_user.domain,
                                      include_remote=False)

        return apps
示例#16
0
def get_master_app_briefs(domain_link, family_id):
    if domain_link.is_remote:
        apps = get_brief_apps(domain_link)
    else:
        apps = get_brief_apps_in_domain(domain_link.master_domain, include_remote=False)

    # Ignore deleted, linked and remote apps
    return [app for app in apps if family_id in [app._id, app.family_id] and app.doc_type == 'Application']
示例#17
0
 def translations_with_app_name(cls, domain):
     blacklisted = TransifexBlacklist.objects.filter(domain=domain).all().values()
     app_ids_to_name = {app.id: app.name for app in get_brief_apps_in_domain(domain)}
     ret = []
     for trans in blacklisted:
         r = trans.copy()
         r['app_name'] = app_ids_to_name.get(trans['app_id'], trans['app_id'])
         ret.append(r)
     return ret
示例#18
0
    def __call__(self, restore_state):
        """
        Generates a report fixture for mobile that can be used by a report module
        """
        restore_user = restore_state.restore_user
        if not toggles.MOBILE_UCR.enabled(restore_user.domain) or not _should_sync(restore_state):
            return []

        if toggles.PREVENT_MOBILE_UCR_SYNC.enabled(restore_user.domain):
            return []

        app_aware_sync_app = restore_state.params.app
        if app_aware_sync_app:
            apps = [app_aware_sync_app]
        elif (
                toggles.ROLE_WEBAPPS_PERMISSIONS.enabled(restore_user.domain)
                and restore_state.params.device_id
                and "WebAppsLogin" in restore_state.params.device_id
        ):
            # Only sync reports for apps the user has access to if this is a restore from webapps
            role = restore_user.get_role(restore_user.domain)
            if role:
                allowed_app_ids = [app['_id'] for app in get_brief_apps_in_domain(restore_user.domain)
                                   if role.permissions.view_web_app(app)]
                apps = get_apps_by_id(restore_user.domain, allowed_app_ids)
            else:
                # If there is no role, allow access to all apps
                apps = get_apps_in_domain(restore_user.domain, include_remote=False)
        else:
            apps = get_apps_in_domain(restore_user.domain, include_remote=False)

        report_configs = [
            report_config
            for app_ in apps
            for module in app_.modules if isinstance(module, ReportModule)
            for report_config in module.report_configs
        ]
        if not report_configs:
            return []

        root = E.fixture(id=self.id, user_id=restore_user.user_id)
        reports_elem = E.reports(last_sync=datetime.utcnow().isoformat())
        for report_config in report_configs:
            try:
                reports_elem.append(self.report_config_to_fixture(report_config, restore_user))
            except ReportConfigurationNotFoundError as err:
                logging.exception('Error generating report fixture: {}'.format(err))
                continue
            except UserReportsError:
                if settings.UNIT_TESTING or settings.DEBUG:
                    raise
            except Exception as err:
                logging.exception('Error generating report fixture: {}'.format(err))
                if settings.UNIT_TESTING or settings.DEBUG:
                    raise
        root.append(reports_elem)
        return [root]
示例#19
0
 def _set_choices(self):
     app_id_choices = tuple(
         (app.id, app.name)
         for app in get_brief_apps_in_domain(self.domain))
     self.fields['from_app_id'].choices = app_id_choices
     self.fields['to_app_id'].choices = app_id_choices
     projects = TransifexProject.objects.filter(domain=self.domain).all()
     if projects:
         self.fields['transifex_project_slug'].choices = (tuple(
             (project.slug, project) for project in projects))
示例#20
0
 def _get_apps(self):
     master_list = {}
     linked_list = {}
     briefs = get_brief_apps_in_domain(self.domain, include_remote=False)
     for brief in briefs:
         if is_linked_app(brief):
             linked_list[brief._id] = brief
         else:
             master_list[brief._id] = brief
     return (master_list, linked_list)
示例#21
0
 def get_context_data(self, **kwargs):
     app_names = {app.id: app.name for app in get_brief_apps_in_domain(self.domain, include_remote=True)}
     return {
         'page_title': self._page_title,
         'hosted_cczs': [h.to_json(app_names) for h in HostedCCZ.objects.filter(link=self.hosted_ccz_link)
                         if h.utility.file_exists()],
         'icds_env': settings.SERVER_ENVIRONMENT in settings.ICDS_ENVS,
         'supporting_list_files': self._get_files_for(DISPLAY_CHOICE_LIST),
         'supporting_footer_files': self._get_files_for(DISPLAY_CHOICE_FOOTER),
     }
示例#22
0
 def _apps_by_id(self):
     def link(app):
         return u'<a href="{}">{}</a>'.format(
             reverse('view_app', args=[self.domain, app.get_id]),
             app.name,
         )
     return {
         app.get_id: link(app)
         for app in get_brief_apps_in_domain(self.domain)
     }
示例#23
0
 def options(self):
     apps_for_domain = get_brief_apps_in_domain(self.domain)
     if settings.SERVER_ENVIRONMENT in settings.ICDS_ENVS:
         return [(app.get_id, _("{name}".format(name=app.name)))
                 for app in apps_for_domain]
     else:
         return [(app.get_id,
                  _("{name} [up to build {version}]".format(
                      name=app.name, version=app.version)))
                 for app in apps_for_domain]
示例#24
0
 def test_get_brief_apps_in_domain(self):
     apps = get_brief_apps_in_domain(self.domain)
     self.assertEqual(len(apps), 2)
     normal_app, remote_app = sorted(apps,
                                     key=lambda app: app.is_remote_app())
     expected_normal_app, expected_remote_app = sorted(
         self.apps, key=lambda app: app.is_remote_app())
     self.assert_docs_equal(remote_app,
                            self._make_app_brief(expected_remote_app))
     self.assert_docs_equal(normal_app,
                            self._make_app_brief(expected_normal_app))
 def test_get_brief_apps_exclude_remote(self):
     apps = get_brief_apps_in_domain(self.domain, include_remote=False)
     self.assertEqual(len(apps), 1)
     normal_app, = apps
     expected_normal_app, _ = sorted(self.apps,
                                     key=lambda app: app.is_remote_app())
     # Since brief apps removes anonymous_cloudcare_hash, a new one gets generated and thus causes
     # a mismatch. Setting it none so we can ignore the difference
     brief_app = self._make_app_brief(expected_normal_app)
     brief_app.anonymous_cloudcare_hash = None
     normal_app.anonymous_cloudcare_hash = None
     self.assert_docs_equal(normal_app, brief_app)
示例#26
0
def get_form_list(domain):
    form_list = []
    briefs = get_brief_apps_in_domain(domain)
    for brief in sorted(briefs, key=lambda b: b.name):
        latest_app = get_app(domain, brief.id, latest=True)
        if not is_remote_app(latest_app):
            for m in latest_app.get_modules():
                for f in m.get_forms():
                    form_list.append({
                        "code": get_combined_id(latest_app.origin_id, f.unique_id),
                        "name": f.full_path_name,
                    })
    return form_list
示例#27
0
 def translations_with_app_name(cls, domain):
     blacklisted = TransifexBlacklist.objects.filter(
         domain=domain).all().values()
     app_ids_to_name = {
         app.id: app.name
         for app in get_brief_apps_in_domain(domain)
     }
     ret = []
     for trans in blacklisted:
         r = trans.copy()
         r['app_name'] = app_ids_to_name.get(trans['app_id'],
                                             trans['app_id'])
         ret.append(r)
     return ret
示例#28
0
 def rows_for_domain(self, domain_obj):
     apps = get_brief_apps_in_domain(domain_obj.name)
     apps = {a.id: a.name for a in apps}
     rows = []
     for hit in self.hits(domain_obj.name):
         username = hit['form']['meta']['username']
         submitted = self.format_date(datetime.strptime(hit['received_on'][:19], '%Y-%m-%dT%H:%M:%S'))
         rows.append([
             hit['form']['@name'],
             submitted,
             apps[hit['app_id']] if hit['app_id'] in apps else _('App not found'),
             username,
         ] + self.domain_properties(domain_obj))
     return rows
示例#29
0
def get_upstream_and_downstream_apps(domain):
    """
    Return 2 lists of app_briefs
    The upstream_list contains apps that originated in the specified domain
    The downstream_list contains apps that have been pulled from a domain upstream of the specified domain
    """
    upstream_list = {}
    downstream_list = {}
    briefs = get_brief_apps_in_domain(domain, include_remote=False)
    for brief in briefs:
        if is_linked_app(brief):
            downstream_list[brief._id] = brief
        else:
            upstream_list[brief._id] = brief
    return upstream_list, downstream_list
示例#30
0
    def test_get_brief_apps_in_domain(self):
        apps = get_brief_apps_in_domain(self.domain)
        self.assertEqual(len(apps), 3)
        normal_app = list(filter(
            lambda app: not app.is_remote_app() and app.doc_type != 'LinkedApplication', apps
        ))[0]
        linked_app = list(filter(lambda app: app.doc_type == 'LinkedApplication', apps))[0]
        remote_app = list(filter(lambda app: app.is_remote_app(), apps))[0]

        brief_normal_app = self._make_app_brief(self.normal_app)
        brief_remote = self._make_app_brief(self.remote_app)
        brief_linked_app = self._make_app_brief(self.linked_app)

        self.assert_docs_equal(normal_app, brief_normal_app)
        self.assert_docs_equal(remote_app, brief_remote)
        self.assert_docs_equal(linked_app, brief_linked_app)
示例#31
0
 def rows_for_domain(self, domain_obj):
     apps = get_brief_apps_in_domain(domain_obj.name)
     apps = {a.id: a.name for a in apps}
     rows = []
     for hit in self.hits(domain_obj.name):
         username = hit['form']['meta']['username']
         submitted = self.format_date(
             datetime.strptime(hit['received_on'][:19],
                               '%Y-%m-%dT%H:%M:%S'))
         rows.append([
             hit['form']['@name'],
             submitted,
             apps[hit['app_id']] if hit['app_id'] in
             apps else _('App not found'),
             username,
         ] + self.domain_properties(domain_obj))
     return rows
示例#32
0
 def page_context(self):
     apps_names = {}
     build_profiles_per_app = {}
     for app in get_brief_apps_in_domain(self.domain, include_remote=True):
         apps_names[app.id] = app.name
         build_profiles_per_app[app.id] = app.build_profiles
     query = LatestEnabledBuildProfiles.objects
     app_id = self.request.GET.get('app_id')
     if app_id:
         query = query.filter(app_id=app_id)
     else:
         query = query.filter(app_id__in=apps_names.keys())
     version = self.request.GET.get('version')
     if version:
         query = query.filter(version=version)
     app_build_profile_id = self.request.GET.get('app_build_profile_id')
     if app_build_profile_id:
         query = query.filter(build_profile_id=app_build_profile_id)
     status = self.request.GET.get('status')
     if status:
         if status == 'active':
             query = query.filter(active=True)
         elif status == 'inactive':
             query = query.filter(active=False)
     app_releases_by_app_profile = [
         release.to_json(apps_names)
         for release in query.order_by('-version')
     ]
     return {
         'creation_form':
         self.creation_form,
         'search_form':
         SearchManageReleasesByAppProfileForm(self.request, self.domain),
         'app_releases_by_app_profile':
         app_releases_by_app_profile,
         'selected_build_details': ({
             'id': version,
             'text': version
         } if version else None),
         'initial_app_build_profile_details':
         self._get_initial_app_build_profile_details(
             build_profiles_per_app, app_id, app_build_profile_id),
         'build_profiles_per_app':
         build_profiles_per_app,
     }
示例#33
0
 def get_context_data(self, **kwargs):
     app_names = {app.id: app.name for app in get_brief_apps_in_domain(self.domain, include_remote=True)}
     if self.request.GET.get('link_id'):
         hosted_cczs = HostedCCZ.objects.filter(link_id=self.request.GET.get('link_id'))
     else:
         hosted_cczs = HostedCCZ.objects.filter(link__domain=self.domain)
     if self.request.GET.get('app_id'):
         hosted_cczs = hosted_cczs.filter(app_id=self.request.GET.get('app_id'))
     version = self.request.GET.get('version')
     if version:
         hosted_cczs = hosted_cczs.filter(version=self.request.GET.get('version'))
     if self.request.GET.get('profile_id'):
         hosted_cczs = hosted_cczs.filter(profile_id=self.request.GET.get('profile_id'))
     hosted_cczs = [h.to_json(app_names) for h in hosted_cczs]
     return {
         'form': self.form,
         'domain': self.domain,
         'hosted_cczs': hosted_cczs,
         'selected_build_details': ({'id': version, 'text': version} if version else None),
         'initial_app_profile_details': self._get_initial_app_profile_details(version),
     }
示例#34
0
    def _get_apps(self, restore_state, restore_user):
        app_aware_sync_app = restore_state.params.app

        if app_aware_sync_app:
            apps = [app_aware_sync_app]
        elif (
                toggles.ROLE_WEBAPPS_PERMISSIONS.enabled(restore_user.domain)
                and restore_state.params.device_id
                and "WebAppsLogin" in restore_state.params.device_id
        ):
            # Only sync reports for apps the user has access to if this is a restore from webapps
            role = restore_user.get_role(restore_user.domain)
            if role:
                allowed_app_ids = [app['_id'] for app in get_brief_apps_in_domain(restore_user.domain)
                                   if role.permissions.view_web_app(app)]
                apps = get_apps_by_id(restore_user.domain, allowed_app_ids)
            else:
                # If there is no role, allow access to all apps
                apps = get_apps_in_domain(restore_user.domain, include_remote=False)
        else:
            apps = get_apps_in_domain(restore_user.domain, include_remote=False)

        return apps
示例#35
0
 def get_page_context(cls, domain):
     return {
         'apps': get_brief_apps_in_domain(domain),
         'templates': cls.templates(domain),
     }
示例#36
0
 def linked_app_names(self, domain):
     return {
         app._id: app.name
         for app in get_brief_apps_in_domain(domain) if is_linked_app(app)
     }
示例#37
0
    def save_copy(self, new_domain_name=None, new_hr_name=None, user=None,
                  copy_by_id=None, share_reminders=True,
                  share_user_roles=True):
        from corehq.apps.app_manager.dbaccessors import get_app
        from corehq.apps.reminders.models import CaseReminderHandler
        from corehq.apps.fixtures.models import FixtureDataItem
        from corehq.apps.app_manager.dbaccessors import get_brief_apps_in_domain
        from corehq.apps.domain.dbaccessors import get_doc_ids_in_domain_by_class
        from corehq.apps.fixtures.models import FixtureDataType
        from corehq.apps.users.models import UserRole

        db = Domain.get_db()
        new_id = db.copy_doc(self.get_id)['id']
        if new_domain_name is None:
            new_domain_name = new_id

        with CriticalSection(['request_domain_name_{}'.format(new_domain_name)]):
            new_domain_name = Domain.generate_name(new_domain_name)
            new_domain = Domain.get(new_id)
            new_domain.name = new_domain_name
            new_domain.hr_name = new_hr_name
            new_domain.copy_history = self.get_updated_history()
            new_domain.is_snapshot = False
            new_domain.snapshot_time = None
            new_domain.organization = None  # TODO: use current user's organization (?)

            # reset stuff
            new_domain.cda.signed = False
            new_domain.cda.date = None
            new_domain.cda.type = None
            new_domain.cda.user_id = None
            new_domain.cda.user_ip = None
            new_domain.is_test = "none"
            new_domain.internal = InternalProperties()
            new_domain.creating_user = user.username if user else None

            for field in self._dirty_fields:
                if hasattr(new_domain, field):
                    delattr(new_domain, field)

            new_app_components = {}  # a mapping of component's id to its copy

            def copy_data_items(old_type_id, new_type_id):
                for item in FixtureDataItem.by_data_type(self.name, old_type_id):
                    comp = self.copy_component(
                        item.doc_type, item._id, new_domain_name, user=user)
                    comp.data_type_id = new_type_id
                    comp.save()

            def get_latest_app_id(doc_id):
                app = get_app(self.name, doc_id).get_latest_saved()
                if app:
                    return app._id, app.doc_type

            for app in get_brief_apps_in_domain(self.name):
                doc_id, doc_type = app.get_id, app.doc_type
                original_doc_id = doc_id
                if copy_by_id and doc_id not in copy_by_id:
                    continue
                if not self.is_snapshot:
                    doc_id, doc_type = get_latest_app_id(doc_id) or (doc_id, doc_type)
                component = self.copy_component(doc_type, doc_id, new_domain_name, user=user)
                if component:
                    new_app_components[original_doc_id] = component

            for doc_id in get_doc_ids_in_domain_by_class(self.name, FixtureDataType):
                if copy_by_id and doc_id not in copy_by_id:
                    continue
                component = self.copy_component(
                    'FixtureDataType', doc_id, new_domain_name, user=user)
                copy_data_items(doc_id, component._id)

            if share_reminders:
                for doc_id in get_doc_ids_in_domain_by_class(self.name, CaseReminderHandler):
                    self.copy_component(
                        'CaseReminderHandler', doc_id, new_domain_name, user=user)
            if share_user_roles:
                for doc_id in get_doc_ids_in_domain_by_class(self.name, UserRole):
                    self.copy_component('UserRole', doc_id, new_domain_name, user=user)

            new_domain.save()

        if user:
            def add_dom_to_user(user):
                user.add_domain_membership(new_domain_name, is_admin=True)
            apply_update(user, add_dom_to_user)

        def update_events(handler):
            """
            Change the form_unique_id to the proper form for each event in a newly copied CaseReminderHandler
            """
            from corehq.apps.app_manager.models import FormBase
            for event in handler.events:
                if not event.form_unique_id:
                    continue
                form = FormBase.get_form(event.form_unique_id)
                form_app = form.get_app()
                m_index, f_index = form_app.get_form_location(form.unique_id)
                form_copy = new_app_components[form_app._id].get_module(m_index).get_form(f_index)
                event.form_unique_id = form_copy.unique_id

        def update_for_copy(handler):
            handler.active = False
            update_events(handler)

        if share_reminders:
            for handler in CaseReminderHandler.get_handlers(new_domain_name):
                apply_update(handler, update_for_copy)

        return new_domain
示例#38
0
 def applications(self):
     return get_brief_apps_in_domain(self.name)
示例#39
0
 def options(self):
     apps_for_domain = get_brief_apps_in_domain(self.domain)
     return [(app.get_id, _("%(name)s [up to build %(version)s]") % {
         'name': app.name,
         'version': app.version}) for app in apps_for_domain]
示例#40
0
 def linked_app_names(self, domain):
     return {
         app._id: app.name for app in get_brief_apps_in_domain(domain)
         if app.doc_type == 'LinkedApplication'
     }
示例#41
0
    def page_context(self):
        timezone = get_timezone_for_request()

        def _link_context(link, timezone=timezone):
            return {
                'linked_domain': link.linked_domain,
                'master_domain': link.qualified_master,
                'remote_base_url': link.remote_base_url,
                'is_remote': link.is_remote,
                'last_update': server_to_user_time(link.last_pull, timezone) if link.last_pull else 'Never',
            }

        model_status = []
        linked_models = dict(LINKED_MODELS)
        master_link = get_domain_master_link(self.domain)
        if master_link:
            linked_apps = {
                app._id: app for app in get_brief_apps_in_domain(self.domain)
                if app.doc_type == 'LinkedApplication'
            }
            models_seen = set()
            history = DomainLinkHistory.objects.filter(link=master_link).annotate(row_number=RawSQL(
                'row_number() OVER (PARTITION BY model, model_detail ORDER BY date DESC)',
                []
            ))
            for action in history:
                models_seen.add(action.model)
                if action.row_number != 1:
                    # first row is the most recent
                    continue
                name = linked_models[action.model]
                update = {
                    'type': action.model,
                    'name': name,
                    'last_update': server_to_user_time(action.date, timezone),
                    'detail': action.model_detail,
                    'can_update': True
                }
                if action.model == 'app':
                    app_name = 'Unknown App'
                    if action.model_detail:
                        detail = action.wrapped_detail
                        app = linked_apps.pop(detail.app_id, None)
                        app_name = app.name if app else detail.app_id
                        if app:
                            update['detail'] = action.model_detail
                        else:
                            update['can_update'] = False
                    else:
                        update['can_update'] = False
                    update['name'] = '{} ({})'.format(name, app_name)
                model_status.append(update)

            # Add in models that have never been synced
            for model, name in LINKED_MODELS:
                if model not in models_seen and model != 'app':
                    model_status.append({
                        'type': model,
                        'name': name,
                        'last_update': ugettext('Never'),
                        'detail': None,
                        'can_update': True
                    })

            # Add in apps that have never been synced
            if linked_apps:
                for app in linked_apps.values():
                    update = {
                        'type': 'app',
                        'name': '{} ({})'.format(linked_models['app'], app.name),
                        'last_update': None,
                        'detail': AppLinkDetail(app_id=app._id).to_json(),
                        'can_update': True
                    }
                    model_status.append(update)

        return {
            'domain': self.domain,
            'timezone': timezone.localize(datetime.utcnow()).tzname(),
            'view_data': {
                'master_link': _link_context(master_link) if master_link else None,
                'model_status': sorted(model_status, key=lambda m: m['name']),
                'linked_domains': [
                    _link_context(link) for link in get_linked_domains(self.domain)
                ],
                'models': [
                    {'slug': model[0], 'name': model[1]}
                    for model in LINKED_MODELS
                ]
            },
        }
示例#42
0
 def applications(self):
     apps = get_brief_apps_in_domain(self.request.domain)
     apps = sorted(apps, key=lambda item: item.name.lower())
     return apps
示例#43
0
 def test_get_brief_apps_exclude_remote(self):
     apps = get_brief_apps_in_domain(self.domain, include_remote=False)
     self.assertEqual(len(apps), 1)
     normal_app, = apps
     expected_normal_app, _ = sorted(self.apps, key=lambda app: app.is_remote_app())
     self.assert_docs_equal(normal_app, self._make_app_brief(expected_normal_app))
示例#44
0
    def get(self, request, domain, urlPath):
        try:
            preview = string_to_boolean(request.GET.get("preview", "false"))
        except ValueError:
            # this is typically only set at all if it's intended to be true so this
            # is a reasonable default for "something went wrong"
            preview = True

        app_access = ApplicationAccess.get_by_domain(domain)
        accessor = CaseAccessors(domain)

        if not preview:
            apps = get_cloudcare_apps(domain)
            if request.project.use_cloudcare_releases:

                if (toggles.CLOUDCARE_LATEST_BUILD.enabled(domain) or
                        toggles.CLOUDCARE_LATEST_BUILD.enabled(request.couch_user.username)):
                    get_cloudcare_app = get_latest_build_doc
                else:
                    get_cloudcare_app = get_latest_released_app_doc

                apps = map(
                    lambda app: get_cloudcare_app(domain, app['_id']),
                    apps,
                )
                apps = filter(None, apps)
                apps = map(wrap_app, apps)

                # convert to json
                apps = [get_app_json(app) for app in apps]
            else:
                # legacy functionality - use the latest build regardless of stars
                apps = [get_latest_build_doc(domain, app['_id']) for app in apps]
                apps = [get_app_json(ApplicationBase.wrap(app)) for app in apps if app]

        else:
            # big TODO: write a new apps view for Formplayer, can likely cut most out now
            if toggles.USE_FORMPLAYER_FRONTEND.enabled(domain):
                apps = get_cloudcare_apps(domain)
            else:
                apps = get_brief_apps_in_domain(domain)
            apps = [get_app_json(app) for app in apps if app and (
                isinstance(app, RemoteApp) or app.application_version == V2)]
            meta = get_meta(request)
            track_clicked_preview_on_hubspot(request.couch_user, request.COOKIES, meta)

        # trim out empty apps
        apps = filter(lambda app: app, apps)
        apps = filter(lambda app: app_access.user_can_access_app(request.couch_user, app), apps)

        def _default_lang():
            if apps:
                # unfortunately we have to go back to the DB to find this
                return Application.get(apps[0]["_id"]).default_language
            else:
                return "en"

        # default language to user's preference, followed by
        # first app's default, followed by english
        language = request.couch_user.language or _default_lang()

        def _url_context():
            # given a url path, returns potentially the app, parent, and case, if
            # they're selected. the front end optimizes with these to avoid excess
            # server calls

            # there's an annoying dependency between this logic and backbone's
            # url routing that seems hard to solve well. this needs to be synced
            # with apps.js if anything changes

            # for apps anything with "view/app/" works

            # for cases it will be:
            # "view/:app/:module/:form/case/:case/"

            # if there are parent cases, it will be:
            # "view/:app/:module/:form/parent/:parent/case/:case/

            # could use regex here but this is actually simpler with the potential
            # absence of a trailing slash
            split = urlPath.split('/')
            app_id = split[1] if len(split) >= 2 else None

            if len(split) >= 5 and split[4] == "parent":
                parent_id = split[5]
                case_id = split[7] if len(split) >= 7 else None
            else:
                parent_id = None
                case_id = split[5] if len(split) >= 6 else None

            app = None
            if app_id:
                if app_id in [a['_id'] for a in apps]:
                    app = look_up_app_json(domain, app_id)
                else:
                    messages.info(request, _("That app is no longer valid. Try using the "
                                             "navigation links to select an app."))
            if app is None and len(apps) == 1:
                app = look_up_app_json(domain, apps[0]['_id'])

            def _get_case(domain, case_id):
                case = accessor.get_case(case_id)
                assert case.domain == domain, "case %s not in %s" % (case_id, domain)
                return case.to_api_json()

            case = _get_case(domain, case_id) if case_id else None
            if parent_id is None and case is not None:
                parent_id = case.get('indices', {}).get('parent', {}).get('case_id', None)
            parent = _get_case(domain, parent_id) if parent_id else None

            return {
                "app": app,
                "case": case,
                "parent": parent
            }

        context = {
            "domain": domain,
            "language": language,
            "apps": apps,
            "apps_raw": apps,
            "preview": preview,
            "maps_api_key": settings.GMAPS_API_KEY,
            "sessions_enabled": request.couch_user.is_commcare_user(),
            "use_cloudcare_releases": request.project.use_cloudcare_releases,
            "username": request.user.username,
            "formplayer_url": settings.FORMPLAYER_URL,
            'use_sqlite_backend': use_sqlite_backend(domain),
        }
        context.update(_url_context())
        if toggles.USE_FORMPLAYER_FRONTEND.enabled(domain):
            return render(request, "cloudcare/formplayer_home.html", context)
        else:
            return render(request, "cloudcare/cloudcare_home.html", context)
示例#45
0
 def options(self):
     apps_for_domain = get_brief_apps_in_domain(self.domain)
     return [(app.get_id, _("%(name)s [up to build %(version)s]") % {
         'name': app.name,
         'version': app.version
     }) for app in apps_for_domain]
示例#46
0
def get_cloudcare_apps(domain):
    apps = get_brief_apps_in_domain(domain, include_remote=False)
    return [app for app in apps if app.cloudcare_enabled]
示例#47
0
    def get(self, request, domain, urlPath):
        try:
            preview = string_to_boolean(request.GET.get("preview", "false"))
        except ValueError:
            # this is typically only set at all if it's intended to be true so this
            # is a reasonable default for "something went wrong"
            preview = True

        app_access = ApplicationAccess.get_by_domain(domain)
        accessor = CaseAccessors(domain)

        if not preview:
            apps = get_cloudcare_apps(domain)
            if request.project.use_cloudcare_releases:

                if (toggles.CLOUDCARE_LATEST_BUILD.enabled(domain)
                        or toggles.CLOUDCARE_LATEST_BUILD.enabled(
                            request.couch_user.username)):
                    get_cloudcare_app = get_latest_build_doc
                else:
                    get_cloudcare_app = get_latest_released_app_doc

                apps = map(
                    lambda app: get_cloudcare_app(domain, app['_id']),
                    apps,
                )
                apps = filter(None, apps)
                apps = map(wrap_app, apps)

                # convert to json
                apps = [get_app_json(app) for app in apps]
            else:
                # legacy functionality - use the latest build regardless of stars
                apps = [
                    get_latest_build_doc(domain, app['_id']) for app in apps
                ]
                apps = [
                    get_app_json(ApplicationBase.wrap(app)) for app in apps
                    if app
                ]

        else:
            # big TODO: write a new apps view for Formplayer, can likely cut most out now
            if toggles.USE_FORMPLAYER_FRONTEND.enabled(domain):
                apps = get_cloudcare_apps(domain)
            else:
                apps = get_brief_apps_in_domain(domain)
            apps = [
                get_app_json(app) for app in apps if app and
                (isinstance(app, RemoteApp) or app.application_version == V2)
            ]
            meta = get_meta(request)
            track_clicked_preview_on_hubspot(request.couch_user,
                                             request.COOKIES, meta)

        # trim out empty apps
        apps = filter(lambda app: app, apps)
        apps = filter(
            lambda app: app_access.user_can_access_app(request.couch_user, app
                                                       ), apps)

        def _default_lang():
            if apps:
                # unfortunately we have to go back to the DB to find this
                return Application.get(apps[0]["_id"]).default_language
            else:
                return "en"

        # default language to user's preference, followed by
        # first app's default, followed by english
        language = request.couch_user.language or _default_lang()

        def _url_context():
            # given a url path, returns potentially the app, parent, and case, if
            # they're selected. the front end optimizes with these to avoid excess
            # server calls

            # there's an annoying dependency between this logic and backbone's
            # url routing that seems hard to solve well. this needs to be synced
            # with apps.js if anything changes

            # for apps anything with "view/app/" works

            # for cases it will be:
            # "view/:app/:module/:form/case/:case/"

            # if there are parent cases, it will be:
            # "view/:app/:module/:form/parent/:parent/case/:case/

            # could use regex here but this is actually simpler with the potential
            # absence of a trailing slash
            split = urlPath.split('/')
            app_id = split[1] if len(split) >= 2 else None

            if len(split) >= 5 and split[4] == "parent":
                parent_id = split[5]
                case_id = split[7] if len(split) >= 7 else None
            else:
                parent_id = None
                case_id = split[5] if len(split) >= 6 else None

            app = None
            if app_id:
                if app_id in [a['_id'] for a in apps]:
                    app = look_up_app_json(domain, app_id)
                else:
                    messages.info(
                        request,
                        _("That app is no longer valid. Try using the "
                          "navigation links to select an app."))
            if app is None and len(apps) == 1:
                app = look_up_app_json(domain, apps[0]['_id'])

            def _get_case(domain, case_id):
                case = accessor.get_case(case_id)
                assert case.domain == domain, "case %s not in %s" % (case_id,
                                                                     domain)
                return case.to_api_json()

            case = _get_case(domain, case_id) if case_id else None
            if parent_id is None and case is not None:
                parent_id = case.get('indices',
                                     {}).get('parent',
                                             {}).get('case_id', None)
示例#48
0
 def applications(self):
     return get_brief_apps_in_domain(self.request.domain)
示例#49
0
    def get(self, request, domain, urlPath):
        try:
            preview = string_to_boolean(request.REQUEST.get("preview", "false"))
        except ValueError:
            # this is typically only set at all if it's intended to be true so this
            # is a reasonable default for "something went wrong"
            preview = True

        app_access = ApplicationAccess.get_by_domain(domain)

        if not preview:
            apps = get_cloudcare_apps(domain)
            if request.project.use_cloudcare_releases:
                # replace the apps with the last starred build of each app, removing the ones that aren't starred
                apps = filter(
                    lambda app: app.is_released,
                    [get_app(domain, app['_id'], latest=True) for app in apps]
                )
                # convert to json
                apps = [get_app_json(app) for app in apps]
            else:
                # legacy functionality - use the latest build regardless of stars
                apps = [get_latest_build_doc(domain, app['_id']) for app in apps]
                apps = [get_app_json(ApplicationBase.wrap(app)) for app in apps if app]

        else:
            apps = get_brief_apps_in_domain(domain)
            apps = [get_app_json(app) for app in apps if app and app.application_version == V2]

        # trim out empty apps
        apps = filter(lambda app: app, apps)
        apps = filter(lambda app: app_access.user_can_access_app(request.couch_user, app), apps)

        def _default_lang():
            if apps:
                # unfortunately we have to go back to the DB to find this
                return Application.get(apps[0]["_id"]).build_langs[0]
            else:
                return "en"

        # default language to user's preference, followed by
        # first app's default, followed by english
        language = request.couch_user.language or _default_lang()

        def _url_context():
            # given a url path, returns potentially the app, parent, and case, if
            # they're selected. the front end optimizes with these to avoid excess
            # server calls

            # there's an annoying dependency between this logic and backbone's
            # url routing that seems hard to solve well. this needs to be synced
            # with apps.js if anything changes

            # for apps anything with "view/app/" works

            # for cases it will be:
            # "view/:app/:module/:form/case/:case/"

            # if there are parent cases, it will be:
            # "view/:app/:module/:form/parent/:parent/case/:case/

            # could use regex here but this is actually simpler with the potential
            # absence of a trailing slash
            split = urlPath.split('/')
            app_id = split[1] if len(split) >= 2 else None

            if len(split) >= 5 and split[4] == "parent":
                parent_id = split[5]
                case_id = split[7] if len(split) >= 7 else None
            else:
                parent_id = None
                case_id = split[5] if len(split) >= 6 else None

            app = None
            if app_id:
                if app_id in [a['_id'] for a in apps]:
                    app = look_up_app_json(domain, app_id)
                else:
                    messages.info(request, _("That app is no longer valid. Try using the "
                                             "navigation links to select an app."))
            if app is None and len(apps) == 1:
                app = look_up_app_json(domain, apps[0]['_id'])

            def _get_case(domain, case_id):
                case = CommCareCase.get(case_id)
                assert case.domain == domain, "case %s not in %s" % (case_id, domain)
                return case.get_json()

            case = _get_case(domain, case_id) if case_id else None
            if parent_id is None and case is not None:
                parent_id = case.get('indices', {}).get('parent', {}).get('case_id', None)
            parent = _get_case(domain, parent_id) if parent_id else None

            return {
                "app": app,
                "case": case,
                "parent": parent
            }

        context = {
            "domain": domain,
            "language": language,
            "apps": apps,
            "apps_raw": apps,
            "preview": preview,
            "maps_api_key": settings.GMAPS_API_KEY,
            "offline_enabled": toggles.OFFLINE_CLOUDCARE.enabled(request.user.username),
            "sessions_enabled": request.couch_user.is_commcare_user(),
            "use_cloudcare_releases": request.project.use_cloudcare_releases,
            "username": request.user.username,
        }
        context.update(_url_context())
        return render(request, "cloudcare/cloudcare_home.html", context)
示例#50
0
    def save_copy(self, new_domain_name=None, new_hr_name=None, user=None,
                  copy_by_id=None, share_reminders=True,
                  share_user_roles=True):
        from corehq.apps.app_manager.dbaccessors import get_app
        from corehq.apps.data_interfaces.models import AutomaticUpdateRule
        from corehq.apps.fixtures.models import FixtureDataItem
        from corehq.apps.app_manager.dbaccessors import get_brief_apps_in_domain
        from corehq.apps.domain.dbaccessors import get_doc_ids_in_domain_by_class
        from corehq.apps.fixtures.models import FixtureDataType
        from corehq.apps.users.models import UserRole

        db = Domain.get_db()
        new_id = db.copy_doc(self.get_id)['id']
        if new_domain_name is None:
            new_domain_name = new_id

        with CriticalSection(['request_domain_name_{}'.format(new_domain_name)]):
            new_domain_name = Domain.generate_name(new_domain_name)
            new_domain = Domain.get(new_id)
            new_domain.name = new_domain_name
            new_domain.hr_name = new_hr_name
            new_domain.copy_history = self.get_updated_history()
            new_domain.is_snapshot = False
            new_domain.snapshot_time = None
            new_domain.organization = None  # TODO: use current user's organization (?)

            # reset stuff
            new_domain.cda.signed = False
            new_domain.cda.date = None
            new_domain.cda.type = None
            new_domain.cda.user_id = None
            new_domain.cda.user_ip = None
            new_domain.is_test = "none"
            new_domain.internal = InternalProperties()
            new_domain.creating_user = user.username if user else None
            new_domain.date_created = datetime.utcnow()
            new_domain.use_sql_backend = True
            new_domain.granted_messaging_access = False

            for field in self._dirty_fields:
                if hasattr(new_domain, field):
                    delattr(new_domain, field)

            # Saving the domain should happen before we import any apps since
            # importing apps can update the domain object (for example, if user
            # as a case needs to be enabled)
            try:
                new_domain.save()
            except PreconditionFailed:
                # This is a hack to resolve http://manage.dimagi.com/default.asp?241492
                # Following solution in
                # https://github.com/dimagi/commcare-hq/commit/d59b1e403060ade599cc4a03db0aabc4da62b668
                time.sleep(0.5)
                new_domain.save()

            new_app_components = {}  # a mapping of component's id to its copy

            def copy_data_items(old_type_id, new_type_id):
                for item in FixtureDataItem.by_data_type(self.name, old_type_id):
                    comp = self.copy_component(
                        item.doc_type, item._id, new_domain_name, user=user)
                    comp.data_type_id = new_type_id
                    comp.save()

            def get_latest_app_id(doc_id):
                app = get_app(self.name, doc_id).get_latest_saved()
                if app:
                    return app._id, app.doc_type

            for app in get_brief_apps_in_domain(self.name):
                doc_id, doc_type = app.get_id, app.doc_type
                original_doc_id = doc_id
                if copy_by_id and doc_id not in copy_by_id:
                    continue
                if not self.is_snapshot:
                    doc_id, doc_type = get_latest_app_id(doc_id) or (doc_id, doc_type)
                component = self.copy_component(doc_type, doc_id, new_domain_name, user=user)
                if component:
                    new_app_components[original_doc_id] = component

            for doc_id in get_doc_ids_in_domain_by_class(self.name, FixtureDataType):
                if copy_by_id and doc_id not in copy_by_id:
                    continue
                component = self.copy_component(
                    'FixtureDataType', doc_id, new_domain_name, user=user)
                copy_data_items(doc_id, component._id)

            def convert_form_unique_id_function(form_unique_id):
                from corehq.apps.app_manager.models import FormBase
                form = FormBase.get_form(form_unique_id)
                form_app = form.get_app()
                m_index, f_index = form_app.get_form_location(form.unique_id)
                form_copy = new_app_components[form_app._id].get_module(m_index).get_form(f_index)
                return form_copy.unique_id

            if share_reminders:
                for rule in AutomaticUpdateRule.by_domain(
                    self.name,
                    AutomaticUpdateRule.WORKFLOW_SCHEDULING,
                    active_only=False,
                ):
                    rule.copy_conditional_alert(
                        new_domain_name,
                        convert_form_unique_id_function=convert_form_unique_id_function,
                    )
            if share_user_roles:
                for doc_id in get_doc_ids_in_domain_by_class(self.name, UserRole):
                    self.copy_component('UserRole', doc_id, new_domain_name, user=user)

        if user:
            def add_dom_to_user(user):
                user.add_domain_membership(new_domain_name, is_admin=True)
            apply_update(user, add_dom_to_user)

        return new_domain