def __call__(self, req): return render_to_response(self.template, req, status=self.code, path=req.path)
def render(self, req, system, format, instrument_file, form_file, calculationset_file, outname): # Allow only GET and HEAD requests. if req.method not in ('POST', ): raise HTTPMethodNotAllowed() # GENERATE DATA OBJECTS if format == 'yaml': instrument = yaml.safe_load(instrument_file.content) form = yaml.safe_load(form_file.content) calculationset = (yaml.safe_load(calculationset_file.content) if calculationset_file and hasattr( calculationset_file, 'content') else None) else: # JSON files instrument = simplejson.loads(instrument_file.content.read()) form = simplejson.loads(form_file.content.read()) calculationset = (simplejson.loads( calculationset_file.content.read()) if calculationset_file and hasattr(calculationset_file, 'content') else None) # VALIDATE UPLOADED RIOS FILES try: val_type = 'Instrument' validate_instrument(instrument) val_type = 'Form' validate_form(form, instrument=instrument) if calculationset: val_type = 'Calculationset' validate_calculationset(calculationset, instrument=instrument) except ValidationError as exc: error = Error((val_type + ' file validation error:'), str(exc)) return render_to_response(self.convert_fail_template, req, errors=[ str(error), ], system=system) else: # Rewind file objects instrument_file.content.seek(0) form_file.content.seek(0) calculationset_file.content.seek(0) # API INITALIZATION session = datetime.datetime.now().strftime('%Y%m%d%H%M%S%f') converter_kwargs = { 'instrument': instrument, 'form': form, 'calculationset': calculationset, 'localization': DEFAULT_LOCALIZATION, 'suppress': True, # Need logged messages } log(session, 'rios_to_%s' % (system, ), '') log(session, 'conversion_params.log', repr(converter_kwargs)) # PROCESS FILE if system == 'redcap': result = rios_to_redcap(**converter_kwargs) else: # system == 'qualtrics' result = rios_to_qualtrics(**converter_kwargs) # PROCESS RESULT AND RETURN RELEVANT FILE if 'instrument' in result: # Initialize zip file zip_container = cStringIO.StringIO() zip_filename = outname + '.zip' # Process data structures and insert into zip with ZIPFILE.ZipFile(zip_container, 'a', ZIPFILE.ZIP_DEFLATED) \ as zipfile: # Write instrument file to zip instrument_name = (str(outname) + ('.csv' if system == 'redcap' else '.txt')) write_to_zip( zipfile=zipfile, name=instrument_name, payload=result['instrument'], format='csv', ) # Write log file to zip if 'logs' in result: log_name = 'conversion_log.txt' write_to_zip(zipfile=zipfile, name=log_name, payload=result['logs'], format=None) # Rewrind zipfile object zip_container.seek(0) log(session, 'output.zip', zip_container) response = BufferedFileApp(zip_container, zip_filename) return response(req) elif 'failure' in result: fail_log = str(result['failure']) log(session, 'failure.log', fail_log) return render_to_response(self.convert_fail_template, req, errors=[ fail_log, ], system=system) else: # Conversion result does not contain the proper structure error = Error('Unexpected serve side error occured', 'Unable to convert data dictionary at this time') log(session, 'error.log', str(error)) return render_to_response(self.convert_fail_template, req, errors=[ str(error), ], system=system)
def render(self, req): return render_to_response(self.template, req, status=200)
def render(self, req, system, format, instrument_title, instrument_id, outname, infile): # Allow only GET and HEAD requests. if req.method not in ('POST', ): raise HTTPMethodNotAllowed() # Construct proper instrument ID if 'urn:' not in instrument_id: instrument_id = 'urn:%s' % (instrument_id, ) # Check for required redcap paramters if system == 'redcap': initialization_errors = [] if not instrument_id: initialization_errors.append('Instrument ID is required') if not instrument_title: initialization_errors.append('Instrument Title is required') if len(initialization_errors) > 0: return render_to_response( self.form_params_fail_template, req, errors=initialization_errors, ) # Validate file with props.csvtoolkit validator API upload_file = infile.content upload_file.seek(0) # VALIDATE UPLOADED FILE if system == 'redcap': try: # Pre-validation processing self.reader = CsvReader(upload_file) # noqa: F821 self.reader.load_attributes() upload_file.seek(0) # Determine and initialize validator first_field = self.reader.attributes[0] if first_field == 'Variable / Field Name': # Process new CSV format self.validator = RedcapModernCsvValidator elif first_field == 'fieldID': # Process legacy CSV format self.validator = RedcapLegacyCsvValidator else: error = Error( "Unknown input CSV header format. Got values:", ", ".join(self.reader.attributes)) error.wrap("Expected first header/field name value to be:", "\"Variable / Field Name\" or \"fieldID\"") raise error except Exception as exc: error = Error( "Unable to parse REDCap data dictionary. Got error:", (str(exc) if isinstance(exc, Error) else repr(exc))) return render_to_response( self.validation_fail_template, req, errors=str(error), system=system, ) else: # Perform validation result = self.validator(StringLoader(upload_file))() if not result.validation: return render_to_response( self.validation_fail_template, req, errors=result.log, system=system, ) else: # system == 'qualtrics', pre-validated in self.parameters try: simplejson.load(infile) except Exception: error = Error("Qualtrics file validation failed:", "The file content is not valid JSON text") error.wrap("Error:", str(exc)) error.wrap("Please try again with a valid QSF file") return render_to_response( self.validation_fail_template, req, errors=str(error), system=system, ) # Rewind file upload_file.seek(0) # API INITIALIATION session = datetime.datetime.now().strftime('%Y%m%d%H%M%S%f') if system == 'redcap': converter_kwargs = { 'instrument_version': DEFAULT_VERSION, 'localization': DEFAULT_LOCALIZATION, 'description': '', 'title': instrument_title, 'id': instrument_id, 'stream': upload_file, 'suppress': True, # Need logged messages } else: # system == 'qualtrics' converter_kwargs = { 'stream': upload_file, 'suppress': True, # Need logged messages 'filemetadata': True, # Pull metadata from file } # LOG INITIALIZATION log(session, '%s_to_rios' % (system, ), '') log(session, 'uploaded_file_contents.log', upload_file.read()) log(session, 'conversion_params.log', repr(converter_kwargs)) # PROCESS FILE result = self.converters[system](**converter_kwargs) # PROCESS RESULT AND RETURN RELEVANT FILES if all(key in result for key in ( 'form', 'instrument', )): # Initialize zip file zip_container = cStringIO.StringIO() zip_filename = outname + '.zip' # Process data structures and insert into zip with ZIPFILE.ZipFile(zip_container, 'a', ZIPFILE.ZIP_DEFLATED) \ as zipfile: # Write instrument file to zip instrument_name = str(outname) + '_i.' + str(format) write_to_zip( zipfile=zipfile, name=instrument_name, payload=result['instrument'], format=format, ) # Write form file to zip form_name = str(outname) + '_f.' + str(format) write_to_zip( zipfile=zipfile, name=form_name, payload=result['form'], format=format, ) # Write calculationset to zipfile if 'calculationset' in result: calc_name = str(outname) + '_c.' + str(format) write_to_zip( zipfile=zipfile, name=calc_name, payload=result['calculationset'], format=format, ) # Write log file to zip if 'logs' in result: log_name = 'conversion_log.txt' write_to_zip(zipfile=zipfile, name=log_name, payload=result['logs'], format=None) # Rewrind zipfile object zip_container.seek(0) log(session, 'output.zip', zip_container) response = BufferedFileApp(zip_container, zip_filename) return response(req) elif 'failure' in result: fail_log = str(result['failure']) log(session, 'failure.log', fail_log) return render_to_response(self.convert_fail_template, req, errors=[ fail_log, ], system=system) else: # Conversion result does not contain the proper structure error = Error('Unexpected serve side error occured', 'Unable to convert data dictionary at this time') log(session, 'error.log', str(error)) return render_to_response(self.convert_fail_template, req, errors=[ str(error), ], system=system)
def render(self, req): response = render_to_response(self.template, req, status=200) html_output = docutils.core.publish_string(response.body, writer_name='html') return Response(html_output)