Ejemplo n.º 1
0
def overwrite_app(app, master_build, report_map=None, maintain_ids=False):
    excluded_fields = set(Application._meta_fields).union([
        'date_created', 'build_profiles', 'copy_history', 'copy_of', 'name',
        'comment', 'doc_type'
    ])
    master_json = master_build.to_json()
    for key, value in master_json.iteritems():
        if key not in excluded_fields:
            app[key] = value
    app['version'] = master_json['version']
    wrapped_app = wrap_app(app)
    for module in wrapped_app.modules:
        if isinstance(module, ReportModule):
            if report_map is not None:
                for config in module.report_configs:
                    try:
                        config.report_id = report_map[config.report_id]
                    except KeyError:
                        raise AppEditingError('Dynamic UCR used in linked app')
            else:
                raise AppEditingError('Report map not passed to overwrite_app')
    if maintain_ids:
        id_map = _get_form_id_map(app)
        wrapped_app = _update_form_ids(wrapped_app, master_build, id_map)
    wrapped_app.copy_attachments(master_build)
    enable_usercase_if_necessary(wrapped_app)
    wrapped_app.save(increment_version=False)
Ejemplo n.º 2
0
def get_app_by_version(domain, app_id, version):
    app = get_build_doc_by_version(domain, app_id, version)
    if not app:
        raise Exception(
            "No app found with id '{}' and version '{}', on '{}'".format(
                app_id, version, domain))
    return wrap_app(app)
Ejemplo n.º 3
0
    def handle(self, commit, **options):
        logger.setLevel('DEBUG')

        start_date = datetime(2020, 3, 19)  # Initial release of FFX app
        end_date = datetime(2020, 4, 4)  # Release of analytics
        app_query = AppES().term('doc_type', 'Application') \
                           .missing('created_from_template') \
                           .date_range('date_created', gt=start_date, lt=end_date)
        hits = app_query.run().hits
        logger.info(f"Pulled {len(hits)} apps from ES")

        hits = [
            h for h in hits
            if 'FFX' in h['name'] and len(h['modules']) == 9 and (
                not h['family_id'] or h['family_id'] in KNOWN_FAMILY_IDS)
        ]
        logger.info(
            f"Filtered to {len(hits)} apps likely imported from app library")

        for hit in hits:
            app = wrap_app(Application.get_db().get(hit['_id']))
            app.created_from_template = _get_app_id(hit['date_created'])
            if commit:
                app.save(increment_version=False)

        logger.info(
            f"Done with backfill_created_from_template, commit={commit}")
Ejemplo n.º 4
0
def setup_ccz_file_for_hosting(hosted_ccz_id):
    try:
        hosted_ccz = HostedCCZ.objects.get(pk=hosted_ccz_id)
    except HostedCCZ.DoesNotExist:
        return
    version = hosted_ccz.version
    ccz_utility = hosted_ccz.utility
    # set up the file if not already present
    if not ccz_utility.file_exists():
        # profile_id should be None and not any other false value
        profile_id = hosted_ccz.profile_id or None
        build = wrap_app(
            get_build_doc_by_version(hosted_ccz.domain, hosted_ccz.app_id,
                                     version))
        ccz_file = create_files_for_ccz(
            build,
            profile_id,
            download_targeted_version=build.has_commcare_flavor)
        try:
            with open(ccz_file, 'rb') as ccz:
                ccz_utility.store_file_in_blobdb(ccz,
                                                 name=hosted_ccz.file_name)
        except:
            exc = sys.exc_info()
            # delete the file from blob db if it was added but later failed
            hosted_ccz.delete_ccz()
            six.reraise(*exc)
Ejemplo n.º 5
0
def setup_ccz_file_for_hosting(hosted_ccz_id, user_email=None):
    try:
        hosted_ccz = HostedCCZ.objects.get(pk=hosted_ccz_id)
    except HostedCCZ.DoesNotExist:
        return
    hosted_ccz.update_status('building')
    version = hosted_ccz.version
    ccz_utility = hosted_ccz.utility
    # set up the file if not already present
    if not ccz_utility.file_exists():
        # profile_id should be None and not any other false value
        profile_id = hosted_ccz.profile_id or None
        build = wrap_app(
            get_build_doc_by_version(hosted_ccz.domain, hosted_ccz.app_id,
                                     version))
        try:
            ccz_file = create_files_for_ccz(build,
                                            profile_id,
                                            download_targeted_version=bool(
                                                build.commcare_flavor))
            with open(ccz_file, 'rb') as ccz:
                ccz_utility.store_file_in_blobdb(ccz,
                                                 name=hosted_ccz.file_name)
            hosted_ccz.update_status('completed')
        except:
            exc = sys.exc_info()
            hosted_ccz.update_status('failed')
            if user_email:
                _notify_failure_to_user(hosted_ccz, build, user_email)
            # delete the file from blob db if it was added but later failed
            hosted_ccz.delete_ccz()
            six.reraise(*exc)
    else:
        hosted_ccz.update_status('completed')
Ejemplo n.º 6
0
def overwrite_app(app, master_build, report_map=None):
    excluded_fields = set(Application._meta_fields).union([
        'date_created', 'build_profiles', 'copy_history', 'copy_of',
        'name', 'comment', 'doc_type', '_LAZY_ATTACHMENTS', 'practice_mobile_worker_id',
        'custom_base_url'
    ])
    master_json = master_build.to_json()
    app_json = app.to_json()
    id_map = _get_form_id_map(app_json)  # do this before we change the source

    for key, value in six.iteritems(master_json):
        if key not in excluded_fields:
            app_json[key] = value
    app_json['version'] = master_json['version']
    wrapped_app = wrap_app(app_json)
    for module in wrapped_app.get_report_modules():
        if report_map is None:
            raise AppEditingError('Report map not passed to overwrite_app')

        for config in module.report_configs:
            try:
                config.report_id = report_map[config.report_id]
            except KeyError:
                raise AppEditingError(config.report_id)

    wrapped_app = _update_form_ids(wrapped_app, master_build, id_map)
    enable_usercase_if_necessary(wrapped_app)
    return wrapped_app
Ejemplo n.º 7
0
    def _add_overrides_for_build(self, doc):
        linked_build = wrap_app(doc)
        log_prefix = "{}{} app {}, build {}".format(
            "[DRY RUN] " if self.dry_run else "", linked_build.domain,
            linked_build.origin_id, linked_build.get_id)

        if not linked_build.upstream_app_id or not linked_build.upstream_version:
            return

        if not linked_build.domain_link:
            logger.error(
                "{}: Skipping due to missing domain link".format(log_prefix))
            return

        try:
            master_build = get_master_app_by_version(
                linked_build.domain_link, linked_build.upstream_app_id,
                linked_build.upstream_version)
        except ActionNotPermitted:
            logger.error("{}: Skipping due to 403".format(log_prefix))
            return

        if not master_build:
            logger.info(
                "{}: Skipping, no master build found".format(log_prefix))
            return

        linked_map = self._get_xmlns_map(linked_build)
        master_map = self._get_xmlns_map(master_build)
        override_map = {
            master_form_unique_id: linked_map[xmlns]
            for xmlns, master_form_unique_id in master_map.items()
            if xmlns in linked_map
        }

        if not override_map:
            logger.info(
                "{}: Skipping, no forms found to map".format(log_prefix))
            return

        current_overrides = {
            pre_id: override.post_id
            for pre_id, override in get_xform_resource_overrides(
                linked_build.domain, linked_build.origin_id).items()
        }
        if set(override_map.items()) - set(current_overrides.items()):
            logger.info("{}: Found {} overrides, updating with {}".format(
                log_prefix, len(current_overrides), len(override_map)))
            if not self.dry_run:
                try:
                    add_xform_resource_overrides(linked_build.domain,
                                                 linked_build.origin_id,
                                                 override_map)
                except ResourceOverrideError as e:
                    logger.error("{}".format(str(
                        e)))  # skip log_prefix, error message has same info
        else:
            logger.info(
                "{}: Skipping, all {} overrides already present".format(
                    log_prefix, len(override_map)))
Ejemplo n.º 8
0
def get_all_latest_builds_for_user(user):
    app_ids = [(domain, app_id) for domain in user.domains
               for app_id in get_app_ids_in_domain(domain)]
    app_docs = [
        get_latest_released_app_doc(app_id[0], app_id[1]) for app_id in app_ids
    ]
    return [wrap_app(app_doc) for app_doc in app_docs if app_doc is not None]
Ejemplo n.º 9
0
    def handle(self, path, build_slug, **options):
        app_slugs = []
        perfpath = os.path.join(path, '{}-performance.txt'.format(build_slug))
        if os.path.exists(perfpath):
            os.remove(perfpath)

        for name in os.listdir(os.path.join(path, 'src')):
            _JSON = '.json'
            if name.endswith(_JSON):
                app_slugs.append(name[:-len(_JSON)])

        for slug in app_slugs:
            print('Fetching %s...' % slug)
            source_path = os.path.join(path, 'src', '%s.json' % slug)
            with open(source_path, encoding='utf-8') as f:
                j = json.load(f)
                app = wrap_app(j)

            app.version = 1
            if not app.domain:
                app.domain = "test"
            build_path = os.path.join(path, build_slug, slug)
            print(' Creating files...')
            if track_perf:
                with record_performance_stats(perfpath, slug):
                    files = app.create_all_files()
            else:
                files = app.create_all_files()

            self.write_files(files, build_path)
Ejemplo n.º 10
0
def overwrite_app(app, master_build, report_map=None):
    excluded_fields = set(Application._meta_fields).union([
        'date_created', 'build_profiles', 'copy_history', 'copy_of',
        'name', 'comment', 'doc_type', '_LAZY_ATTACHMENTS', 'practice_mobile_worker_id',
        'custom_base_url'
    ])
    master_json = master_build.to_json()
    app_json = app.to_json()
    id_map = _get_form_id_map(app_json)  # do this before we change the source

    for key, value in six.iteritems(master_json):
        if key not in excluded_fields:
            app_json[key] = value
    app_json['version'] = master_json['version']
    wrapped_app = wrap_app(app_json)
    for module in wrapped_app.get_report_modules():
        if report_map is None:
            raise AppEditingError('Report map not passed to overwrite_app')

        for config in module.report_configs:
            try:
                config.report_id = report_map[config.report_id]
            except KeyError:
                raise AppEditingError(config.report_id)

    wrapped_app = _update_form_ids(wrapped_app, master_build, id_map)
    enable_usercase_if_necessary(wrapped_app)
    return wrapped_app
Ejemplo n.º 11
0
def get_master_app_by_version(domain_link, upstream_app_id, upstream_version):
    if domain_link.is_remote:
        app = get_app_by_version(domain_link, upstream_app_id, upstream_version)
    else:
        app = get_build_doc_by_version(domain_link.master_domain, upstream_app_id, upstream_version)

    if app:
        return wrap_app(app)
Ejemplo n.º 12
0
def get_all_latest_builds_for_user(user):
    app_ids = [
        (domain, app_id)
        for domain in user.domains
        for app_id in get_app_ids_in_domain(domain)
    ]
    app_docs = [get_latest_released_app_doc(app_id[0], app_id[1]) for app_id in app_ids]
    return [wrap_app(app_doc) for app_doc in app_docs if app_doc is not None]
Ejemplo n.º 13
0
def overwrite_app(app, master_build, report_map=None):
    excluded_fields = set(Application._meta_fields).union([
        'date_created',
        'build_profiles',
        'copy_history',
        'copy_of',
        'name',
        'comment',
        'doc_type',
        '_LAZY_ATTACHMENTS',
        'practice_mobile_worker_id',
        'custom_base_url',
        'family_id',
    ])
    master_json = master_build.to_json()
    app_json = app.to_json()

    for key, value in master_json.items():
        if key not in excluded_fields:
            app_json[key] = value
    app_json['version'] = app_json.get('version', 1)
    app_json['upstream_version'] = master_json['version']
    app_json['upstream_app_id'] = master_json['copy_of']
    wrapped_app = wrap_app(app_json)
    for module in wrapped_app.get_report_modules():
        if report_map is None:
            raise AppEditingError('Report map not passed to overwrite_app')

        for config in module.report_configs:
            try:
                config.report_id = report_map[config.report_id]
            except KeyError:
                raise AppEditingError(config.report_id)

    # Legacy linked apps have different form unique ids than their master app(s). These mappings
    # are stored as ResourceOverride objects. Look up to see if this app has any.
    from corehq.apps.app_manager.suite_xml.post_process.resources import get_xform_resource_overrides
    overrides = get_xform_resource_overrides(domain=wrapped_app.domain,
                                             app_id=wrapped_app.get_id)
    ids_map = {
        pre_id: override.post_id
        for pre_id, override in overrides.items()
    }
    wrapped_app = _update_forms(wrapped_app, master_build, ids_map)

    # Multimedia versions should be set based on the linked app's versions, not those of the master app.
    for path in wrapped_app.multimedia_map.keys():
        wrapped_app.multimedia_map[path].version = None
    wrapped_app.set_media_versions()

    enable_usercase_if_necessary(wrapped_app)
    return wrapped_app
Ejemplo n.º 14
0
def _update_form_ids(app, master_app, form_ids_by_xmlns):

    _attachments = master_app.get_attachments()

    app_source = app.to_json()
    app_source.pop('external_blobs')
    app_source['_attachments'] = _attachments

    updated_source = update_form_unique_ids(app_source, form_ids_by_xmlns)

    attachments = app_source.pop('_attachments')
    new_wrapped_app = wrap_app(updated_source)
    save = partial(new_wrapped_app.save, increment_version=False)
    return new_wrapped_app.save_attachments(attachments, save)
Ejemplo n.º 15
0
def _update_form_ids(app, master_app, id_map):

    _attachments = master_app.get_attachments()

    app_source = app.to_json()
    app_source.pop('external_blobs')
    app_source['_attachments'] = _attachments

    updated_source = update_form_unique_ids(app_source, id_map)

    attachments = app_source.pop('_attachments')
    new_wrapped_app = wrap_app(updated_source)
    save = partial(new_wrapped_app.save, increment_version=False)
    return new_wrapped_app.save_attachments(attachments, save)
Ejemplo n.º 16
0
def get_report_configs(domain, ls_app_version):
    if ls_app_version:
        app = wrap_app(
            get_build_by_version(domain,
                                 SUPERVISOR_APP_ID,
                                 ls_app_version,
                                 return_doc=True))
    else:
        app = get_app(domain, SUPERVISOR_APP_ID, latest=True)
    return {
        report_config.report_id: report_config
        for module in app.get_report_modules()
        for report_config in module.report_configs
        if report_config.report_id in REPORT_IDS
    }
Ejemplo n.º 17
0
def pull_master_app(request, domain, app_id):
    app = get_current_app_doc(domain, app_id)
    master_app = get_app(None, app['master'])
    latest_master_build = get_app(None, app['master'], latest=True)
    params = {}
    if app['domain'] in master_app.linked_whitelist:
        excluded_fields = set(Application._meta_fields).union([
            'date_created', 'build_profiles', 'copy_history', 'copy_of',
            'name', 'comment', 'doc_type'
        ])
        master_json = latest_master_build.to_json()
        for key, value in master_json.iteritems():
            if key not in excluded_fields:
                app[key] = value
        app['version'] = master_json['version']
        wrapped_app = wrap_app(app)
        mobile_ucrs = False
        for module in wrapped_app.modules:
            if isinstance(module, ReportModule):
                mobile_ucrs = True
                break
        if mobile_ucrs:
            messages.error(
                request,
                _('This linked application uses mobile UCRs '
                  'which are currently not supported. For this application '
                  'to function correctly, you will need to remove those modules '
                  'or revert to a previous version that did not include them.')
            )
        else:
            messages.success(
                request,
                _('Your linked application was successfully updated to the latest version.'
                  ))
        wrapped_app.copy_attachments(latest_master_build)
        wrapped_app.save(increment_version=False)
    else:
        messages.error(
            request,
            _('This project is not authorized to update from the master application. '
              'Please contact the maintainer of the master app if you believe this is a mistake. '
              ))
    return HttpResponseRedirect(
        reverse_util('view_app', params=params, args=[domain, app_id]))
Ejemplo n.º 18
0
def overwrite_app(app, master_build, include_ucrs=False, report_map=None):
    excluded_fields = set(Application._meta_fields).union([
        'date_created', 'build_profiles', 'copy_history', 'copy_of', 'name',
        'comment', 'doc_type'
    ])
    master_json = master_build.to_json()
    for key, value in master_json.iteritems():
        if key not in excluded_fields:
            app[key] = value
    app['version'] = master_json['version']
    wrapped_app = wrap_app(app)
    for module in wrapped_app.modules:
        if isinstance(module, ReportModule):
            if include_ucrs and report_map is not None:
                for config in module.report_configs:
                    config.report_id = report_map[config.report_id]
            else:
                raise AppEditingError()
    wrapped_app.copy_attachments(master_build)
    wrapped_app.save(increment_version=False)
Ejemplo n.º 19
0
def overwrite_app(app, master_build, report_map=None):
    excluded_fields = set(Application._meta_fields).union([
        'date_created', 'build_profiles', 'copy_history', 'copy_of',
        'name', 'comment', 'doc_type', '_LAZY_ATTACHMENTS', 'practice_mobile_worker_id',
        'custom_base_url', 'family_id',
    ])
    master_json = master_build.to_json()
    app_json = app.to_json()

    old_form_ids_by_xmlns = _get_historical_form_ids_by_xmlns(app)  # before updating anything

    for key, value in master_json.items():
        if key not in excluded_fields:
            app_json[key] = value
    app_json['version'] = app_json.get('version', 1)
    app_json['upstream_version'] = master_json['version']
    app_json['upstream_app_id'] = master_json['copy_of']
    wrapped_app = wrap_app(app_json)
    for module in wrapped_app.get_report_modules():
        if report_map is None:
            raise AppEditingError('Report map not passed to overwrite_app')

        for config in module.report_configs:
            try:
                config.report_id = report_map[config.report_id]
            except KeyError:
                raise AppEditingError(config.report_id)

    ids_map = _map_old_form_ids_to_new(wrapped_app, old_form_ids_by_xmlns)
    wrapped_app = _update_form_ids(wrapped_app, master_build, ids_map)

    # Multimedia versions should be set based on the linked app's versions, not those of the master app.
    for path in wrapped_app.multimedia_map.keys():
        wrapped_app.multimedia_map[path].version = None
    wrapped_app.set_media_versions()

    enable_usercase_if_necessary(wrapped_app)
    return wrapped_app
Ejemplo n.º 20
0
    def handle(self, from_domain, from_app_id, to_domain, *args, **options):
        self.from_domain = from_domain
        self.to_domain = to_domain
        to_app_id = options.get('to-app-id')
        version = options.get('version')
        if to_app_id:
            app = get_current_app(self.to_domain, to_app_id)
            print('Overwriting application: {}'.format(app.name))
        else:
            print('Creating new application')
            app = Application()

        if version:
            from_app_doc = get_build_doc_by_version(self.from_domain, from_app_id, version)
        else:
            from_app_doc = get_latest_released_app_doc(self.from_domain, from_app_id)

        if not from_app_doc:
            raise CommandError("From app not found")

        from_app = wrap_app(from_app_doc)
        print('Overwring app with "{}" (version {})'.format(from_app.name, from_app.version))
        overwrite_app(app, from_app, self.report_map)
Ejemplo n.º 21
0
def update_linked_whitelist(request, domain, app_id):
    app = wrap_app(get_current_app_doc(domain, app_id))
    new_whitelist = json.loads(request.POST.get('whitelist'))
    app.linked_whitelist = new_whitelist
    app.save()
    return HttpResponse()
Ejemplo n.º 22
0
def _get_build_functional_version(domain, app_id, version):
    app_build = wrap_app(
        get_build_by_version(domain, app_id, version, return_doc=True))
    return app_build.profile.get('custom_properties',
                                 {}).get('cc-app-version-tag')
Ejemplo n.º 23
0
def _convert_app_from_remote_linking_source(app_json):
    attachments = app_json.pop('_LAZY_ATTACHMENTS', {})
    app = wrap_app(app_json)
    app._LAZY_ATTACHMENTS = attachments
    return app
Ejemplo n.º 24
0
def _convert_app_from_remote_linking_source(app_json):
    attachments = app_json.pop('_LAZY_ATTACHMENTS', {})
    app = wrap_app(app_json)
    app._LAZY_ATTACHMENTS = attachments
    return app
Ejemplo n.º 25
0
def get_brief_apps(domain_link):
    apps = _do_simple_request('linked_domain:brief_apps',
                              domain_link)['brief_apps']
    return [wrap_app(app) for app in apps]