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
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
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
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)
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)
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
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
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)
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
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
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
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
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 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
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
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
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
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
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)
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)
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)
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)
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)
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)
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)