def kml_export(request, username, id_string): # read the locations from the database owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) helper_auth_helper(request) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) data = {'data': kml_export_data(id_string, user=owner)} response = \ render(request, "survey.kml", data, content_type="application/vnd.google-earth.kml+xml") response['Content-Disposition'] = \ disposition_ext_and_date(id_string, 'kml') audit = {"xform": xform.id_string, "export_type": Export.KML_EXPORT} audit_log( Actions.EXPORT_CREATED, request.user, owner, _("Created KML export on '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) # log download as well audit_log( Actions.EXPORT_DOWNLOADED, request.user, owner, _("Downloaded KML export on '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) return response
def delete_export(request, username, id_string, export_type): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) export_id = request.POST.get('export_id') # find the export entry in the db export = get_object_or_404(Export, id=export_id) export.delete() audit = { "xform": xform.id_string, "export_type": export.export_type } audit_log( Actions.EXPORT_DOWNLOADED, request.user, owner, _("Deleted %(export_type)s export '%(filename)s'" " on '%(id_string)s'.") % { 'export_type': export.export_type.upper(), 'filename': export.filename, 'id_string': xform.id_string, }, audit, request) return HttpResponseRedirect(reverse( export_list, kwargs={ "username": username, "id_string": id_string, "export_type": export_type }))
def _generate_new_export(request, xform, query, export_type): query = _set_start_end_params(request, query) extension = _get_extension_from_export_type(export_type) try: if export_type == Export.EXTERNAL_EXPORT: export = generate_external_export( export_type, xform.user.username, xform.id_string, None, request.GET.get('token'), query, request.GET.get('meta') ) else: export = generate_export( export_type, extension, xform.user.username, xform.id_string, None, query ) audit = { "xform": xform.id_string, "export_type": export_type } log.audit_log( log.Actions.EXPORT_CREATED, request.user, xform.user, _("Created %(export_type)s export on '%(id_string)s'.") % { 'id_string': xform.id_string, 'export_type': export_type.upper() }, audit, request) except NoRecordsFoundError: raise Http404(_("No records found to export")) except J2XException as e: # j2x exception return {'error': str(e)} else: return export
def _generate_new_export(request, xform, query, export_type): query = _set_start_end_params(request, query) extension = _get_extension_from_export_type(export_type) try: if export_type == Export.EXTERNAL_EXPORT: export = generate_external_export(export_type, xform.user.username, xform.id_string, None, request.GET.get('token'), query, request.GET.get('meta')) else: export = generate_export(export_type, extension, xform.user.username, xform.id_string, None, query) audit = {"xform": xform.id_string, "export_type": export_type} log.audit_log( log.Actions.EXPORT_CREATED, request.user, xform.user, _("Created %(export_type)s export on '%(id_string)s'.") % { 'id_string': xform.id_string, 'export_type': export_type.upper() }, audit, request) except NoRecordsFoundError: raise Http404(_("No records found to export")) except J2XException as e: # j2x exception return {'error': str(e)} else: return export
def kml_export(request, username, id_string): # read the locations from the database owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) helper_auth_helper(request) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) data = {'data': kml_export_data(id_string, user=owner)} response = \ render(request, "survey.kml", data, content_type="application/vnd.google-earth.kml+xml") response['Content-Disposition'] = \ disposition_ext_and_date(id_string, 'kml') audit = { "xform": xform.id_string, "export_type": Export.KML_EXPORT } audit_log( Actions.EXPORT_CREATED, request.user, owner, _("Created KML export on '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) # log download as well audit_log( Actions.EXPORT_DOWNLOADED, request.user, owner, _("Downloaded KML export on '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) return response
def delete_export(request, username, id_string, export_type): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) export_id = request.POST.get('export_id') # find the export entry in the db export = get_object_or_404(Export, id=export_id) export.delete() audit = {"xform": xform.id_string, "export_type": export.export_type} audit_log( Actions.EXPORT_DOWNLOADED, request.user, owner, _("Deleted %(export_type)s export '%(filename)s'" " on '%(id_string)s'.") % { 'export_type': export.export_type.upper(), 'filename': export.filename, 'id_string': xform.id_string, }, audit, request) return HttpResponseRedirect( reverse(export_list, kwargs={ "username": username, "id_string": id_string, "export_type": export_type }))
def generate_instance(username, xml_file, media_files, uuid=None): ''' Process an XForm submission as if done via HTTP :param IO xml_file: file-like object containing XML XForm :param string username: username of the Form's owner :param list media_files: a list of UploadedFile objects :param string uuid: an optionnal uuid for the instance. :returns a (status, message) tuple. ''' try: instance = create_instance( username, xml_file, media_files, uuid=uuid ) except InstanceInvalidUserError: return {'code': SMS_SUBMISSION_REFUSED, 'text': _(u"Username or ID required.")} except InstanceEmptyError: return {'code': SMS_INTERNAL_ERROR, 'text': _(u"Received empty submission. " u"No instance was created")} except FormInactiveError: return {'code': SMS_SUBMISSION_REFUSED, 'text': _(u"Form is not active")} except XForm.DoesNotExist: return {'code': SMS_SUBMISSION_REFUSED, 'text': _(u"Form does not exist on this account")} except ExpatError: return {'code': SMS_INTERNAL_ERROR, 'text': _(u"Improperly formatted XML.")} except DuplicateInstance: return {'code': SMS_SUBMISSION_REFUSED, 'text': _(u"Duplicate submission")} if instance is None: return {'code': SMS_INTERNAL_ERROR, 'text': _(u"Unable to create submission.")} user = User.objects.get(username=username) audit = { "xform": instance.xform.id_string } audit_log(Actions.SUBMISSION_CREATED, user, instance.xform.user, _("Created submission on form %(id_string)s.") % {"id_string": instance.xform.id_string}, audit, HttpRequest()) xml_file.close() if len(media_files): [_file.close() for _file in media_files] return {'code': SMS_SUBMISSION_ACCEPTED, 'text': _(u"[SUCCESS] Your submission has been accepted."), 'id': get_sms_instance_id(instance)}
def log_export(request, xform, export_type): # log download as well audit = {"xform": xform.id_string, "export_type": export_type} log.audit_log( log.Actions.EXPORT_DOWNLOADED, request.user, xform.user, _("Downloaded %(export_type)s export on '%(id_string)s'.") % { 'id_string': xform.id_string, 'export_type': export_type.upper() }, audit, request)
def create_export(request, username, id_string, export_type): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) if export_type == Export.EXTERNAL_EXPORT: # check for template before trying to generate a report if not MetaData.external_export(xform=xform): return HttpResponseForbidden(_(u'No XLS Template set.')) query = request.POST.get("query") force_xlsx = request.POST.get('xls') != 'true' # export options group_delimiter = request.POST.get("options[group_delimiter]", '/') if group_delimiter not in ['.', '/']: return HttpResponseBadRequest( _("%s is not a valid delimiter" % group_delimiter)) # default is True, so when dont_.. is yes # split_select_multiples becomes False split_select_multiples = request.POST.get( "options[dont_split_select_multiples]", "no") == "no" binary_select_multiples = getattr(settings, 'BINARY_SELECT_MULTIPLES', False) # external export option meta = request.POST.get("meta") options = { 'group_delimiter': group_delimiter, 'split_select_multiples': split_select_multiples, 'binary_select_multiples': binary_select_multiples, 'meta': meta.replace(",", "") if meta else None } try: create_async_export(xform, export_type, query, force_xlsx, options) except Export.ExportTypeError: return HttpResponseBadRequest( _("%s is not a valid export type" % export_type)) else: audit = {"xform": xform.id_string, "export_type": export_type} audit_log( Actions.EXPORT_CREATED, request.user, owner, _("Created %(export_type)s export on '%(id_string)s'.") % { 'export_type': export_type.upper(), 'id_string': xform.id_string, }, audit, request) return HttpResponseRedirect( reverse(export_list, kwargs={ "username": username, "id_string": id_string, "export_type": export_type }))
def bulksubmission(request, username): # puts it in a temp directory. # runs "import_tools(temp_directory)" # deletes posting_user = get_object_or_404(User, username__iexact=username) # request.FILES is a django.utils.datastructures.MultiValueDict # for each key we have a list of values try: temp_postfile = request.FILES.pop("zip_submission_file", []) except IOError: return HttpResponseBadRequest( _(u"There was a problem receiving your " u"ODK submission. [Error: IO Error " u"reading data]")) if len(temp_postfile) != 1: return HttpResponseBadRequest( _(u"There was a problem receiving your" u" ODK submission. [Error: multiple " u"submission files (?)]")) postfile = temp_postfile[0] tempdir = tempfile.gettempdir() our_tfpath = os.path.join(tempdir, postfile.name) with open(our_tfpath, 'wb') as f: f.write(postfile.read()) with open(our_tfpath, 'rb') as f: total_count, success_count, errors = import_instances_from_zip( f, posting_user) # chose the try approach as suggested by the link below # http://stackoverflow.com/questions/82831 try: os.remove(our_tfpath) except IOError: # TODO: log this Exception somewhere pass json_msg = { 'message': _(u"Submission complete. Out of %(total)d " u"survey instances, %(success)d were imported, " u"(%(rejected)d were rejected as duplicates, " u"missing forms, etc.)") % { 'total': total_count, 'success': success_count, 'rejected': total_count - success_count }, 'errors': u"%d %s" % (len(errors), errors) } audit = {"bulk_submission_log": json_msg} audit_log(Actions.USER_BULK_SUBMISSION, request.user, posting_user, _("Made bulk submissions."), audit, request) response = HttpResponse(json.dumps(json_msg)) response.status_code = 200 response['Location'] = request.build_absolute_uri(request.path) return response
def bulksubmission(request, username): # puts it in a temp directory. # runs "import_tools(temp_directory)" # deletes posting_user = get_object_or_404(User, username__iexact=username) # request.FILES is a django.utils.datastructures.MultiValueDict # for each key we have a list of values try: temp_postfile = request.FILES.pop("zip_submission_file", []) except IOError: return HttpResponseBadRequest(_(u"There was a problem receiving your " u"ODK submission. [Error: IO Error " u"reading data]")) if len(temp_postfile) != 1: return HttpResponseBadRequest(_(u"There was a problem receiving your" u" ODK submission. [Error: multiple " u"submission files (?)]")) postfile = temp_postfile[0] tempdir = tempfile.gettempdir() our_tfpath = os.path.join(tempdir, postfile.name) with open(our_tfpath, 'wb') as f: f.write(postfile.read()) with open(our_tfpath, 'rb') as f: total_count, success_count, errors = import_instances_from_zip( f, posting_user) # chose the try approach as suggested by the link below # http://stackoverflow.com/questions/82831 try: os.remove(our_tfpath) except IOError: # TODO: log this Exception somewhere pass json_msg = { 'message': _(u"Submission complete. Out of %(total)d " u"survey instances, %(success)d were imported, " u"(%(rejected)d were rejected as duplicates, " u"missing forms, etc.)") % {'total': total_count, 'success': success_count, 'rejected': total_count - success_count}, 'errors': u"%d %s" % (len(errors), errors) } audit = { "bulk_submission_log": json_msg } audit_log(Actions.USER_BULK_SUBMISSION, request.user, posting_user, _("Made bulk submissions."), audit, request) response = HttpResponse(json.dumps(json_msg)) response.status_code = 200 response['Location'] = request.build_absolute_uri(request.path) return response
def log_export(request, xform, export_type): # log download as well audit = { "xform": xform.id_string, "export_type": export_type } log.audit_log( log.Actions.EXPORT_DOWNLOADED, request.user, xform.user, _("Downloaded %(export_type)s export on '%(id_string)s'.") % { 'id_string': xform.id_string, 'export_type': export_type.upper() }, audit, request)
def delete_xform(request, username, id_string): xform = get_object_or_404(XForm, user__username__iexact=username, id_string__iexact=id_string) # delete xform and submissions remove_xform(xform) audit = {} audit_log( Actions.FORM_DELETED, request.user, xform.user, _("Deleted form '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) return HttpResponseRedirect(settings.APP_ROOT + "%s" % username)
def toggle_downloadable(request, username, id_string): xform = XForm.objects.get(user__username__iexact=username, id_string__iexact=id_string) xform.downloadable = not xform.downloadable xform.save() audit = {} audit_log( Actions.FORM_UPDATED, request.user, xform.user, _("Made form '%(id_string)s' %(downloadable)s.") % { 'id_string': xform.id_string, 'downloadable': _("downloadable") if xform.downloadable else _("un-downloadable") }, audit, request) return HttpResponseRedirect(settings.APP_ROOT + "%s" % username)
def map_view(request, username, id_string, template='map.html'): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) data = {'content_user': owner, 'xform': xform} data['profile'], created = UserProfile.objects.get_or_create(user=owner) data['form_view'] = True data['jsonform_url'] = reverse(download_jsonform, kwargs={ "username": username, "id_string": id_string }) data['enketo_edit_url'] = reverse('edit_data', kwargs={ "username": username, "id_string": id_string, "data_id": 0 }) data['enketo_add_url'] = reverse('enter_data', kwargs={ "username": username, "id_string": id_string }) data['enketo_add_with_url'] = reverse('add_submission_with', kwargs={ "username": username, "id_string": id_string }) data['mongo_api_url'] = reverse('mongo_view_api', kwargs={ "username": username, "id_string": id_string }) data['delete_data_url'] = reverse('delete_data', kwargs={ "username": username, "id_string": id_string }) data['mapbox_layer'] = MetaData.mapbox_layer_upload(xform) audit = {"xform": xform.id_string} audit_log( Actions.FORM_MAP_VIEWED, request.user, owner, _("Requested map on '%(id_string)s'.") % {'id_string': xform.id_string}, audit, request) return render(request, template, data)
def google_xls_export(request, username, id_string): token = None if request.user.is_authenticated(): try: ts = TokenStorageModel.objects.get(id=request.user) except TokenStorageModel.DoesNotExist: pass else: token = ts.token elif request.session.get('access_token'): token = request.session.get('access_token') if token is None: request.session["google_redirect_url"] = reverse(google_xls_export, kwargs={ 'username': username, 'id_string': id_string }) return HttpResponseRedirect(redirect_uri) owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) valid, dd = dd_for_params(id_string, owner, request) if not valid: return dd ddw = XlsWriter() tmp = NamedTemporaryFile(delete=False) ddw.set_file(tmp) ddw.set_data_dictionary(dd) temp_file = ddw.save_workbook_to_file() temp_file.close() url = google_export_xls(tmp.name, xform.title, token, blob=True) os.unlink(tmp.name) audit = {"xform": xform.id_string, "export_type": "google"} audit_log( Actions.EXPORT_CREATED, request.user, owner, _("Created Google Docs export on '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) return HttpResponseRedirect(url)
def google_xls_export(request, username, id_string): token = None if request.user.is_authenticated(): try: ts = TokenStorageModel.objects.get(id=request.user) except TokenStorageModel.DoesNotExist: pass else: token = ts.token elif request.session.get('access_token'): token = request.session.get('access_token') if token is None: request.session["google_redirect_url"] = reverse( google_xls_export, kwargs={'username': username, 'id_string': id_string}) return HttpResponseRedirect(redirect_uri) owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) valid, dd = dd_for_params(id_string, owner, request) if not valid: return dd ddw = XlsWriter() tmp = NamedTemporaryFile(delete=False) ddw.set_file(tmp) ddw.set_data_dictionary(dd) temp_file = ddw.save_workbook_to_file() temp_file.close() url = google_export_xls(tmp.name, xform.title, token, blob=True) os.unlink(tmp.name) audit = { "xform": xform.id_string, "export_type": "google" } audit_log( Actions.EXPORT_CREATED, request.user, owner, _("Created Google Docs export on '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) return HttpResponseRedirect(url)
def formList(request, username): """ This is where ODK Collect gets its download list. """ formlist_user = get_object_or_404(User, username__iexact=username) profile, created = UserProfile.objects.get_or_create(user=formlist_user) if profile.require_auth: authenticator = HttpDigestAuthenticator() if not authenticator.authenticate(request): return authenticator.build_challenge_response() # unauthorized if user in auth request does not match user in path # unauthorized if user not active if not request.user.is_active: return HttpResponseNotAuthorized() # filter private forms (where require_auth=False) # for users who are non-owner if request.user.username == profile.user.username: xforms = XForm.objects.filter(downloadable=True, user__username__iexact=username) else: xforms = XForm.objects.filter(downloadable=True, user__username__iexact=username, require_auth=False) audit = {} audit_log(Actions.USER_FORMLIST_REQUESTED, request.user, formlist_user, _("Requested forms list."), audit, request) data = { 'host': request.build_absolute_uri().replace(request.get_full_path(), ''), 'xforms': xforms } response = render(request, "xformsList.xml", data, content_type="text/xml; charset=utf-8") response['X-OpenRosa-Version'] = '1.0' tz = pytz.timezone(settings.TIME_ZONE) dt = datetime.now(tz).strftime('%a, %d %b %Y %H:%M:%S %Z') response['Date'] = dt return response
def data_view(request, username, id_string): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) data = {'owner': owner, 'xform': xform} audit = { "xform": xform.id_string, } audit_log( Actions.FORM_DATA_VIEWED, request.user, owner, _("Requested data view for '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) return render(request, "data_view.html", data)
def test_audit_log_call(self): account_user = User(username="******") request_user = User(username="******") request = RequestFactory().get("/") # create a log audit = {} audit_log(Actions.FORM_PUBLISHED, request_user, account_user, "Form published", audit, request) # function should just run without exception so we are good at this # point query for this log entry sort = {"created_on": -1} cursor = AuditLog.query_mongo( account_user.username, None, None, sort, 0, 1) self.assertTrue(cursor.count() > 0) record = cursor.next() self.assertEqual(record['account'], "alice") self.assertEqual(record['user'], "bob") self.assertEqual(record['action'], Actions.FORM_PUBLISHED)
def formList(request, username): """ This is where ODK Collect gets its download list. """ formlist_user = get_object_or_404(User, username__iexact=username) profile, created = UserProfile.objects.get_or_create(user=formlist_user) if profile.require_auth: authenticator = HttpDigestAuthenticator() if not authenticator.authenticate(request): return authenticator.build_challenge_response() # unauthorized if user in auth request does not match user in path # unauthorized if user not active if not request.user.is_active: return HttpResponseNotAuthorized() # filter private forms (where require_auth=False) # for users who are non-owner if request.user.username == profile.user.username: xforms = XForm.objects.filter(downloadable=True, user__username__iexact=username) else: xforms = XForm.objects.filter(downloadable=True, user__username__iexact=username, require_auth=False) audit = {} audit_log(Actions.USER_FORMLIST_REQUESTED, request.user, formlist_user, _("Requested forms list."), audit, request) data = { 'host': request.build_absolute_uri().replace( request.get_full_path(), ''), 'xforms': xforms } response = render(request, "xformsList.xml", data, content_type="text/xml; charset=utf-8") response['X-OpenRosa-Version'] = '1.0' tz = pytz.timezone(settings.TIME_ZONE) dt = datetime.now(tz).strftime('%a, %d %b %Y %H:%M:%S %Z') response['Date'] = dt return response
def zip_export(request, username, id_string): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) helper_auth_helper(request) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) if request.GET.get('raw'): id_string = None attachments = Attachment.objects.filter(instance__xform=xform) zip_file = None try: zip_file = create_attachments_zipfile(attachments) audit = { "xform": xform.id_string, "export_type": Export.ZIP_EXPORT } audit_log( Actions.EXPORT_CREATED, request.user, owner, _("Created ZIP export on '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) # log download as well audit_log( Actions.EXPORT_DOWNLOADED, request.user, owner, _("Downloaded ZIP export on '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) if request.GET.get('raw'): id_string = None response = response_with_mimetype_and_name('zip', id_string) response.write(FileWrapper(zip_file)) response['Content-Length'] = zip_file.tell() zip_file.seek(0) finally: zip_file and zip_file.close() return response
def download_xlsform(request, username, id_string): xform = get_object_or_404(XForm, user__username__iexact=username, id_string__iexact=id_string) owner = User.objects.get(username__iexact=username) helper_auth_helper(request) if not has_permission(xform, owner, request, xform.shared): return HttpResponseForbidden('Not shared.') file_path = xform.xls.name default_storage = get_storage_class()() if file_path != '' and default_storage.exists(file_path): audit = { "xform": xform.id_string } audit_log( Actions.FORM_XLS_DOWNLOADED, request.user, xform.user, _("Downloaded XLS file for form '%(id_string)s'.") % { "id_string": xform.id_string }, audit, request) split_path = file_path.split(os.extsep) extension = 'xls' if len(split_path) > 1: extension = split_path[len(split_path) - 1] response = response_with_mimetype_and_name( 'vnd.ms-excel', id_string, show_date=False, extension=extension, file_path=file_path) return response else: messages.add_message(request, messages.WARNING, _(u'No XLS file for your form ' u'<strong>%(id)s</strong>') % {'id': id_string}) return HttpResponseRedirect(settings.APP_ROOT + "%s" % username)
def download_xform(request, username, id_string): user = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, user=user, id_string__iexact=id_string) profile, created =\ UserProfile.objects.get_or_create(user=user) if profile.require_auth: authenticator = HttpDigestAuthenticator() if not authenticator.authenticate(request): return authenticator.build_challenge_response() audit = {"xform": xform.id_string} audit_log( Actions.FORM_XML_DOWNLOADED, request.user, xform.user, _("Downloaded XML for form '%(id_string)s'.") % {"id_string": xform.id_string}, audit, request) response = response_with_mimetype_and_name('xml', id_string, show_date=False) response.content = xform.xml return response
def data_view(request, username, id_string): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) data = { 'owner': owner, 'xform': xform } audit = { "xform": xform.id_string, } audit_log( Actions.FORM_DATA_VIEWED, request.user, owner, _("Requested data view for '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) return render(request, "data_view.html", data)
def export_download(request, username, id_string, export_type, filename): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) helper_auth_helper(request) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) # find the export entry in the db export = get_object_or_404(Export, xform=xform, filename=filename) if (export_type == Export.GDOC_EXPORT or export_type == Export.EXTERNAL_EXPORT) \ and export.export_url is not None: return HttpResponseRedirect(export.export_url) ext, mime_type = export_def_from_filename(export.filename) audit = { "xform": xform.id_string, "export_type": export.export_type } audit_log( Actions.EXPORT_DOWNLOADED, request.user, owner, _("Downloaded %(export_type)s export '%(filename)s' " "on '%(id_string)s'.") % { 'export_type': export.export_type.upper(), 'filename': export.filename, 'id_string': xform.id_string, }, audit, request) if request.GET.get('raw'): id_string = None default_storage = get_storage_class()() if not isinstance(default_storage, FileSystemStorage): return HttpResponseRedirect(default_storage.url(export.filepath)) basename = os.path.splitext(export.filename)[0] response = response_with_mimetype_and_name( mime_type, name=basename, extension=ext, file_path=export.filepath, show_date=False) return response
def download_xlsform(request, username, id_string): xform = get_object_or_404(XForm, user__username__iexact=username, id_string__iexact=id_string) owner = User.objects.get(username__iexact=username) helper_auth_helper(request) if not has_permission(xform, owner, request, xform.shared): return HttpResponseForbidden('Not shared.') file_path = xform.xls.name default_storage = get_storage_class()() if file_path != '' and default_storage.exists(file_path): audit = {"xform": xform.id_string} audit_log( Actions.FORM_XLS_DOWNLOADED, request.user, xform.user, _("Downloaded XLS file for form '%(id_string)s'.") % {"id_string": xform.id_string}, audit, request) split_path = file_path.split(os.extsep) extension = 'xls' if len(split_path) > 1: extension = split_path[len(split_path) - 1] response = response_with_mimetype_and_name('vnd.ms-excel', id_string, show_date=False, extension=extension, file_path=file_path) return response else: messages.add_message( request, messages.WARNING, _(u'No XLS file for your form ' u'<strong>%(id)s</strong>') % {'id': id_string}) return HttpResponseRedirect(settings.APP_ROOT + "%s" % username)
def export_download(request, username, id_string, export_type, filename): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) helper_auth_helper(request) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) # find the export entry in the db export = get_object_or_404(Export, xform=xform, filename=filename) if (export_type == Export.GDOC_EXPORT or export_type == Export.EXTERNAL_EXPORT) \ and export.export_url is not None: return HttpResponseRedirect(export.export_url) ext, mime_type = export_def_from_filename(export.filename) audit = {"xform": xform.id_string, "export_type": export.export_type} audit_log( Actions.EXPORT_DOWNLOADED, request.user, owner, _("Downloaded %(export_type)s export '%(filename)s' " "on '%(id_string)s'.") % { 'export_type': export.export_type.upper(), 'filename': export.filename, 'id_string': xform.id_string, }, audit, request) if request.GET.get('raw'): id_string = None default_storage = get_storage_class()() if not isinstance(default_storage, FileSystemStorage): return HttpResponseRedirect(default_storage.url(export.filepath)) basename = os.path.splitext(export.filename)[0] response = response_with_mimetype_and_name(mime_type, name=basename, extension=ext, file_path=export.filepath, show_date=False) return response
def map_view(request, username, id_string, template='map.html'): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) data = {'content_user': owner, 'xform': xform} data['profile'], created = UserProfile.objects.get_or_create(user=owner) data['form_view'] = True data['jsonform_url'] = reverse(download_jsonform, kwargs={"username": username, "id_string": id_string}) data['enketo_edit_url'] = reverse('edit_data', kwargs={"username": username, "id_string": id_string, "data_id": 0}) data['enketo_add_url'] = reverse('enter_data', kwargs={"username": username, "id_string": id_string}) data['enketo_add_with_url'] = reverse('add_submission_with', kwargs={"username": username, "id_string": id_string}) data['mongo_api_url'] = reverse('mongo_view_api', kwargs={"username": username, "id_string": id_string}) data['delete_data_url'] = reverse('delete_data', kwargs={"username": username, "id_string": id_string}) data['mapbox_layer'] = MetaData.mapbox_layer_upload(xform) audit = { "xform": xform.id_string } audit_log(Actions.FORM_MAP_VIEWED, request.user, owner, _("Requested map on '%(id_string)s'.") % {'id_string': xform.id_string}, audit, request) return render(request, template, data)
def zip_export(request, username, id_string): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) helper_auth_helper(request) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) if request.GET.get('raw'): id_string = None attachments = Attachment.objects.filter(instance__xform=xform) zip_file = None try: zip_file = create_attachments_zipfile(attachments) audit = {"xform": xform.id_string, "export_type": Export.ZIP_EXPORT} audit_log( Actions.EXPORT_CREATED, request.user, owner, _("Created ZIP export on '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) # log download as well audit_log( Actions.EXPORT_DOWNLOADED, request.user, owner, _("Downloaded ZIP export on '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) if request.GET.get('raw'): id_string = None response = response_with_mimetype_and_name('zip', id_string) response.write(FileWrapper(zip_file)) response['Content-Length'] = zip_file.tell() zip_file.seek(0) finally: zip_file and zip_file.close() return response
def instance(request, username, id_string): xform, is_owner, can_edit, can_view = get_xform_and_perms( username, id_string, request) # no access if not (xform.shared_data or can_view or request.session.get('public_link') == xform.uuid): return HttpResponseForbidden(_(u'Not shared.')) audit = { "xform": xform.id_string, } audit_log( Actions.FORM_DATA_VIEWED, request.user, xform.user, _("Requested instance view for '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) return render( request, 'instance.html', { 'username': username, 'id_string': id_string, 'xform': xform, 'can_edit': can_edit })
def download_xform(request, username, id_string): user = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, user=user, id_string__iexact=id_string) profile, created =\ UserProfile.objects.get_or_create(user=user) if profile.require_auth: authenticator = HttpDigestAuthenticator() if not authenticator.authenticate(request): return authenticator.build_challenge_response() audit = { "xform": xform.id_string } audit_log( Actions.FORM_XML_DOWNLOADED, request.user, xform.user, _("Downloaded XML for form '%(id_string)s'.") % { "id_string": xform.id_string }, audit, request) response = response_with_mimetype_and_name('xml', id_string, show_date=False) response.content = xform.xml return response
def instance(request, username, id_string): xform, is_owner, can_edit, can_view = get_xform_and_perms( username, id_string, request) # no access if not (xform.shared_data or can_view or request.session.get('public_link') == xform.uuid): return HttpResponseForbidden(_(u'Not shared.')) audit = { "xform": xform.id_string, } audit_log( Actions.FORM_DATA_VIEWED, request.user, xform.user, _("Requested instance view for '%(id_string)s'.") % { 'id_string': xform.id_string, }, audit, request) return render(request, 'instance.html', { 'username': username, 'id_string': id_string, 'xform': xform, 'can_edit': can_edit })
def data_export(request, username, id_string, export_type): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) helper_auth_helper(request) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) query = request.GET.get("query") extension = export_type # check if we should force xlsx force_xlsx = request.GET.get('xls') != 'true' if export_type == Export.XLS_EXPORT and force_xlsx: extension = 'xlsx' elif export_type in [Export.CSV_ZIP_EXPORT, Export.SAV_ZIP_EXPORT]: extension = 'zip' audit = { "xform": xform.id_string, "export_type": export_type } # check if we need to re-generate, # we always re-generate if a filter is specified if should_create_new_export(xform, export_type) or query or\ 'start' in request.GET or 'end' in request.GET: # check for start and end params if 'start' in request.GET or 'end' in request.GET: if not query: query = '{}' query = json.dumps( _set_submission_time_to_query(json.loads(query), request)) try: export = generate_export( export_type, extension, username, id_string, None, query) audit_log( Actions.EXPORT_CREATED, request.user, owner, _("Created %(export_type)s export on '%(id_string)s'.") % { 'id_string': xform.id_string, 'export_type': export_type.upper() }, audit, request) except NoRecordsFoundError: return HttpResponseNotFound(_("No records found to export")) else: export = newset_export_for(xform, export_type) # log download as well audit_log( Actions.EXPORT_DOWNLOADED, request.user, owner, _("Downloaded %(export_type)s export on '%(id_string)s'.") % { 'id_string': xform.id_string, 'export_type': export_type.upper() }, audit, request) if not export.filename: # tends to happen when using newset_export_for. return HttpResponseNotFound("File does not exist!") # get extension from file_path, exporter could modify to # xlsx if it exceeds limits path, ext = os.path.splitext(export.filename) ext = ext[1:] if request.GET.get('raw'): id_string = None response = response_with_mimetype_and_name( Export.EXPORT_MIMES[ext], id_string, extension=ext, file_path=export.filepath) return response
def create_export(request, username, id_string, export_type): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) if export_type == Export.EXTERNAL_EXPORT: # check for template before trying to generate a report if not MetaData.external_export(xform=xform): return HttpResponseForbidden(_(u'No XLS Template set.')) query = request.POST.get("query") force_xlsx = request.POST.get('xls') != 'true' # export options group_delimiter = request.POST.get("options[group_delimiter]", '/') if group_delimiter not in ['.', '/']: return HttpResponseBadRequest( _("%s is not a valid delimiter" % group_delimiter)) # default is True, so when dont_.. is yes # split_select_multiples becomes False split_select_multiples = request.POST.get( "options[dont_split_select_multiples]", "no") == "no" binary_select_multiples = getattr(settings, 'BINARY_SELECT_MULTIPLES', False) # external export option meta = request.POST.get("meta") options = { 'group_delimiter': group_delimiter, 'split_select_multiples': split_select_multiples, 'binary_select_multiples': binary_select_multiples, 'meta': meta.replace(",", "") if meta else None } try: create_async_export(xform, export_type, query, force_xlsx, options) except Export.ExportTypeError: return HttpResponseBadRequest( _("%s is not a valid export type" % export_type)) else: audit = { "xform": xform.id_string, "export_type": export_type } audit_log( Actions.EXPORT_CREATED, request.user, owner, _("Created %(export_type)s export on '%(id_string)s'.") % { 'export_type': export_type.upper(), 'id_string': xform.id_string, }, audit, request) return HttpResponseRedirect(reverse( export_list, kwargs={ "username": username, "id_string": id_string, "export_type": export_type }) )
def generate_instance(username, xml_file, media_files, uuid=None): ''' Process an XForm submission as if done via HTTP :param IO xml_file: file-like object containing XML XForm :param string username: username of the Form's owner :param list media_files: a list of UploadedFile objects :param string uuid: an optionnal uuid for the instance. :returns a (status, message) tuple. ''' try: instance = create_instance(username, xml_file, media_files, uuid=uuid) except InstanceInvalidUserError: return { 'code': SMS_SUBMISSION_REFUSED, 'text': _(u"Username or ID required.") } except InstanceEmptyError: return { 'code': SMS_INTERNAL_ERROR, 'text': _(u"Received empty submission. " u"No instance was created") } except FormInactiveError: return { 'code': SMS_SUBMISSION_REFUSED, 'text': _(u"Form is not active") } except XForm.DoesNotExist: return { 'code': SMS_SUBMISSION_REFUSED, 'text': _(u"Form does not exist on this account") } except ExpatError: return { 'code': SMS_INTERNAL_ERROR, 'text': _(u"Improperly formatted XML.") } except DuplicateInstance: return { 'code': SMS_SUBMISSION_REFUSED, 'text': _(u"Duplicate submission") } if instance is None: return { 'code': SMS_INTERNAL_ERROR, 'text': _(u"Unable to create submission.") } user = User.objects.get(username=username) audit = {"xform": instance.xform.id_string} audit_log( Actions.SUBMISSION_CREATED, user, instance.xform.user, _("Created submission on form %(id_string)s.") % {"id_string": instance.xform.id_string}, audit, HttpRequest()) xml_file.close() if len(media_files): [_file.close() for _file in media_files] return { 'code': SMS_SUBMISSION_ACCEPTED, 'text': _(u"[SUCCESS] Your submission has been accepted."), 'id': get_sms_instance_id(instance) }
def submission(request, username=None): if username: formlist_user = get_object_or_404(User, username__iexact=username) profile, created = UserProfile.objects.get_or_create( user=formlist_user) if profile.require_auth: authenticator = HttpDigestAuthenticator() if not authenticator.authenticate(request): return authenticator.build_challenge_response() if request.method == 'HEAD': response = OpenRosaResponse(status=204) if username: response['Location'] = request.build_absolute_uri().replace( request.get_full_path(), '/%s/submission' % username) else: response['Location'] = request.build_absolute_uri().replace( request.get_full_path(), '/submission') return response xml_file_list = [] media_files = [] # request.FILES is a django.utils.datastructures.MultiValueDict # for each key we have a list of values try: xml_file_list = request.FILES.pop("xml_submission_file", []) if len(xml_file_list) != 1: return OpenRosaResponseBadRequest( _(u"There should be a single XML submission file.") ) # save this XML file and media files as attachments media_files = request.FILES.values() # get uuid from post request uuid = request.POST.get('uuid') error, instance = safe_create_instance( username, xml_file_list[0], media_files, uuid, request) if error: return error elif instance is None: return OpenRosaResponseBadRequest( _(u"Unable to create submission.")) audit = { "xform": instance.xform.id_string } audit_log( Actions.SUBMISSION_CREATED, request.user, instance.xform.user, _("Created submission on form %(id_string)s.") % { "id_string": instance.xform.id_string }, audit, request) # response as html if posting with a UUID if not username and uuid: response = _html_submission_response(request, instance) else: response = _submission_response(request, instance) # ODK needs two things for a form to be considered successful # 1) the status code needs to be 201 (created) # 2) The location header needs to be set to the host it posted to response.status_code = 201 response['Location'] = request.build_absolute_uri(request.path) return response except IOError as e: if _bad_request(e): return OpenRosaResponseBadRequest( _(u"File transfer interruption.")) else: raise finally: if len(xml_file_list): [_file.close() for _file in xml_file_list] if len(media_files): [_file.close() for _file in media_files]
def data_export(request, username, id_string, export_type): owner = get_object_or_404(User, username__iexact=username) xform = get_object_or_404(XForm, id_string__iexact=id_string, user=owner) helper_auth_helper(request) if not has_permission(xform, owner, request): return HttpResponseForbidden(_(u'Not shared.')) query = request.GET.get("query") extension = export_type # check if we should force xlsx force_xlsx = request.GET.get('xls') != 'true' if export_type == Export.XLS_EXPORT and force_xlsx: extension = 'xlsx' elif export_type in [Export.CSV_ZIP_EXPORT, Export.SAV_ZIP_EXPORT]: extension = 'zip' audit = {"xform": xform.id_string, "export_type": export_type} # check if we need to re-generate, # we always re-generate if a filter is specified if should_create_new_export(xform, export_type) or query or\ 'start' in request.GET or 'end' in request.GET: # check for start and end params if 'start' in request.GET or 'end' in request.GET: if not query: query = '{}' query = json.dumps( _set_submission_time_to_query(json.loads(query), request)) try: export = generate_export(export_type, extension, username, id_string, None, query) audit_log( Actions.EXPORT_CREATED, request.user, owner, _("Created %(export_type)s export on '%(id_string)s'.") % { 'id_string': xform.id_string, 'export_type': export_type.upper() }, audit, request) except NoRecordsFoundError: return HttpResponseNotFound(_("No records found to export")) else: export = newset_export_for(xform, export_type) # log download as well audit_log( Actions.EXPORT_DOWNLOADED, request.user, owner, _("Downloaded %(export_type)s export on '%(id_string)s'.") % { 'id_string': xform.id_string, 'export_type': export_type.upper() }, audit, request) if not export.filename: # tends to happen when using newset_export_for. return HttpResponseNotFound("File does not exist!") # get extension from file_path, exporter could modify to # xlsx if it exceeds limits path, ext = os.path.splitext(export.filename) ext = ext[1:] if request.GET.get('raw'): id_string = None response = response_with_mimetype_and_name(Export.EXPORT_MIMES[ext], id_string, extension=ext, file_path=export.filepath) return response
def submission(request, username=None): if username: formlist_user = get_object_or_404(User, username__iexact=username) profile, created = UserProfile.objects.get_or_create( user=formlist_user) if profile.require_auth: authenticator = HttpDigestAuthenticator() if not authenticator.authenticate(request): return authenticator.build_challenge_response() if request.method == 'HEAD': response = OpenRosaResponse(status=204) if username: response['Location'] = request.build_absolute_uri().replace( request.get_full_path(), '/%s/submission' % username) else: response['Location'] = request.build_absolute_uri().replace( request.get_full_path(), '/submission') return response xml_file_list = [] media_files = [] # request.FILES is a django.utils.datastructures.MultiValueDict # for each key we have a list of values try: xml_file_list = request.FILES.pop("xml_submission_file", []) if len(xml_file_list) != 1: return OpenRosaResponseBadRequest( _(u"There should be a single XML submission file.")) # save this XML file and media files as attachments media_files = request.FILES.values() # get uuid from post request uuid = request.POST.get('uuid') error, instance = safe_create_instance(username, xml_file_list[0], media_files, uuid, request) if error: return error elif instance is None: return OpenRosaResponseBadRequest( _(u"Unable to create submission.")) audit = {"xform": instance.xform.id_string} audit_log( Actions.SUBMISSION_CREATED, request.user, instance.xform.user, _("Created submission on form %(id_string)s.") % {"id_string": instance.xform.id_string}, audit, request) # response as html if posting with a UUID if not username and uuid: response = _html_submission_response(request, instance) else: response = _submission_response(request, instance) # ODK needs two things for a form to be considered successful # 1) the status code needs to be 201 (created) # 2) The location header needs to be set to the host it posted to response.status_code = 201 response['Location'] = request.build_absolute_uri(request.path) return response except IOError as e: if _bad_request(e): return OpenRosaResponseBadRequest( _(u"File transfer interruption.")) else: raise finally: if len(xml_file_list): [_file.close() for _file in xml_file_list] if len(media_files): [_file.close() for _file in media_files]