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
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
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
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
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
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
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
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
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
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
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)
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
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
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.")
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) }
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
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
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) }
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
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
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.")
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
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
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) }
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) }
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
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) }