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), }
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)
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
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", ) ) )
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))
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), }
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 __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
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) ), }
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
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
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
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
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']
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
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]
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))
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)
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), }
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) }
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]
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)
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
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
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
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
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)
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
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, }
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), }
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
def get_page_context(cls, domain): return { 'apps': get_brief_apps_in_domain(domain), 'templates': cls.templates(domain), }
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) }
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
def applications(self): return get_brief_apps_in_domain(self.name)
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]
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' }
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 ] }, }
def applications(self): apps = get_brief_apps_in_domain(self.request.domain) apps = sorted(apps, key=lambda item: item.name.lower()) return apps
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))
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)
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]
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]
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)
def applications(self): return get_brief_apps_in_domain(self.request.domain)
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)
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