コード例 #1
0
    def put(self, username, goal_id, start_at, duration, start_value,
            target_value, category_id, **kwargs):
        profile = get_auth_profile_or_abort(username, "goal")
        goal = profile.get_goal_by_id(goal_id)

        if goal is None:
            report_error_and_abort(422, "goal", "Goal not found")

        if goal.end_at < dt.datetime.utcnow():
            report_error_and_abort(422, "goal", "Goal already expired")

        category = GoalCategory.get_by_id(category_id)

        if category is None:
            report_error_and_abort(422, "goal", "Goal category not found")

        if start_value == target_value:
            report_error_and_abort(422, "goal",
                                   "Goal target value equals start value")

        utc_start_at = start_at - start_at.utcoffset()

        goal.category = category
        goal.start_at = utc_start_at
        goal.end_at = utc_start_at + dt.timedelta(days=duration)
        goal.start_value = start_value
        goal.target_value = target_value

        try:
            goal.save()
        except:
            db.session.rollback()
            report_error_and_abort(500, "goal", "Unable to update goal")

        return goal, 200
コード例 #2
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
	def post(self, username, confirmation_code, **kwargs):

		user = User.find_by_username(username)

		if not user:
			report_error_and_abort(422, "confirmation", "Confirmation failed.")
		
		confirmation = UserConfirmation.find_by_username(username)
		
		if not confirmation:
			report_error_and_abort(422, "confirmation", "Confirmation failed.")

		if not confirmation.check_code(confirmation_code):
			report_error_and_abort(422, "confirmation", "Confirmation failed (invalid code)")

		if not confirmation.check_expiration(self.CONFIRMATION_CODE_EXPIRY_S):
			report_error_and_abort(422, "confirmation", "Confirmation failed (activation code expired)")

		# If we reach here we have a valid user and confirmation code
		try:
			confirmation.delete()
			user.confirmed = True
			user.updated_at = dt.datetime.utcnow()
			user.save()
		except:
			db.session.rollback()
			report_error_and_abort(500, "confirmation", "Unable to confirm user")

		return user, 200
コード例 #3
0
    def put(self,
            username,
            workout_id,
            name,
            start_at,
            distance,
            duration,
            category_id,
            climb=None,
            edited=None):
        profile = get_auth_profile_or_abort(username, "workout")
        workout = profile.get_workout_by_id(workout_id)

        if workout is None:
            report_error_and_abort(422, "workout", "Workout not found")

        category = WorkoutCategoryModel.get_by_id(category_id)

        if category is None:
            report_error_and_abort(422, "workout",
                                   "Workout category not found")

        if name is None or name == "":
            name = category.name

        utc_start_at = start_at - start_at.utcoffset()
        now = dt.datetime.utcnow().replace(tzinfo=pytz.UTC)

        if utc_start_at > now:
            report_error_and_abort(422, "workout",
                                   "Workout start time is in the future")

        # remove data from goal before registering updated
        try:
            remove_workout_data_from_goals(profile, workout)
        except:
            db.session.rollback()
            report_error_and_abort(500, "workout", "Unable to update workout")

        # update category
        workout.category = category
        workout.name = name
        workout.start_at = utc_start_at
        workout.distance = distance
        workout.duration = duration

        if climb is not None:
            workout.climb = climb

        if edited is not None:
            workout.edited = edited

        try:
            workout.save()
            add_workout_data_to_goals(profile, workout)
        except:
            db.session.rollback()
            report_error_and_abort(500, "workout", "Unable to update workout")

        return workout, 200
コード例 #4
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
    def get(self, disc_id, **kwargs):
        discipline = DisciplineModel.get_by_id(disc_id)

        if discipline is None:
            report_error_and_abort(404, "discipline", "Discipline not found.")

        return discipline
コード例 #5
0
    def get(self, username, goal_id):
        profile = get_auth_profile_or_abort(username, "goal")
        goal = profile.get_goal_by_id(goal_id)

        if goal is None:
            report_error_and_abort(404, "goal", "Goal not found.")

        return goal
コード例 #6
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
	def get(self, **kwargs):
		auth_username = get_jwt_identity()
		user = User.find_by_username(auth_username)

		if user is None: # should not be possible as we are auth'ed
			report_error_and_abort(422, "user", "User not found")
		
		return user
コード例 #7
0
def get_auth_profile_or_abort(username, module_name="profile"):
    auth_username = get_jwt_identity()
    if auth_username != username:
        report_error_and_abort(422, module_name, "Profile not found")

    user = User.find_by_username(auth_username)
    if user.profile is None:  # should not be possible to have a user without a profile
        report_error_and_abort(422, module_name, "Profile not found")

    return user.profile
コード例 #8
0
    def get(self, username, workout_id):
        profile = get_auth_profile_or_abort(username, "workout")
        workout = profile.get_workout_by_id(workout_id)

        if workout is None:
            report_error_and_abort(404, "workout", "Workout not found.")

        if workout.category.supports_gps_data:
            workout.register_extended_data()
        return workout
コード例 #9
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
	def post(self):
		username = get_jwt_identity()
		user = User.find_by_username(username)

		if user is None:
			report_error_and_abort(401, "refresh", "Login refresh failed")
		
		user.access_token = create_access_token(identity=user.username, fresh=False)
		TokenRegistry.add_token(user.access_token)
		return user, 200
コード例 #10
0
    def get(self, token_id, **kwargs):
        auth_username = get_jwt_identity()
        user_token = TokenRegistry.get_by_id(token_id)

        if user_token is None:
            report_error_and_abort(404, "token", "Token not found.")

        if user_token.username != auth_username:
            report_error_and_abort(403, "token",
                                   "Other user's token requested.")

        return user_token
コード例 #11
0
    def get(self, username, goal_id=None, limit=10, offset=0):
        profile = get_auth_profile_or_abort(username, "workout")

        if goal_id is None:
            return profile.get_workouts(limit, offset)

        goal = profile.get_goal_by_id(goal_id)

        if goal is None:
            report_error_and_abort(422, "workout", "Goal not found.")

        return Workout.get_workouts_for_goal(goal)
コード例 #12
0
def save_uploaded_file_or_abort(uploaded_file, profile_name):
    filename = secure_filename("{0}_{1}".format(profile_name,
                                                uploaded_file.filename))
    filepath = path.join(current_app.config["GPX_UPLOAD_DIR"], filename)

    try:
        uploaded_file.save(filepath)
    except:
        report_error_and_abort(422, "workout",
                               "Workout file could not be read.")

    return filepath
コード例 #13
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
    def get(self, username, **kwargs):
        auth_username = get_jwt_identity()

        if auth_username != username:
            report_error_and_abort(422, "profile", "Profile not found")

        user = User.find_by_username(auth_username)

        if user.profile is None:  # should not be possible to have a user without a profile
            report_error_and_abort(422, "profile", "Profile not found")

        # load profile from db
        return user.profile, 200
コード例 #14
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
	def delete(self):
		jti = get_raw_jwt()["jti"]
		token = TokenRegistry.find_by_jti(jti)

		if token is not None:
			try:
				token.revoked = False
				token.save()
			except:
				db.session.rollback()
				report_error_and_abort(500, "logout", "Logout failed(2).")				

		return generate_message_response(200, "logout", "Logged out.")
コード例 #15
0
    def post(self, username, start_at, duration, start_value, target_value,
             category_id):
        profile = get_auth_profile_or_abort(username, "goal")
        category = GoalCategory.get_by_id(category_id)
        current_value = 0

        if category is None:
            report_error_and_abort(422, "goal", "Goal category not found")

        utc_start_at = start_at - start_at.utcoffset()
        utc_end_at = utc_start_at + dt.timedelta(days=duration)
        now = dt.datetime.utcnow().replace(tzinfo=pytz.UTC)

        if utc_end_at < now:
            report_error_and_abort(422, "goal", "Goal already expired")

        if start_value == target_value:
            report_error_and_abort(422, "goal",
                                   "Goal target value equals start value")

        if category.name == "Weight loss":
            current_value = start_value

        try:
            new_goal = Goal(profile.id, category, utc_start_at, utc_end_at,
                            start_value, target_value, current_value)
            new_goal.save()
        except:
            db.session.rollback()
            report_error_and_abort(500, "goal", "Unable to create goal.")

        return new_goal, 200, {
            'Location': '{}/{}'.format(request.path, new_goal.id)
        }
コード例 #16
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
    def post(self, username):
        profile = get_auth_profile_or_abort(username, "polar")
        polar_user = profile.get_polar_data()

        if polar_user is None:
            polar_user = PolarUser(profile.id, profile.username)

        if not polar_user.has_valid_access_token():
            polar_user.generate_state_code()
        else:
            polar_user.state = None

        try:
            polar_user.updated_at = dt.datetime.utcnow()
            polar_user.save()
        except:
            db.session.rollback()
            report_error_and_abort(500, "polar", "Failed to retrieve data.")

        return polar_user
コード例 #17
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
    def get(self, username):
        profile = get_auth_profile_or_abort(username, "polar")
        polar_user = profile.get_polar_data()

        if polar_user is None:
            return {}, 204  # no data

        if not polar_user.has_valid_access_token():
            if polar_user.state is None:
                polar_user.generate_state_code()
        else:
            polar_user.state = None

        try:
            polar_user.save()
        except:
            db.session.rollback()
            report_error_and_abort(500, "polar", "Failed to retrieve data.")

        return polar_user
コード例 #18
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
    def post(self, name, length, is_route, **kwargs):
        auth_username = get_jwt_identity()
        discipline = DisciplineModel.find_by_name(name)

        if discipline is not None:
            report_error_and_abort(409, "discipline",
                                   "Discipline name already exists.")

        try:
            new_discipline = DisciplineModel(name, length, auth_username,
                                             is_route)
            new_discipline.save()
        except:
            db.session.rollback()
            report_error_and_abort(500, "discipline",
                                   "Unable to create discipline.")

        return new_discipline, 200, {
            'Location': '{}/{}'.format(request.path, new_discipline.id)
        }
コード例 #19
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
    def get(self, username, start_at=None, end_at=None):
        auth_username = get_jwt_identity()

        if auth_username != username:
            report_error_and_abort(422, "profile", "Profile not found")

        user = User.find_by_username(auth_username)

        if user.profile is None:  # should not be possible to have a user without a profile
            report_error_and_abort(422, "profile", "Profile not found")

        weight_list = []
        if start_at is not None and end_at is not None:
            start_date = dt.datetime(start_at.year, start_at.month,
                                     start_at.day, 0, 0, 0)
            end_date = dt.datetime(end_at.year, end_at.month, end_at.day, 23,
                                   59, 59, 999999)
            weight_list = user.profile.weights.filter(
                and_(ProfileWeightHistory.created_at > start_date,
                     ProfileWeightHistory.created_at < end_date)).order_by(
                         ProfileWeightHistory.created_at.desc()).all()
        elif start_at is not None:
            start_date = dt.datetime(start_at.year, start_at.month,
                                     start_at.day, 0, 0, 0)
            weight_list = user.profile.weights.filter(
                ProfileWeightHistory.created_at > start_date).order_by(
                    ProfileWeightHistory.created_at.desc()).all()
        elif end_at is not None:
            end_date = dt.datetime(end_at.year, end_at.month, end_at.day, 23,
                                   59, 59, 999999)
            weight_list = user.profile.weights.filter(
                ProfileWeightHistory.created_at < end_date).order_by(
                    ProfileWeightHistory.created_at.desc()).all()
        else:
            weight_list = user.profile.weights.order_by(
                ProfileWeightHistory.created_at.desc()).all()

        return weight_list
コード例 #20
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
	def post(self, email, password, **kwargs):
		user = User.find_by_email(email)

		if user is None:
		   report_error_and_abort(401, "login", "Login failed") 

		if not user.confirmed:
			report_error_and_abort(401, "login", "Login failed")

		if not user.check_password(password):
			report_error_and_abort(401, "login", "Login failed")
		
		user.access_token = create_access_token(identity=user.username, fresh=True)
		TokenRegistry.add_token(user.access_token)
		return user, 200
コード例 #21
0
    def delete(self, token_id, **kwargs):
        auth_username = get_jwt_identity()
        user_token = TokenRegistry.get_by_id(token_id)

        if user_token is None:
            report_error_and_abort(404, "token", "Token not found.")

        if user_token.username != auth_username:
            report_error_and_abort(403, "token",
                                   "Cannot delete other user's token.")

        try:
            user_token.delete()
        except:
            db.session.rollback()
            report_error_and_abort(500, "profile", "Unable to delete profile")

        return generate_message_response(200, "token", "Token deleted.")
コード例 #22
0
    def put(self, token_id, revoked, **kwargs):
        auth_username = get_jwt_identity()
        user_token = TokenRegistry.get_by_id(token_id)

        if user_token is None:
            report_error_and_abort(404, "token", "Token not found.")

        if user_token.username != auth_username:
            report_error_and_abort(403, "token",
                                   "Cannot update other user's token.")

        try:
            user_token.revoked = revoked
            user_token.save()
        except:
            db.session.rollback()
            report_error_and_abort(500, "profile", "Unable to update token")

        return user_token
コード例 #23
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
    def put(self,
            username,
            height=None,
            weight=None,
            birth_date=None,
            **kwargs):
        auth_username = get_jwt_identity()

        if auth_username != username:
            report_error_and_abort(422, "profile", "Profile not found")

        user = User.find_by_username(auth_username)

        if user.profile is None:  # should not be possible to have a user without a profile
            report_error_and_abort(422, "profile", "Profile not found")

        was_updated = False

        if (height is not None):
            user.profile.set_height(height)
            was_updated = True

        if (weight is not None):
            user.profile.set_weight(weight)
            was_updated = True

        if birth_date is not None:
            user.profile.birth_date = birth_date
            was_updated = True

        if was_updated:
            try:
                user.profile.updated_at = dt.datetime.utcnow()
                user.save()
            except:
                db.session.rollback()
                report_error_and_abort(500, "profile",
                                       "Unable to update profile")

        return user.profile, 200
コード例 #24
0
    def post(self,
             username,
             name,
             start_at,
             distance,
             duration,
             category_id,
             climb=0,
             edited=False):
        profile = get_auth_profile_or_abort(username, "workout")
        category = WorkoutCategoryModel.get_by_id(category_id)

        if category is None:
            report_error_and_abort(422, "workout",
                                   "Workout category not found")

        if name is None or name == "":
            name = category.name

        utc_start_at = start_at - start_at.utcoffset()
        now = dt.datetime.utcnow().replace(tzinfo=pytz.UTC)

        if utc_start_at > now:
            report_error_and_abort(422, "workout",
                                   "Workout start time is in the future")

        try:
            new_workout = Workout(profile.id, category, name, utc_start_at,
                                  distance, duration, climb, None, edited)
            new_workout.save()
            add_workout_data_to_goals(profile, new_workout)
        except:
            db.session.rollback()
            report_error_and_abort(500, "workout", "Unable to create workout.")

        return new_workout, 200, {
            'Location': '{}/{}'.format(request.path, new_workout.id)
        }
コード例 #25
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
	def post(self, username, email, password, **kwargs):

		if User.find_by_username(username):
			report_error_and_abort(409, "register", "User already exists(1)")

		if User.find_by_email(email):
			report_error_and_abort(409, "register", "User already exists(2)")
	
		new_user = User(username, email, password, **kwargs)
		new_profile = Profile(new_user)
		confirmation = UserConfirmation(username, None, **kwargs)

		try:
			confirmation.save()
			new_user.save()
			new_profile.save()
			mail_send_confirmation_code(username, email, confirmation.code)

		except:
			db.session.rollback()
			report_error_and_abort(500, "register", "Unable to create user")

		return new_user, 201, {'Location': '{0}/{1}'.format(request.path, new_user.id) }
コード例 #26
0
ファイル: resource.py プロジェクト: andraune/run4it_backend
    def put(self, disc_id, name, length, is_route, **kwargs):
        auth_username = get_jwt_identity()

        discipline = DisciplineModel.get_by_id(disc_id)

        if discipline is None:
            report_error_and_abort(404, "discipline", "Discipline not found.")

        if discipline.username != auth_username:
            report_error_and_abort(403, "discipline",
                                   "Cannot update other user's token.")

        try:
            discipline.name = name
            discipline.length = length
            discipline.is_route = is_route
            discipline.save()
        except:
            db.session.rollback()
            report_error_and_abort(500, "discipline",
                                   "Unable to update discipline.")

        return discipline
コード例 #27
0
    def post(self, username, category_id):
        profile = get_auth_profile_or_abort(username, "workout")
        category = WorkoutCategoryModel.get_by_id(category_id)

        if category is None:
            report_error_and_abort(422, "workout",
                                   "Workout category not found")

        if request.files is None or len(
                request.files) != 1 or request.files["gpxfile"] is None:
            report_error_and_abort(422, "workout",
                                   "Workout file not provided.")

        uploaded_file = request.files["gpxfile"]

        if not is_valid_workout_filename(uploaded_file.filename):
            report_error_and_abort(422, "workout", "Workout filename invalid.")

        tmp_filepath = save_uploaded_file_or_abort(uploaded_file,
                                                   profile.username)

        # create object with temporary data and use it to parse workout file
        new_workout = Workout(profile.id, category, category.name,
                              dt.datetime.utcnow(), 0, 1, 0, tmp_filepath,
                              False)
        new_workout.register_extended_data()
        parsed_summary = new_workout.extended_summary

        if parsed_summary is None:
            remove_uploaded_file(tmp_filepath)
            db.session.rollback()
            report_error_and_abort(422, "workout",
                                   "Failed to parse uploaded file")

        new_workout.name = get_autogenerated_workout_name(
            parsed_summary.latitude, parsed_summary.longitude,
            new_workout.category_name)
        new_workout.start_at = parsed_summary.time
        new_workout.duration = parsed_summary.duration

        if category.supports_gps_data:
            new_workout.distance = parsed_summary.distance
            new_workout.climb = parsed_summary.elevation

        workout_filepath = None
        try:
            new_workout.save()
            workout_filepath = rename_uploaded_file(tmp_filepath,
                                                    profile.username,
                                                    new_workout.id)
            new_workout.resource_path = workout_filepath
            new_workout.save()
            add_workout_data_to_goals(profile, new_workout)
        except:
            remove_uploaded_file(tmp_filepath)
            remove_uploaded_file(workout_filepath)
            db.session.rollback()
            report_error_and_abort(500, "workout",
                                   "Unable to create workout from file.")

        return new_workout, 200, {
            'Location': '{}/{}'.format(request.path, new_workout.id)
        }