Example #1
0
    def get(self, request, *args, **kwargs):
        error_response = self.check_before_zipping()
        if error_response:
            return error_response

        path = None
        transfer_enabled = settings.SHARED_DRIVE_CONF.transfer_enabled
        if transfer_enabled:
            path = os.path.join(settings.SHARED_DRIVE_CONF.transfer_dir,
                                uuid.uuid4().hex)

        files, errors = self.iter_files()
        fpath = make_zip_file(files, compress=self.compress_zip, path=path)
        if errors:
            self.log_errors(errors)

        if transfer_enabled:
            return TransferHttpResponse(fpath, content_type=self.zip_mimetype)
        else:
            response = StreamingHttpResponse(FileWrapper(
                open(fpath), CHUNK_SIZE),
                                             content_type=self.zip_mimetype)
            response['Content-Length'] = os.path.getsize(fpath)
            set_file_download(response, self.zip_name)
            return response
Example #2
0
def download_test_jar(request):
    with open(os.path.join(os.path.dirname(__file__), 'static', 'app_manager', 'CommCare.jar')) as f:
        jar = f.read()

    response = HttpResponse(content_type="application/java-archive")
    set_file_download(response, "CommCare.jar")
    response['Content-Length'] = len(jar)
    response.write(jar)
    return response
Example #3
0
def download_test_jar(request):
    with open(os.path.join(os.path.dirname(__file__), 'static', 'app_manager', 'CommCare.jar')) as f:
        jar = f.read()

    response = HttpResponse(content_type="application/java-archive")
    set_file_download(response, "CommCare.jar")
    response['Content-Length'] = len(jar)
    response.write(jar)
    return response
Example #4
0
def case_upload_form_ids(request, domain, upload_id):
    try:
        case_upload = _get_case_upload_record(domain, upload_id, request.couch_user)
    except CaseUploadRecord.DoesNotExist:
        return HttpResponseNotFound()

    ids_stream = ('{}\n'.format(form_id)
                  for form_id in get_form_ids_for_case_upload(case_upload))
    response = StreamingHttpResponse(ids_stream, content_type='text/plain')
    set_file_download(response, f"{domain}-case_upload-form_ids.txt")
    return response
Example #5
0
def formdefs(request, domain, app_id):
    # TODO: Looks like this function is never used
    langs = [json.loads(request.GET.get('lang', '"en"'))]
    format = request.GET.get('format', 'json')
    app = get_app(domain, app_id)

    def get_questions(form):
        xform = XForm(form.source)
        prefix = '/%s/' % xform.data_node.tag_name

        def remove_prefix(string):
            if string.startswith(prefix):
                return string[len(prefix):]
            else:
                raise Exception()

        def transform_question(q):
            return {
                'id': remove_prefix(q['value']),
                'type': q['tag'],
                'text': q['label'] if q['tag'] != 'hidden' else ''
            }

        return [transform_question(q) for q in xform.get_questions(langs)]

    formdefs = [{
        'name':
        "%s, %s" % (f['form'].get_module().name['en'], f['form'].name['en'])
        if f['type'] == 'module_form' else 'User Registration',
        'columns': ['id', 'type', 'text'],
        'rows':
        get_questions(f['form'])
    } for f in app.get_forms(bare=False)]

    if format == 'xlsx':
        f = StringIO()
        writer = Excel2007ExportWriter()
        writer.open([(sheet['name'], [FormattedRow(sheet['columns'])])
                     for sheet in formdefs], f)
        writer.write([(sheet['name'], [
            FormattedRow([
                cell for (_, cell) in sorted(
                    row.items(),
                    key=lambda item: sheet['columns'].index(item[0]))
            ]) for row in sheet['rows']
        ]) for sheet in formdefs])
        writer.close()
        response = HttpResponse(
            f.getvalue(), content_type=Format.from_format('xlsx').mimetype)
        set_file_download(response, 'formdefs.xlsx')
        return response
    else:
        return json_response(formdefs)
Example #6
0
def formdefs(request, domain, app_id):
    # TODO: Looks like this function is never used
    langs = [json.loads(request.GET.get('lang', '"en"'))]
    format = request.GET.get('format', 'json')
    app = get_app(domain, app_id)

    def get_questions(form):
        xform = XForm(form.source)
        prefix = '/%s/' % xform.data_node.tag_name

        def remove_prefix(string):
            if string.startswith(prefix):
                return string[len(prefix):]
            else:
                raise Exception()

        def transform_question(q):
            return {
                'id': remove_prefix(q['value']),
                'type': q['tag'],
                'text': q['label'] if q['tag'] != 'hidden' else ''
            }
        return [transform_question(q) for q in xform.get_questions(langs)]
    formdefs = [{
        'name': "%s, %s" % (
            f['form'].get_module().name['en'],
            f['form'].name['en']
        ) if f['type'] == 'module_form' else 'User Registration',
        'columns': ['id', 'type', 'text'],
        'rows': get_questions(f['form'])
    } for f in app.get_forms(bare=False)]

    if format == 'xlsx':
        f = StringIO()
        writer = Excel2007ExportWriter()
        writer.open([(sheet['name'], [FormattedRow(sheet['columns'])]) for sheet in formdefs], f)
        writer.write([(
            sheet['name'],
            [
                FormattedRow([
                    cell for (_, cell) in
                    sorted(row.items(), key=lambda item: sheet['columns'].index(item[0]))
                ])
                for row in sheet['rows']
            ]
        ) for sheet in formdefs])
        writer.close()
        response = HttpResponse(f.getvalue(), content_type=Format.from_format('xlsx').mimetype)
        set_file_download(response, 'formdefs.xlsx')
        return response
    else:
        return json_response(formdefs)
Example #7
0
def case_upload_file(request, domain, upload_id):
    try:
        case_upload = CaseUploadRecord.objects.get(upload_id=upload_id, domain=domain)
    except CaseUploadRecord.DoesNotExist:
        return HttpResponseNotFound()

    if not user_may_view_file_upload(domain, request.couch_user, case_upload):
        return HttpResponseForbidden()

    response = StreamingHttpResponse(open(case_upload.get_tempfile_ref_for_upload_ref(), 'rb'))

    set_file_download(response, case_upload.upload_file_meta.filename)
    return response
Example #8
0
def case_upload_file(request, domain, upload_id):
    try:
        case_upload = _get_case_upload_record(domain, upload_id, request.couch_user)
    except CaseUploadRecord.DoesNotExist:
        return HttpResponseNotFound()

    if not user_may_view_file_upload(domain, request.couch_user, case_upload):
        return HttpResponseForbidden()

    response = StreamingHttpResponse(open(case_upload.get_tempfile_ref_for_upload_ref(), 'rb'))

    set_file_download(response, case_upload.upload_file_meta.filename)
    return response
Example #9
0
def _get_xform_source(request, app, form, filename="form.xml"):
    download = json.loads(request.GET.get('download', 'false'))
    lang = request.COOKIES.get('lang', app.langs[0])
    source = form.source
    if download:
        response = HttpResponse(source)
        response['Content-Type'] = "application/xml"
        for lc in [lang] + app.langs:
            if lc in form.name:
                filename = "%s.xml" % unidecode(form.name[lc])
                break
        set_file_download(response, filename)
        return response
    else:
        return json_response(source)
Example #10
0
def _get_xform_source(request, app, form, filename="form.xml"):
    download = json.loads(request.GET.get('download', 'false'))
    lang = request.COOKIES.get('lang', app.langs[0])
    source = form.source
    if download:
        response = HttpResponse(source)
        response['Content-Type'] = "application/xml"
        for lc in [lang] + app.langs:
            if lc in form.name:
                filename = "%s.xml" % unidecode(form.name[lc])
                break
        set_file_download(response, filename)
        return response
    else:
        return json_response(source)
Example #11
0
def export_gzip(req, domain, app_id):
    app_json = get_app(domain, app_id)
    fd, fpath = tempfile.mkstemp()
    with os.fdopen(fd, 'w') as tmp:
        with zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED) as z:
            z.writestr('application.json', app_json.export_json())

    wrapper = FileWrapper(open(fpath, 'rb'))
    response = HttpResponse(wrapper, content_type='application/zip')
    response['Content-Length'] = os.path.getsize(fpath)
    app = Application.get(app_id)
    set_file_download(response, '{domain}-{app_name}-{app_version}.zip'.format(
        app_name=slugify(app.name), app_version=slugify(six.text_type(app.version)), domain=domain
    ))
    return response
Example #12
0
def export_gzip(req, domain, app_id):
    app_json = get_app(domain, app_id)
    fd, fpath = tempfile.mkstemp()
    with os.fdopen(fd, 'w') as tmp:
        with zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED) as z:
            z.writestr('application.json', app_json.export_json())

    wrapper = FileWrapper(open(fpath))
    response = HttpResponse(wrapper, content_type='application/zip')
    response['Content-Length'] = os.path.getsize(fpath)
    app = Application.get(app_id)
    set_file_download(response, '{domain}-{app_name}-{app_version}.zip'.format(
        app_name=slugify(app.name), app_version=slugify(unicode(app.version)), domain=domain
    ))
    return response
Example #13
0
    def get(self, request, *args, **kwargs):
        error_response = self.check_before_zipping()
        if error_response:
            return error_response

        files, errors = self.iter_files()
        fpath = make_zip_tempfile(files, compress=self.compress_zip)
        if errors:
            self.log_errors(errors)

        wrapper = FileWrapper(open(fpath))
        response = HttpResponse(wrapper, mimetype=self.zip_mimetype)
        response['Content-Length'] = os.path.getsize(fpath)
        set_file_download(response, self.zip_name)
        return response
Example #14
0
def get_xform_source(request, domain, app_id, form_unique_id):
    app = get_app(domain, app_id)
    try:
        form = app.get_form(form_unique_id)
    except IndexError:
        raise Http404()

    lang = request.COOKIES.get('lang', app.langs[0])
    source = form.source
    response = HttpResponse(source)
    response['Content-Type'] = "application/xml"
    filename = form.default_name()
    for lc in [lang] + app.langs:
        if lc in form.name:
            filename = form.name[lc]
            break
    set_file_download(response, "%s.xml" % unidecode(filename))
    return response
Example #15
0
def download_jad(request, domain, app_id):
    """
    See ApplicationBase.create_jadjar_from_build_files

    """
    app = request.app
    if not app.copy_of:
        app.set_media_versions()
    jad, _ = app.create_jadjar_from_build_files()
    try:
        response = HttpResponse(jad)
    except Exception:
        messages.error(request, BAD_BUILD_MESSAGE)
        return back_to_main(request, domain, app_id=app_id)
    set_file_download(response, "CommCare.jad")
    response["Content-Type"] = "text/vnd.sun.j2me.app-descriptor"
    response["Content-Length"] = len(jad)
    return response
Example #16
0
def get_xform_source(request, domain, app_id, form_unique_id):
    app = get_app(domain, app_id)
    try:
        form = app.get_form(form_unique_id)
    except IndexError:
        raise Http404()

    lang = request.COOKIES.get('lang', app.langs[0])
    source = form.source
    response = HttpResponse(source)
    response['Content-Type'] = "application/xml"
    filename = form.default_name()
    for lc in [lang] + app.langs:
        if lc in form.name:
            filename = form.name[lc]
            break
    set_file_download(response, "%s.xml" % unidecode(filename))
    return response
Example #17
0
def export_gzip(req, domain, app_id):
    app_json = get_app(domain, app_id)
    fd, fpath = tempfile.mkstemp()
    with os.fdopen(fd, "w") as tmp:
        with zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED) as z:
            z.writestr("application.json", app_json.export_json())

    wrapper = FileWrapper(open(fpath))
    response = HttpResponse(wrapper, content_type="application/zip")
    response["Content-Length"] = os.path.getsize(fpath)
    app = Application.get(app_id)
    set_file_download(
        response,
        "{domain}-{app_name}-{app_version}.zip".format(
            app_name=slugify(app.name), app_version=slugify(unicode(app.version)), domain=domain
        ),
    )
    return response
Example #18
0
def download_jad(request, domain, app_id):
    """
    See ApplicationBase.create_jadjar_from_build_files

    """
    app = request.app
    if not app.copy_of:
        app.set_media_versions()
    jad, _ = app.create_jadjar_from_build_files()
    try:
        response = HttpResponse(jad)
    except Exception:
        messages.error(request, BAD_BUILD_MESSAGE)
        return back_to_main(request, domain, app_id=app_id)
    set_file_download(response, "CommCare.jad")
    response["Content-Type"] = "text/vnd.sun.j2me.app-descriptor"
    response["Content-Length"] = len(jad)
    return response
def multimedia_list_download(request, domain, app_id):
    app = get_app(domain, app_id)
    include_audio = request.GET.get("audio", True)
    include_images = request.GET.get("images", True)
    strip_jr = request.GET.get("strip_jr", True)
    filelist = []
    for m in app.get_modules():
        for f in m.get_forms():
            validate_xform(domain, f.source)
            parsed = XForm(f.source)
            if include_images:
                filelist.extend(parsed.image_references)
            if include_audio:
                filelist.extend(parsed.audio_references)

    if strip_jr:
        filelist = [s.replace("jr://file/", "") for s in filelist if s]
    response = HttpResponse()
    set_file_download(response, 'list.txt')
    response.write("\n".join(sorted(set(filelist))))
    return response
Example #20
0
def multimedia_list_download(request, domain, app_id):
    app = get_app(domain, app_id)
    include_audio = request.GET.get("audio", True)
    include_images = request.GET.get("images", True)
    strip_jr = request.GET.get("strip_jr", True)
    filelist = []
    for m in app.get_modules():
        for f in m.get_forms():
            parsed = XForm(f.source)
            parsed.validate(version=app.application_version)
            if include_images:
                filelist.extend(parsed.image_references)
            if include_audio:
                filelist.extend(parsed.audio_references)

    if strip_jr:
        filelist = [s.replace("jr://file/", "") for s in filelist if s]
    response = HttpResponse()
    set_file_download(response, 'list.txt')
    response.write("\n".join(sorted(set(filelist))))
    return response
Example #21
0
def download_jar(request, domain, app_id):
    """
    See ApplicationBase.create_jadjar_from_build_files

    This is the only view that will actually be called
    in the process of downloading a complete CommCare.jar
    build (i.e. over the air to a phone).

    """
    response = HttpResponse(content_type="application/java-archive")
    app = request.app
    if not app.copy_of:
        app.set_media_versions()
    _, jar = app.create_jadjar_from_build_files()
    set_file_download(response, 'CommCare.jar')
    response['Content-Length'] = len(jar)
    try:
        response.write(jar)
    except Exception:
        messages.error(request, BAD_BUILD_MESSAGE)
        return back_to_main(request, domain, app_id=app_id)
    return response
Example #22
0
    def get(self, request, *args, **kwargs):
        error_response = self.check_before_zipping()
        if error_response:
            return error_response

        path = None
        transfer_enabled = settings.SHARED_DRIVE_CONF.transfer_enabled
        if transfer_enabled:
            path = os.path.join(settings.SHARED_DRIVE_CONF.transfer_dir, uuid.uuid4().hex)

        files, errors = self.iter_files()
        fpath = make_zip_file(files, compress=self.compress_zip, path=path)
        if errors:
            self.log_errors(errors)

        if transfer_enabled:
            return TransferHttpResponse(fpath, mimetype=self.zip_mimetype)
        else:
            response = StreamingHttpResponse(FileWrapper(open(fpath), CHUNK_SIZE), mimetype=self.zip_mimetype)
            response['Content-Length'] = os.path.getsize(fpath)
            set_file_download(response, self.zip_name)
            return response
Example #23
0
def download_jar(request, domain, app_id):
    """
    See ApplicationBase.create_jadjar_from_build_files

    This is the only view that will actually be called
    in the process of downloading a complete CommCare.jar
    build (i.e. over the air to a phone).

    """
    response = HttpResponse(content_type="application/java-archive")
    app = request.app
    if not app.copy_of:
        app.set_media_versions()
    _, jar = app.create_jadjar_from_build_files()
    set_file_download(response, 'CommCare.jar')
    response['Content-Length'] = len(jar)
    try:
        response.write(jar)
    except Exception:
        messages.error(request, BAD_BUILD_MESSAGE)
        return back_to_main(request, domain, app_id=app_id)
    return response
Example #24
0
def download_file(request, domain, app_id, path):
    if path == "app.json":
        return JsonResponse(request.app.to_json())

    content_type_map = {
        'ccpr': 'commcare/profile',
        'jad': 'text/vnd.sun.j2me.app-descriptor',
        'jar': 'application/java-archive',
        'xml': 'application/xml',
        'txt': 'text/plain',
    }
    try:
        content_type = content_type_map[path.split('.')[-1]]
    except KeyError:
        content_type = None
    response = HttpResponse(content_type=content_type)

    if path in ('CommCare.jad', 'CommCare.jar'):
        set_file_download(response, path)
        full_path = path
    else:
        full_path = 'files/%s' % path

    def resolve_path(path):
        return RegexURLResolver(
            r'^', 'corehq.apps.app_manager.download_urls').resolve(path)

    try:
        assert request.app.copy_of
        obj = CachedObject('{id}::{path}'.format(
            id=request.app._id,
            path=full_path,
        ))
        if not obj.is_cached():
            payload = request.app.fetch_attachment(full_path)
            if type(payload) is unicode:
                payload = payload.encode('utf-8')
            buffer = StringIO(payload)
            metadata = {'content_type': content_type}
            obj.cache_put(buffer, metadata, timeout=None)
        else:
            _, buffer = obj.get()
            payload = buffer.getvalue()
        response.write(payload)
        response['Content-Length'] = len(response.content)
        return response
    except (ResourceNotFound, AssertionError):
        if request.app.copy_of:
            if request.META.get('HTTP_USER_AGENT') == 'bitlybot':
                raise Http404()
            elif path == 'profile.ccpr':
                # legacy: should patch build to add odk profile
                # which wasn't made on build for a long time
                add_odk_profile_after_build(request.app)
                request.app.save()
                return download_file(request, domain, app_id, path)
            elif path in ('CommCare.jad', 'CommCare.jar'):
                request.app.create_jadjar_from_build_files(save=True)
                try:
                    request.app.save(increment_version=False)
                except ResourceConflict:
                    # Likely that somebody tried to download the jad and jar
                    # files for the first time simultaneously.
                    pass
                return download_file(request, domain, app_id, path)
            else:
                try:
                    resolve_path(path)
                except Resolver404:
                    # ok this was just a url that doesn't exist
                    # todo: log since it likely exposes a mobile bug
                    # logging was removed because such a mobile bug existed
                    # and was spamming our emails
                    pass
                else:
                    # this resource should exist but doesn't
                    logging.error(
                        'Expected build resource %s not found' % path,
                        extra={'request': request}
                    )
                    if not request.app.build_broken:
                        request.app.build_broken = True
                        request.app.build_broken_reason = 'incomplete-build'
                        try:
                            request.app.save()
                        except ResourceConflict:
                            # this really isn't a big deal:
                            # It'll get updated next time a resource is request'd;
                            # in fact the conflict is almost certainly from
                            # another thread doing this exact update
                            pass
                raise Http404()
        try:
            callback, callback_args, callback_kwargs = resolve_path(path)
        except Resolver404:
            raise Http404()

        return callback(request, domain, app_id, *callback_args, **callback_kwargs)
Example #25
0
def download_file(request, domain, app_id, path):
    download_target_version = request.GET.get(
        'download_target_version') == 'true'
    if download_target_version:
        parts = path.split('.')
        assert len(parts) == 2
        target = Application.get(app_id).commcare_flavor
        assert target != 'none'
        path = parts[0] + '-' + target + '.' + parts[1]

    if path == "app.json":
        return JsonResponse(request.app.to_json())

    content_type_map = {
        'ccpr': 'commcare/profile',
        'jad': 'text/vnd.sun.j2me.app-descriptor',
        'jar': 'application/java-archive',
        'xml': 'application/xml',
        'txt': 'text/plain',
    }
    try:
        content_type = content_type_map[path.split('.')[-1]]
    except KeyError:
        content_type = None
    response = HttpResponse(content_type=content_type)

    if request.GET.get('download') == 'true':
        response['Content-Disposition'] = "attachment; filename={}".format(
            path)

    build_profile = request.GET.get('profile')
    build_profile_access = domain_has_privilege(domain,
                                                privileges.BUILD_PROFILES)
    if path in ('CommCare.jad', 'CommCare.jar'):
        set_file_download(response, path)
        full_path = path
    elif build_profile and build_profile in request.app.build_profiles and build_profile_access:
        full_path = 'files/%s/%s' % (build_profile, path)
    else:
        full_path = 'files/%s' % path

    def resolve_path(path):
        return RegexURLResolver(
            r'^', 'corehq.apps.app_manager.download_urls').resolve(path)

    def create_build_files_if_necessary_handling_conflicts(is_retry=False):
        try:
            try:
                # look for file guaranteed to exist if profile is created
                request.app.fetch_attachment(
                    'files/{id}/profile.xml'.format(id=build_profile))
            except ResourceNotFound:
                request.app.create_build_files(build_profile_id=build_profile)
                request.app.save()
        except ResourceConflict:
            if is_retry:
                raise
            request.app = Application.get(request.app.get_id)
            create_build_files_if_necessary_handling_conflicts(True)

    try:
        assert request.app.copy_of
        # lazily create language profiles to avoid slowing initial build
        try:
            payload = request.app.fetch_attachment(full_path)
        except ResourceNotFound:
            if build_profile in request.app.build_profiles and build_profile_access:
                create_build_files_if_necessary_handling_conflicts()
                payload = request.app.fetch_attachment(full_path)
            else:
                raise
        if path in ['profile.xml', 'media_profile.xml']:
            payload = convert_XML_To_J2ME(payload, path,
                                          request.app.use_j2me_endpoint)
        response.write(payload)
        response['Content-Length'] = len(response.content)
        return response
    except (ResourceNotFound, AssertionError):
        if request.app.copy_of:
            if request.META.get('HTTP_USER_AGENT') == 'bitlybot':
                raise Http404()
            elif path == 'profile.ccpr':
                # legacy: should patch build to add odk profile
                # which wasn't made on build for a long time
                add_odk_profile_after_build(request.app)
                request.app.save()
                return download_file(request, domain, app_id, path)
            elif path in ('CommCare.jad', 'CommCare.jar'):
                if not request.app.build_spec.supports_j2me():
                    raise Http404()
                request.app.create_jadjar_from_build_files(save=True)
                try:
                    request.app.save(increment_version=False)
                except ResourceConflict:
                    # Likely that somebody tried to download the jad and jar
                    # files for the first time simultaneously.
                    pass
                return download_file(request, domain, app_id, path)
            else:
                try:
                    resolve_path(path)
                except Resolver404:
                    # ok this was just a url that doesn't exist
                    pass
                else:
                    # this resource should exist but doesn't
                    _assert = soft_assert('@'.join(['jschweers',
                                                    'dimagi.com']))
                    _assert(False,
                            'Expected build resource %s not found' % path)
                raise Http404()
        try:
            callback, callback_args, callback_kwargs = resolve_path(path)
        except Resolver404:
            raise Http404()

        return callback(request, domain, app_id, *callback_args,
                        **callback_kwargs)
Example #26
0
def download_file(request, domain, app_id, path):
    download_target_version = request.GET.get('download_target_version') == 'true'
    if download_target_version:
        parts = path.split('.')
        assert len(parts) == 2
        target = Application.get(app_id).target_commcare_flavor
        assert target != 'none'
        path = parts[0] + '-' + target + '.' + parts[1]

    if path == "app.json":
        return JsonResponse(request.app.to_json())

    content_type_map = {
        'ccpr': 'commcare/profile',
        'jad': 'text/vnd.sun.j2me.app-descriptor',
        'jar': 'application/java-archive',
        'xml': 'application/xml',
        'txt': 'text/plain',
    }
    try:
        content_type = content_type_map[path.split('.')[-1]]
    except KeyError:
        content_type = None
    response = HttpResponse(content_type=content_type)

    if request.GET.get('download') == 'true':
        response['Content-Disposition'] = "attachment; filename={}".format(path)

    build_profile = request.GET.get('profile')
    build_profile_access = domain_has_privilege(domain, privileges.BUILD_PROFILES)
    if path in ('CommCare.jad', 'CommCare.jar'):
        set_file_download(response, path)
        full_path = path
    elif build_profile and build_profile in request.app.build_profiles and build_profile_access:
        full_path = 'files/%s/%s' % (build_profile, path)
    else:
        full_path = 'files/%s' % path

    def resolve_path(path):
        return RegexURLResolver(
            r'^', 'corehq.apps.app_manager.download_urls').resolve(path)

    def create_build_files_if_necessary_handling_conflicts(is_retry=False):
        try:
            try:
                # look for file guaranteed to exist if profile is created
                request.app.fetch_attachment('files/{id}/profile.xml'.format(id=build_profile), return_bytes=True)
            except ResourceNotFound:
                request.app.create_build_files(build_profile_id=build_profile)
                request.app.save()
        except ResourceConflict:
            if is_retry:
                raise
            create_build_files_if_necessary_handling_conflicts(True)

    try:
        assert request.app.copy_of
        # lazily create language profiles to avoid slowing initial build
        try:
            payload = request.app.fetch_attachment(full_path, return_bytes=True)
        except ResourceNotFound:
            if build_profile in request.app.build_profiles and build_profile_access:
                create_build_files_if_necessary_handling_conflicts()
                payload = request.app.fetch_attachment(full_path, return_bytes=True)
            else:
                raise
        if path in ['profile.xml', 'media_profile.xml']:
            payload = convert_XML_To_J2ME(payload, path, request.app.use_j2me_endpoint)
        response.write(payload)
        response['Content-Length'] = len(response.content)
        return response
    except (ResourceNotFound, AssertionError):
        if request.app.copy_of:
            if request.META.get('HTTP_USER_AGENT') == 'bitlybot':
                raise Http404()
            elif path == 'profile.ccpr':
                # legacy: should patch build to add odk profile
                # which wasn't made on build for a long time
                add_odk_profile_after_build(request.app)
                request.app.save()
                return download_file(request, domain, app_id, path)
            elif path in ('CommCare.jad', 'CommCare.jar'):
                if not request.app.build_spec.supports_j2me():
                    raise Http404()
                request.app.create_jadjar_from_build_files(save=True)
                try:
                    request.app.save(increment_version=False)
                except ResourceConflict:
                    # Likely that somebody tried to download the jad and jar
                    # files for the first time simultaneously.
                    pass
                return download_file(request, domain, app_id, path)
            else:
                try:
                    resolve_path(path)
                except Resolver404:
                    # ok this was just a url that doesn't exist
                    pass
                else:
                    # this resource should exist but doesn't
                    _assert = soft_assert('@'.join(['jschweers', 'dimagi.com']))
                    _assert(False, 'Expected build resource %s not found' % path)
                raise Http404()
        try:
            callback, callback_args, callback_kwargs = resolve_path(path)
        except Resolver404:
            raise Http404()

        return callback(request, domain, app_id, *callback_args, **callback_kwargs)
Example #27
0
def download_file(request, domain, app_id, path):
    if path == "app.json":
        return JsonResponse(request.app.to_json())

    content_type_map = {
        'ccpr': 'commcare/profile',
        'jad': 'text/vnd.sun.j2me.app-descriptor',
        'jar': 'application/java-archive',
        'xml': 'application/xml',
        'txt': 'text/plain',
    }
    try:
        content_type = content_type_map[path.split('.')[-1]]
    except KeyError:
        content_type = None
    response = HttpResponse(content_type=content_type)

    build_profile = request.GET.get('profile')
    build_profile_access = domain_has_privilege(domain, privileges.BUILD_PROFILES)
    if path in ('CommCare.jad', 'CommCare.jar'):
        set_file_download(response, path)
        full_path = path
    elif build_profile and build_profile in request.app.build_profiles and build_profile_access:
        full_path = 'files/%s/%s' % (build_profile, path)
    else:
        full_path = 'files/%s' % path

    def resolve_path(path):
        return RegexURLResolver(
            r'^', 'corehq.apps.app_manager.download_urls').resolve(path)

    try:
        assert request.app.copy_of
        obj = CachedObject('{id}::{path}'.format(
            id=request.app._id,
            path=full_path,
        ))
        if not obj.is_cached():
            #lazily create language profiles to avoid slowing initial build
            try:
                payload = request.app.fetch_attachment(full_path)
            except ResourceNotFound:
                if build_profile in request.app.build_profiles and build_profile_access:
                    try:
                        # look for file guaranteed to exist if profile is created
                        request.app.fetch_attachment('files/{id}/profile.xml'.format(id=build_profile))
                    except ResourceNotFound:
                        request.app.create_build_files(save=True, build_profile_id=build_profile)
                        request.app.save()
                        payload = request.app.fetch_attachment(full_path)
                    else:
                        # if profile.xml is found the profile has been built and its a bad request
                        raise
                else:
                    raise
            if type(payload) is unicode:
                payload = payload.encode('utf-8')
            buffer = StringIO(payload)
            metadata = {'content_type': content_type}
            obj.cache_put(buffer, metadata, timeout=None)
        else:
            _, buffer = obj.get()
            payload = buffer.getvalue()
        if path in ['profile.xml', 'media_profile.xml']:
            payload = convert_XML_To_J2ME(payload, path, request.app.use_j2me_endpoint)
        response.write(payload)
        response['Content-Length'] = len(response.content)
        return response
    except (ResourceNotFound, AssertionError):
        if request.app.copy_of:
            if request.META.get('HTTP_USER_AGENT') == 'bitlybot':
                raise Http404()
            elif path == 'profile.ccpr':
                # legacy: should patch build to add odk profile
                # which wasn't made on build for a long time
                add_odk_profile_after_build(request.app)
                request.app.save()
                return download_file(request, domain, app_id, path)
            elif path in ('CommCare.jad', 'CommCare.jar'):
                if not request.app.build_spec.supports_j2me():
                    raise Http404()
                request.app.create_jadjar_from_build_files(save=True)
                try:
                    request.app.save(increment_version=False)
                except ResourceConflict:
                    # Likely that somebody tried to download the jad and jar
                    # files for the first time simultaneously.
                    pass
                return download_file(request, domain, app_id, path)
            else:
                try:
                    resolve_path(path)
                except Resolver404:
                    # ok this was just a url that doesn't exist
                    # todo: log since it likely exposes a mobile bug
                    # logging was removed because such a mobile bug existed
                    # and was spamming our emails
                    pass
                else:
                    # this resource should exist but doesn't
                    _assert = soft_assert('@'.join(['jschweers', 'dimagi.com']))
                    _assert(False, 'Expected build resource %s not found' % path)
                raise Http404()
        try:
            callback, callback_args, callback_kwargs = resolve_path(path)
        except Resolver404:
            raise Http404()

        return callback(request, domain, app_id, *callback_args, **callback_kwargs)
Example #28
0
def download_file(request, domain, app_id, path):
    if path == "app.json":
        return JsonResponse(request.app.to_json())

    content_type_map = {
        'ccpr': 'commcare/profile',
        'jad': 'text/vnd.sun.j2me.app-descriptor',
        'jar': 'application/java-archive',
        'xml': 'application/xml',
        'txt': 'text/plain',
    }
    try:
        content_type = content_type_map[path.split('.')[-1]]
    except KeyError:
        content_type = None
    response = HttpResponse(content_type=content_type)

    build_profile = request.GET.get('profile')
    build_profile_access = domain_has_privilege(domain,
                                                privileges.BUILD_PROFILES)
    if path in ('CommCare.jad', 'CommCare.jar'):
        set_file_download(response, path)
        full_path = path
    elif build_profile and build_profile in request.app.build_profiles and build_profile_access:
        full_path = 'files/%s/%s' % (build_profile, path)
    else:
        full_path = 'files/%s' % path

    def resolve_path(path):
        return RegexURLResolver(
            r'^', 'corehq.apps.app_manager.download_urls').resolve(path)

    try:
        assert request.app.copy_of
        obj = CachedObject('{id}::{path}'.format(
            id=request.app._id,
            path=full_path,
        ))
        if not obj.is_cached():
            #lazily create language profiles to avoid slowing initial build
            try:
                payload = request.app.fetch_attachment(full_path)
            except ResourceNotFound:
                if build_profile in request.app.build_profiles and build_profile_access:
                    try:
                        # look for file guaranteed to exist if profile is created
                        request.app.fetch_attachment(
                            'files/{id}/profile.xml'.format(id=build_profile))
                    except ResourceNotFound:
                        request.app.create_build_files(
                            save=True, build_profile_id=build_profile)
                        request.app.save()
                        payload = request.app.fetch_attachment(full_path)
                    else:
                        # if profile.xml is found the profile has been built and its a bad request
                        raise
                else:
                    raise
            if type(payload) is unicode:
                payload = payload.encode('utf-8')
            buffer = StringIO(payload)
            metadata = {'content_type': content_type}
            obj.cache_put(buffer, metadata, timeout=None)
        else:
            _, buffer = obj.get()
            payload = buffer.getvalue()
        if path in ['profile.xml', 'media_profile.xml']:
            payload = convert_XML_To_J2ME(payload, path,
                                          request.app.use_j2me_endpoint)
        response.write(payload)
        response['Content-Length'] = len(response.content)
        return response
    except (ResourceNotFound, AssertionError):
        if request.app.copy_of:
            if request.META.get('HTTP_USER_AGENT') == 'bitlybot':
                raise Http404()
            elif path == 'profile.ccpr':
                # legacy: should patch build to add odk profile
                # which wasn't made on build for a long time
                add_odk_profile_after_build(request.app)
                request.app.save()
                return download_file(request, domain, app_id, path)
            elif path in ('CommCare.jad', 'CommCare.jar'):
                request.app.create_jadjar_from_build_files(save=True)
                try:
                    request.app.save(increment_version=False)
                except ResourceConflict:
                    # Likely that somebody tried to download the jad and jar
                    # files for the first time simultaneously.
                    pass
                return download_file(request, domain, app_id, path)
            else:
                try:
                    resolve_path(path)
                except Resolver404:
                    # ok this was just a url that doesn't exist
                    # todo: log since it likely exposes a mobile bug
                    # logging was removed because such a mobile bug existed
                    # and was spamming our emails
                    pass
                else:
                    # this resource should exist but doesn't
                    logging.error('Expected build resource %s not found' %
                                  path,
                                  extra={'request': request})
                    if not request.app.build_broken:
                        request.app.build_broken = True
                        request.app.build_broken_reason = 'incomplete-build'
                        try:
                            request.app.save()
                        except ResourceConflict:
                            # this really isn't a big deal:
                            # It'll get updated next time a resource is request'd;
                            # in fact the conflict is almost certainly from
                            # another thread doing this exact update
                            pass
                raise Http404()
        try:
            callback, callback_args, callback_kwargs = resolve_path(path)
        except Resolver404:
            raise Http404()

        return callback(request, domain, app_id, *callback_args,
                        **callback_kwargs)
Example #29
0
def formdefs(request, domain, app_id):
    # TODO: Looks like this function is never used
    langs = [json.loads(request.GET.get("lang", '"en"'))]
    format = request.GET.get("format", "json")
    app = get_app(domain, app_id)

    def get_questions(form):
        xform = XForm(form.source)
        prefix = "/%s/" % xform.data_node.tag_name

        def remove_prefix(string):
            if string.startswith(prefix):
                return string[len(prefix) :]
            else:
                raise Exception()

        def transform_question(q):
            return {
                "id": remove_prefix(q["value"]),
                "type": q["tag"],
                "text": q["label"] if q["tag"] != "hidden" else "",
            }

        return [transform_question(q) for q in xform.get_questions(langs)]

    formdefs = [
        {
            "name": "%s, %s" % (f["form"].get_module().name["en"], f["form"].name["en"])
            if f["type"] == "module_form"
            else "User Registration",
            "columns": ["id", "type", "text"],
            "rows": get_questions(f["form"]),
        }
        for f in app.get_forms(bare=False)
    ]

    if format == "xlsx":
        f = StringIO()
        writer = Excel2007ExportWriter()
        writer.open([(sheet["name"], [FormattedRow(sheet["columns"])]) for sheet in formdefs], f)
        writer.write(
            [
                (
                    sheet["name"],
                    [
                        FormattedRow(
                            [
                                cell
                                for (_, cell) in sorted(row.items(), key=lambda item: sheet["columns"].index(item[0]))
                            ]
                        )
                        for row in sheet["rows"]
                    ],
                )
                for sheet in formdefs
            ]
        )
        writer.close()
        response = HttpResponse(f.getvalue(), content_type=Format.from_format("xlsx").mimetype)
        set_file_download(response, "formdefs.xlsx")
        return response
    else:
        return json_response(formdefs)
Example #30
0
def download_file(request, domain, app_id, path):
    download_target_version = request.GET.get('download_target_version') == 'true'
    if download_target_version:
        parts = path.split('.')
        assert len(parts) == 2
        target = Application.get(app_id).commcare_flavor
        assert target != 'none'
        path = parts[0] + '-' + target + '.' + parts[1]

    if path == "app.json":
        return JsonResponse(request.app.to_json())

    content_type_map = {
        'ccpr': 'commcare/profile',
        'jad': 'text/vnd.sun.j2me.app-descriptor',
        'jar': 'application/java-archive',
        'xml': 'application/xml',
        'txt': 'text/plain',
    }
    try:
        content_type = content_type_map[path.split('.')[-1]]
    except KeyError:
        content_type = None
    response = HttpResponse(content_type=content_type)

    if request.GET.get('download') == 'true':
        response['Content-Disposition'] = "attachment; filename={}".format(path)

    build_profile_id = _get_build_profile_id(request)
    build_profile_access = domain_has_privilege(domain, privileges.BUILD_PROFILES)
    if path in ('CommCare.jad', 'CommCare.jar'):
        set_file_download(response, path)
        full_path = path
    elif build_profile_id and build_profile_id in request.app.build_profiles and build_profile_access:
        full_path = 'files/%s/%s' % (build_profile_id, path)
    else:
        full_path = 'files/%s' % path

    def resolve_path(path):
        return url(r'^', include('corehq.apps.app_manager.download_urls')).resolve(path)

    def create_build_files(build_profile_id=None):
        request.app.create_build_files(build_profile_id=build_profile_id)
        request.app.save()

    def create_build_files_if_necessary_handling_conflicts(is_retry=False):
        try:
            try:
                # look for file guaranteed to exist if profile is created
                request.app.fetch_attachment('files/{id}/profile.xml'.format(id=build_profile_id))
            except ResourceNotFound:
                create_build_files(build_profile_id)
        except ResourceConflict:
            if is_retry:
                raise
            request.app = Application.get(request.app.get_id)
            create_build_files_if_necessary_handling_conflicts(True)

    # Todo; remove after https://dimagi-dev.atlassian.net/browse/ICDS-1483 is fixed
    extension = path.split(".")[-1]
    if extension not in content_type_map.keys():
        metrics_counter("commcare.invalid_download_requests",
            tags={"domain": domain, "extension": extension})
    try:
        assert request.app.copy_of
        # create build files for default profile if they were not created during initial build
        # or for language profiles for which build files have not been created yet
        try:
            payload = request.app.fetch_attachment(full_path)
        except ResourceNotFound:
            if not build_profile_id or (build_profile_id in request.app.build_profiles and build_profile_access):
                create_build_files_if_necessary_handling_conflicts()
            else:
                raise
            payload = request.app.fetch_attachment(full_path)
        if path in ['profile.xml', 'media_profile.xml']:
            payload = convert_XML_To_J2ME(payload, path, request.app.use_j2me_endpoint)
        response.write(payload)
        if path in ['profile.ccpr', 'media_profile.ccpr'] and request.app.last_released:
            last_released = request.app.last_released.replace(microsecond=0)    # mobile doesn't want microseconds
            last_released = ServerTime(last_released).user_time(pytz.UTC).done().isoformat()
            response['X-CommCareHQ-AppReleasedOn'] = last_released
        response['Content-Length'] = len(response.content)
        return response
    except (ResourceNotFound, AssertionError):
        if request.app.copy_of:
            if request.META.get('HTTP_USER_AGENT') == 'bitlybot':
                raise Http404()
            elif path == 'profile.ccpr':
                # legacy: should patch build to add odk profile
                # which wasn't made on build for a long time
                add_odk_profile_after_build(request.app)
                request.app.save()
                return download_file(request, domain, app_id, path)
            elif path in ('CommCare.jad', 'CommCare.jar'):
                if not request.app.build_spec.supports_j2me():
                    raise Http404()
                request.app.create_jadjar_from_build_files(save=True)
                try:
                    request.app.save(increment_version=False)
                except ResourceConflict:
                    # Likely that somebody tried to download the jad and jar
                    # files for the first time simultaneously.
                    pass
                return download_file(request, domain, app_id, path)
            else:
                try:
                    resolve_path(path)
                except Resolver404:
                    # ok this was just a url that doesn't exist
                    pass
                else:
                    # this resource should exist but doesn't
                    _assert = soft_assert('@'.join(['jschweers', 'dimagi.com']))
                    _assert(False, 'Expected build resource %s not found' % path)
                raise Http404()
        try:
            callback, callback_args, callback_kwargs = resolve_path(path)
        except Resolver404:
            raise Http404()

        return callback(request, domain, app_id, *callback_args, **callback_kwargs)