Пример #1
0
    def get(self):
        survey = database.survey.get(current_identity.survey_id)
        start_time = database.survey.get_start_time(survey)
        if start_time:
            start_time = start_time.isoformat()

        contact_email = survey.contact_email
        if not contact_email:
            admin_user = database.survey.get_admin(survey)
            contact_email = admin_user.email

        response = {
            'survey_id': survey.id,
            'about_text': survey.about_text,
            'terms_of_service': survey.terms_of_service,
            'contact_email': contact_email,
            'survey_start': start_time,
            'survey_max_days': survey.max_survey_days,
            'survey_max_prompts': survey.max_prompts,
            'survey_record_acceleration': survey.record_acceleration,
            'survey_record_mode': survey.record_mode,
            'gps_accuracy_threshold_meters': survey.gps_accuracy_threshold,
            'tripbreaker_interval_seconds': survey.trip_break_interval,
            'tripbreaker_cold_start_distance_meters':
            survey.trip_break_cold_start_distance,
            'tripbreaker_subway_buffer_meters': survey.trip_subway_buffer
        }
        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=make_keys_camelcase(response))
Пример #2
0
    def post(self):
        results = {}
        # check if a survey with the same name exists
        survey_name = request.json.get('surveyName')
        if survey_name:
            if not database.survey.find_by_name(survey_name):
                results['survey_name'] = True
            else:
                results['survey_name'] = False

        # check if the email already exists in database
        email = request.json.get('email')
        if email:
            if not database.web_user.find_by_email(email):
                results['email'] = True
            else:
                results['email'] = False

        # check that entered signup code is valid
        signup_token = request.json.get('signupCode')
        if signup_token:
            if database.survey.register.validate_token(signup_token):
                results['signup_code'] = True
            else:
                results['signup_code'] = False

        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=make_keys_camelcase(results))
Пример #3
0
    def post(self):
        validations = [{
            'admin_email': {
                'key': 'email',
                'validator': value_exists,
                'response': Error,
                'error': 'Email cannot be blank.',
            },
            'admin_password': {
                'key': 'password',
                'validator': value_exists,
                'response': Error,
                'error': 'Password cannot be blank.',
            },
            'survey_name': {
                'key': 'surveyName',
                'validator': value_exists,
                'response': Error,
                'error': 'Survey name cannot be blank.',
            },
            'signup_code': {
                'key': 'signupCode',
                'validator': database.survey.register.use_token,
                'response': Error,
                'error': 'Survey sign-up token is invalid.',
            }
        }]

        validated = validate_json(validations, self.headers,
                                  self.resource_type)

        errors = []
        survey = database.survey.register.create(
            survey_name=validated['survey_name'])
        if survey:
            admin_role = database.web_user.create_admin(
                survey=survey,
                email=validated['admin_email'],
                password=validated['admin_password'])
            reseacher_token = database.web_user.create_invite_researcher_token(
                survey)
        else:
            errors.append('Survey already exists.')

        if not errors:
            if not admin_role:
                errors.append('Admin user could not be created.')
            if not reseacher_token:
                errors.append(
                    'Initial invite reseacher token could not be created.')

        if errors:
            return Error(status_code=400,
                         headers=self.headers,
                         resource_type=self.resource_type,
                         errors=errors)
        return Success(status_code=201,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=make_keys_camelcase(validated))
Пример #4
0
def to_prompts_geojson(query_result, group_by=None):
    # group multiple prompt responses into a single feature
    sorted_prompts = []
    if group_by:
        grouped_prompts = {}
        grouped_responses = {}
        for row in query_result:
            timestamp = getattr(row, group_by).isoformat()
            grouped_prompts.setdefault(timestamp, []).append(row)
            response_str = row.response
            if isinstance(row.response, list):
                response_str = ', '.join(row.response)
            grouped_responses.setdefault(timestamp, []).append(response_str)

        for timestamp, prompts in sorted(grouped_prompts.items()):
            for prompt in prompts:
                prompt.responses = grouped_responses[timestamp]
                sorted_prompts.append(prompt)
    else:
        sorted_prompts = query_result

    # generate the geojson data
    geojson = {
        'type': 'FeatureCollection',
        'features': []
    }
    cols = None
    for row in sorted_prompts:
        if not cols:
            cols = row.__table__.columns.keys()
            cols.pop(cols.index('latitude'))
            cols.pop(cols.index('longitude'))

            if group_by:
                cols.pop(cols.index('response'))
                cols.append('responses')

        feature = {
            'type': 'Feature',
            'properties': {},
            'geometry': {
                'type': 'Point',
                'coordinates': [float(row.longitude), float(row.latitude)]
            }
        }

        for col in cols:
            value = getattr(row, col)
            if isinstance(value, datetime):
                value = value.isoformat()
            if isinstance(value, Decimal):
                value = float(value)
            feature['properties'][col] = value
        feature = make_keys_camelcase(feature)
        geojson['features'].append(feature)
    return geojson
Пример #5
0
 def get(self):
     survey = database.survey.get(current_identity.survey_id)
     prompts = database.prompts.formatted_prompt_questions(survey)
     response = {
         'survey_id': survey.id,
         'prompts': prompts,
         'started':
         True if database.survey.get_start_time(survey) else False
     }
     return Success(status_code=200,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    body=make_keys_camelcase(response))
Пример #6
0
    def post(self):
        data = json.loads(request.data)
        survey_name = data['survey_name'].lower()

        survey = database.survey.find_by_name(survey_name)
        if not survey:
            return Error(status_code=400,
                         headers=self.headers,
                         resource_type=self.resource_type,
                         errors=['Specified survey not found'])

        user = database.user.create(survey=survey, user_data=data['user'])

        if user:
            survey_json = database.survey.formatted_survey_questions(survey)
            prompts_json = database.survey.formatted_survey_prompts(survey)
            # supply a default max_prompts value of 0 if no prompts are set instead of None
            max_prompts = survey.max_prompts if len(prompts_json) > 0 else 0
            response = {
                'survey_id': survey.id,
                'user': '******',
                'uuid': data['user']['uuid'],
                'default_avatar': get_default_avatar_path(),
                'avatar': survey.avatar_uri,
                'survey': survey_json,
                'prompt': {
                    'max_days': survey.max_survey_days,
                    'max_prompts': max_prompts,
                    'num_prompts': len(prompts_json),
                    'prompts': prompts_json
                },
                'lang': survey.language,
                'about_text': survey.about_text,
                'terms_of_service': survey.terms_of_service,
                'survey_name': survey.pretty_name,
                'record_acceleration': survey.record_acceleration,
                'record_mode': survey.record_mode
            }
            return Success(status_code=201,
                           headers=self.headers,
                           resource_type=self.resource_type,
                           body=make_keys_camelcase(response))

        return Error(status_code=400,
                     headers=self.headers,
                     resource_type=self.resource_type,
                     errors=['Could not register new user.'])
Пример #7
0
 def get(self):
     survey = database.survey.get(current_identity.survey_id)
     response = {
         'language': survey.language,
         'about_text': survey.about_text,
         'terms_of_service': survey.terms_of_service,
         'max_days': survey.max_survey_days,
         'max_prompts': survey.max_prompts,
         'survey': database.survey.get_survey_questions_json(survey),
         'survey_id': survey.id,
         'started':
         True if database.survey.get_start_time(survey) else False
     }
     return Success(status_code=200,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    body=make_keys_camelcase(response))
def mobile_data_dump(survey_id, start, end, timezone, sse_channel):
    survey = database.survey.get(survey_id)
    event_start_response = {
        'start': start.isoformat(),
        'end': end.isoformat(),
        'type': 'raw-export-started'
    }
    sse.publish(event_start_response, channel=sse_channel)
    basepath = os.path.join('user', 'exports')
    database.export._begin('raw', survey, basepath, start, end)
    basename = survey.pretty_name + '-responses'
    data = database.export.survey_data(survey, start, end, timezone)
    zip_filename = save_zip(basepath=basepath, basename=basename, data=data)
    export = database.export._finish('raw', survey, basepath, zip_filename)
    event_finished_response = make_keys_camelcase(export)
    event_finished_response['type'] = 'raw-export-complete'
    sse.publish(event_finished_response, channel=sse_channel)
    def get(self):
        survey = database.survey.get(current_identity.survey_id)
        start = database.survey.get_start_time(survey)

        response = {
            'message': 'Survey has not begun.',
            'start_time': None,
            'last_export': None
        }

        if start:
            response['message'] = 'Survey has started'
            response['start_time'] = start.isoformat()
            response['last_export'] = survey.last_export

        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=make_keys_camelcase(response))
Пример #10
0
    def post(self):
        validations = [{
            'about_text': {
                'key': 'aboutText',
                'validator': None,
            },
            'terms_of_service': {
                'key': 'termsOfService',
                'validator': None
            },
            'contact_email': {
                'key': 'contactEmail',
                'validator': value_exists,
                'response': Error,
                'error': 'A contact email address must be specified.'
            },
            'survey_max_days': {
                'key': 'surveyMaxDays',
                'validator': value_exists,
                'response': Error,
                'error':
                'A maximum number of survey prompt days must be entered.',
            },
            'survey_max_prompts': {
                'key': 'surveyMaxPrompts',
                'validator': value_exists,
                'response': Error,
                'error': 'A maximum number of survey prompts must be entered.',
            },
            'gps_accuracy_meters': {
                'key':
                'gpsAccuracyThresholdMeters',
                'validator':
                value_exists,
                'response':
                Error,
                'error':
                'A minimum GPS accuracy threshold must be specified. (Higher threshold is lower accuracy)'
            },
            'tripbreaker_interval_seconds': {
                'key': 'tripbreakerIntervalSeconds',
                'validator': value_exists,
                'response': Error,
                'error': 'Trip breaking interval must be provided.'
            },
            'tripbreaker_cold_start_meters': {
                'key': 'tripbreakerColdStartDistanceMeters',
                'validator': value_exists,
                'response': Error,
                'error': 'Trip breaking cold start distance must be provided.'
            },
            'tripbreaker_subway_buffer_meters': {
                'key': 'tripbreakerSubwayBufferMeters',
                'validator': value_exists,
                'response': Error,
                'error': 'Trip breaking subway buffer must be provided.'
            }
        }]
        validated = validate_json(validations, self.headers,
                                  self.resource_type)
        survey = database.survey.get(current_identity.survey_id)
        survey.about_text = validated['about_text']
        survey.terms_of_service = validated['terms_of_service']
        survey.contact_email = validated['contact_email']
        survey.max_survey_days = validated['survey_max_days']
        survey.max_prompts = validated['survey_max_prompts']
        survey.gps_accuracy_threshold = validated['gps_accuracy_meters']
        survey.trip_break_interval = validated['tripbreaker_interval_seconds']
        survey.trip_break_cold_start_distance = validated[
            'tripbreaker_cold_start_meters']
        survey.trip_subway_buffer = validated[
            'tripbreaker_subway_buffer_meters']
        db.session.commit()

        return Success(status_code=201,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=make_keys_camelcase(validated))
Пример #11
0
    def post(self):
        validations = [{
            'email': {
                'key': 'email',
                'validator': value_exists,
                'response': Error,
                'error': 'Email cannot be blank.',
            },
            'password': {
                'key': 'password',
                'validator': value_exists,
                'response': Error,
                'error': 'Password cannot be blank.',
            },
            'survey_name': {
                'key': 'surveyName',
                'validator': value_exists,
                'response': Error,
                'error': 'Survey name cannot be blank.',
            }
        }]
        validated = validate_json(validations, self.headers,
                                  self.resource_type)
        survey = database.survey.find_by_name(validated['survey_name'])

        # create a researcher user if a signup token is provided
        researcherToken = request.json.get('registrationToken', '').strip()
        if researcherToken:
            user = database.web_user.create_researcher(
                survey=survey,
                email=validated['email'],
                password=validated['password'],
                token=researcherToken)

            if user is False:
                return Error(status_code=400,
                             headers=self.headers,
                             resource_type=self.resource_type,
                             errors=['Web user already exists for email.'])
            elif user is None:
                return Error(status_code=403,
                             headers=self.headers,
                             resource_type=self.resource_type,
                             errors=['Researcher user could not be created.'])

        else:
            mobile_user = database.mobile_user.find_by_email(
                email=validated['email'])
            if not mobile_user:
                return Error(
                    status_code=404,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    errors=[
                        'Participant email not found in any survey response.'
                    ])
            else:
                user = database.web_user.create_participant(
                    survey,
                    email=validated['email'],
                    password=validated['password'],
                    uuid=mobile_user.uuid)
                if user is False:
                    return Error(
                        status_code=400,
                        headers=self.headers,
                        resource_type=self.resource_type,
                        errors=['Participant user could not be created.'])
        return Success(status_code=201,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=make_keys_camelcase(validated))