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)