Пример #1
0
    def get(self, uuid):
        survey = database.survey.get(current_identity.survey_id)
        start = dateutil.parser.parse(request.values.get('startTime'))
        end = dateutil.parser.parse(request.values.get('endTime'))

        parameters = {
            'break_interval_seconds': survey.trip_break_interval,
            'cold_start_distance_meters':
            survey.trip_break_cold_start_distance,
            'subway_buffer_meters': survey.trip_subway_buffer,
            'accuracy_cutoff_meters': survey.gps_accuracy_threshold
        }
        gps_points = database.mobile_user.coordinates(survey, uuid, start, end)
        trips, summaries = tripbreaker.run(parameters, survey.subway_stops,
                                           gps_points)

        response = {
            'trips': to_trips_geojson(trips, summaries) if trips else {},
            'searchStart': start.isoformat(),
            'searchEnd': end.isoformat()
        }
        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=response)
Пример #2
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))
Пример #3
0
def delete_inactive_survey():
    survey_name = request.form.get('surveyName')
    error = database.survey_admin.delete(survey_name)
    if not error:
        # format the same as jinja2 renders the template
        response = {
            'recent_signups': [],
            'message': 'Survey "{}" deleted.'.format(survey_name)
        }

        for survey in database.survey_admin.get_recent_signups(10):
            response['recent_signups'].append({
                'name':
                survey.name,
                'pretty_name':
                survey.pretty_name,
                'created_at':
                str(survey.created_at.replace(microsecond=0)),
                'active':
                'True' if survey.mobile_coordinates.first() else 'False'
            })

        return Success(status_code=200,
                       headers={'Location': '/manage-surveys/delete'},
                       resource_type='NewSurveySchema',
                       body=response)
    return Error(status_code=400,
                 headers={'Location': '/manage-surveys/delete'},
                 resource_type='NewSurveySchema',
                 errors=[error])
Пример #4
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))
Пример #5
0
    def post(self):
        survey = database.survey.get(current_identity.survey_id)
        data = request.files.get('stops')

        dialect = csv.Sniffer().sniff(data.read(), delimiters=';,')
        data.seek(0)
        reader = csv.DictReader(data, dialect=dialect)
        reader.fieldnames = [name.lower() for name in reader.fieldnames]

        # determine the keys out of the options for the lat/lng columns
        location_columns = None
        location_columns_options = [('latitude', 'longitude'), ('lat', 'lng'),
                                    ('y', 'x')]

        for columns in location_columns_options:
            if set(columns).issubset(set(reader.fieldnames)):
                location_columns = columns

        # insert subway stations into database
        if location_columns:
            rename = ('latitude' and 'longitude') not in location_columns
            if rename:
                reader = self._rename_columns(location_columns, reader)

            subway_stops = database.survey.upsert_subway_stops(survey=survey,
                                                               stops=reader)
            return Success(status_code=201,
                           headers=self.headers,
                           resource_type=self.resource_type,
                           body={'stations': to_prompts_geojson(subway_stops)})
        return Error(status_code=400,
                     headers=self.headers,
                     resource_type=self.resource_type,
                     errors=['Failed to parse subway stops .csv file'])
Пример #6
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))
Пример #7
0
    def post(self):
        validations = [{
            'language': {
                'key': 'language',
                'validator': value_exists,
                'response': Error,
                'error': 'Language selection cannot be blank.',
            },
            'about_text': {
                'key': 'aboutText',
                'validator': value_exists,
                'response': Error,
                'error': 'Survey about text cannot be blank.',
            },
            'terms_of_service': {
                'key': 'termsOfService',
                'validator': value_exists,
                'response': Error,
                'error': 'Survey terms of service name cannot be blank.',
            }
        }]
        validated = validate_json(validations, self.headers,
                                  self.resource_type)
        survey = database.survey.get(current_identity.survey_id)
        database.survey.update(survey,
                               settings=validated,
                               questions=request.json['questions'])

        return Success(status_code=201,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=request.json)
Пример #8
0
    def post(self):
        survey = database.survey.get(current_identity.survey_id)
        img = request.files.get('avatar')

        # delete the previous avatar image file
        if survey.avatar_uri:
            filehandler.delete(survey.avatar_uri)

        # shrink avatar image size
        try:
            thumbnail = filehandler.make_thumbnail(img)
        except IOError as e:
            return Error(status_code=400,
                         headers=self.headers,
                         resource_type=self.resource_type,
                         errors=[e.message])

        filename = filehandler.save(
            thumbnail,
            extensions=set(['.jpg', '.jpeg', '.gif', '.png', '.bmp']))
        # get image uri by finding static folder within avatar path. This
        # is to dynamically include subfolders within the static assets folder
        with current_app.app_context():
            uri = '{base}/user/avatars/{file}'.format(
                base=current_app.config['ASSETS_ROUTE'], file=filename)
            survey.avatar_uri = uri
            database.survey.update(survey)

        return Success(status_code=201,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body={'avatarUri': uri})
Пример #9
0
    def post(self):
        survey = database.survey.get(current_identity.survey_id)
        database.prompts.update(survey=survey, prompts=request.json['prompts'])

        return Success(status_code=201,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=request.json)
Пример #10
0
 def post(self):
     survey = database.survey.get(current_identity.survey_id)
     database.survey.reset(survey)
     survey = database.survey.get_survey_questions_json(survey)
     return Success(status_code=201,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    body={'survey': survey})
Пример #11
0
 def get(self):
     survey = database.survey.get(current_identity.survey_id)
     token = database.web_user.get_invite_researcher_token(survey)
     if not token:
         token = database.web_user.create_invite_researcher_token(survey)
     return Success(status_code=200,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    body={'token': token.token})
Пример #12
0
 def post(self):
     survey = database.survey.get(current_identity.survey_id)
     response = {
         'token':
         database.web_user.create_invite_researcher_token(survey).token
     }
     return Success(status_code=201,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    body=response)
Пример #13
0
def disable_account_recovery_token():
    token_id = request.form['tokenId']
    token = database.token.account_recovery.disable(token_id)
    response = {
        'message': 'WebUserResetPasswordToken {id} disabled.'.format(id=token.id)
    }
    return Success(status_code=201,
                   headers={'Location': '/account-recovery/deactivate'},
                   resource_type='DeactivateNewSurveyToken',
                   body=response)
Пример #14
0
 def delete(self):
     survey = database.survey.get(current_identity.survey_id)
     survey.subway_stops.delete()
     db.session.commit()
     return Success(status_code=200,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    body={'stations': {
                        'features': []
                    }})
Пример #15
0
 def get(self):
     survey = database.survey.get(current_identity.survey_id)
     response = {
         'stations': to_prompts_geojson(survey.subway_stops),
         'bufferSize': survey.trip_subway_buffer
     }
     return Success(status_code=200,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    body=response)
Пример #16
0
    def post(self):
        json_data = json.loads(request.data.decode('utf-8'))
        data = rename_json_keys(json_data, camelcase_to_underscore)
        survey_name = data['survey_name'].lower().strip()

        survey = database.survey.find_by_name(survey_name)
        if not survey:
            return Error(status_code=410,
                         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 = {
                'user': '******',
                'uuid': data['user']['uuid'],
                'contact_email': survey.contact_email,
                '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
            }

            # add in deprecation warning for v1 api
            return Success(
                status_code=201,
                headers=self.headers,
                resource_type=self.resource_type,
                status=
                'Warning (deprecated): API v1 will soon be phased out. Please refer to documentation for v2 calls.',
                body=rename_json_keys(response, underscore_to_camelcase))

        return Error(status_code=400,
                     headers=self.headers,
                     resource_type=self.resource_type,
                     errors=['Could not register new user.'])
Пример #17
0
 def delete(self, email):
     survey = database.survey.get(current_identity.survey_id)
     user = survey.web_users.filter_by(email=email).one_or_none()
     if user:
         database.web_user.delete(user)
         return Success(status_code=201,
                        headers=self.headers,
                        resource_type=self.resource_type,
                        body={})
     return Error(status_code=401,
                  headers=self.headers,
                  resource_type=self.resource_type,
                  errors=['Web user could not be deleted from survey.'])
Пример #18
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))
Пример #19
0
    def get(self):
        survey = database.survey.get(current_identity.survey_id)
        uri = survey.avatar_uri

        # use default avatar if a custom one is not set
        if not uri:
            with current_app.app_context():
                uri = '{base}/static/{avatar}'.format(
                    base=current_app.config['ASSETS_ROUTE'],
                    avatar=current_app.config['DEFAULT_AVATAR_FILENAME'])
        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body={'avatarUri': uri})
Пример #20
0
 def put(self):
     email = request.json.get('email')
     password = request.json.get('password')
     token = request.json.get('token')
     user = database.web_user.update_password(email, password, token)
     if user:
         return Success(status_code=201,
                        headers=self.headers,
                        resource_type=self.resource_type,
                        body={})
     return Error(status_code=401,
                  headers=self.headers,
                  resource_type=self.resource_type,
                  errors=[])
Пример #21
0
    def get(self):
        survey = database.survey.get(current_identity.survey_id)
        sort_fields = json.loads(request.values.get('sorting', '{}'))
        page_index = int(request.values.get('pageIndex'))
        items_per_page = int(request.values.get('itemsPerPage'))

        response = database.web_user.paginated_table(
            survey=survey,
            page_index=page_index,
            items_per_page=items_per_page,
            sort_fields=sort_fields)
        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=response)
Пример #22
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.'])
Пример #23
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))
Пример #24
0
    def delete(self):
        survey = database.survey.get(current_identity.survey_id)
        if survey.avatar_uri:
            filehandler.delete(survey.avatar_uri)

        # reset to default avatar
        with current_app.app_context():
            default_avatar_uri = '{base}/user/{avatar}'.format(
                base=current_app.config['ASSETS_ROUTE'],
                avatar=current_app.config['DEFAULT_AVATAR_FILENAME'])
            survey.avatar_uri = default_avatar_uri
            database.survey.update(survey)

        return Success(status_code=202,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body={'avatarUri': default_avatar_uri})
Пример #25
0
def upload_survey_schema_json():
    if not request.json.get('surveyName'):
        return Error(status_code=400,
                     headers={'Location': '/manage-surveys/schema'},
                     resource_type='NewSurveySchema',
                     errors=['A unique survey name must be provided.'])
    errors = None
    if request.json.get('schema'):
        survey_name = request.json['surveyName']
        error = database.survey_admin.create_from_schema(
            survey_name=survey_name,
            admin_email=request.json['schema']['adminEmail'],
            admin_password=request.json['schema']['adminPassword'],
            language=request.json['schema']['language'],
            survey_questions=request.json['schema']['surveyQuestions'],
            survey_prompts=request.json['schema']['surveyPrompts'])
        if not error:
            # format the same as jinja2 renders the template
            response = {
                'recent_signups': [],
                'message': 'Survey "{}" created.'.format(survey_name)
            }
            for survey in database.survey_admin.get_recent_signups(10):
                response['recent_signups'].append({
                    'name':
                    survey.name,
                    'pretty_name':
                    survey.pretty_name,
                    'created_at':
                    str(survey.created_at.replace(microsecond=0)),
                    'active':
                    'True' if survey.mobile_coordinates.first() else 'False'
                })

            return Success(status_code=201,
                           headers={'Location': '/manage-surveys/schema'},
                           resource_type='NewSurveySchema',
                           body=response)
        errors = [error]

    if not errors:
        errors = ['New survey schema could not be uploaded.']
    return Error(status_code=400,
                 headers={'Location': '/manage-surveys/schema'},
                 resource_type='NewSurveySchema',
                 errors=errors)
    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))
Пример #27
0
    def get(self):
        survey = database.survey.get(current_identity.survey_id)
        start = request.values.get('start')
        end = request.values.get('end')
        period = request.values.get('period')
        get_counts_overview = request.values.get(
            'countsTable').lower() == 'true'
        response = {
            'installationsBarGraph':
            mobile_installations_bargraph(survey, start, end, period),
            'activeUsersLineGraph':
            active_users_linegraph(survey)
        }
        if get_counts_overview is True:
            response['overview'] = survey_overview(survey)

        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=response)
Пример #28
0
def generate_new_survey_token():
    database.token.new_survey.create()
    response = {
        'recent_tokens': [],
        'message': 'New survey sign-up token successfully created.'
    }

    # format the same as jinja2 renders the template
    for token in database.token.new_survey.get_recent(10):
        response['recent_tokens'].append({
            'token': token.token,
            'created_at': str(token.created_at.replace(microsecond=0)),
            'active': str(token.active),
            'usages': token.usages
        })

    return Success(status_code=201,
                   headers={'Location': '/signup-tokens/token'},
                   resource_type='NewSurveyToken',
                   body=response)
    def get(self):
        survey_id = current_identity.survey_id
        start = ciso8601.parse_datetime(request.values.get('start'))
        end = ciso8601.parse_datetime(request.values.get('end'))
        timezone = request.values.get('timezone')
        sse_channel = request.values.get('channel')
        # sse.publish({'msg': 'starting exports...', 'type': 'request-ack'},
        #             channel=sse_channel)

        mobile_data_dump.queue(survey_id, start, end, timezone, sse_channel)
        # mobile_data_dump(survey_id, start, end, timezone, sse_channel)

        response = {
            'start': start.isoformat(),
            'end': end.isoformat()
        }
        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=response)
Пример #30
0
    def post(self):
        email = request.json.get('email')
        base_url = request.json.get('baseUrl')

        token = database.web_user.create_reset_password_token(email)
        if token:
            email_password_token.queue(current_app.config['MAILGUN_DOMAIN'],
                                       current_app.config['MAILGUN_API_KEY'],
                                       base_url, email, token.token)
            # email_password_token(current_app.config['MAILGUN_DOMAIN'],
            #                      current_app.config['MAILGUN_API_KEY'],
            #                      base_url, email, token.token)

            return Success(status_code=201,
                           headers=self.headers,
                           resource_type=self.resource_type,
                           body={})
        return Error(status_code=401,
                     headers=self.headers,
                     resource_type=self.resource_type,
                     errors=['Email not found.'])