API - replace 'Activity' with 'Workout' - #58
This commit is contained in:
@ -18,7 +18,7 @@ from sqlalchemy import exc, or_
|
||||
from werkzeug.exceptions import RequestEntityTooLarge
|
||||
from werkzeug.utils import secure_filename
|
||||
|
||||
from ..activities.utils_files import get_absolute_file_path
|
||||
from ..workouts.utils_files import get_absolute_file_path
|
||||
from .models import User
|
||||
from .utils import (
|
||||
authenticate,
|
||||
@ -310,8 +310,8 @@ def get_authenticated_user_profile(
|
||||
"language": "en",
|
||||
"last_name": null,
|
||||
"location": null,
|
||||
"nb_activities": 6,
|
||||
"nb_sports": 3,
|
||||
"nb_workouts": 6,
|
||||
"picture": false,
|
||||
"sports_list": [
|
||||
1,
|
||||
@ -371,8 +371,8 @@ def edit_user(auth_user_id: int) -> Union[Dict, HttpResponse]:
|
||||
"language": "en",
|
||||
"last_name": null,
|
||||
"location": null,
|
||||
"nb_activities": 6,
|
||||
"nb_sports": 3,
|
||||
"nb_workouts": 6,
|
||||
"picture": false,
|
||||
"sports_list": [
|
||||
1,
|
||||
|
@ -9,7 +9,7 @@ from sqlalchemy.ext.declarative import DeclarativeMeta
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
from sqlalchemy.sql.expression import select
|
||||
|
||||
from ..activities.models import Activity
|
||||
from ..workouts.models import Workout
|
||||
from .utils_token import decode_user_token, get_user_token
|
||||
|
||||
BaseModel: DeclarativeMeta = db.Model
|
||||
@ -32,8 +32,8 @@ class User(BaseModel):
|
||||
timezone = db.Column(db.String(50), nullable=True)
|
||||
# does the week start Monday?
|
||||
weekm = db.Column(db.Boolean(50), default=False, nullable=False)
|
||||
activities = db.relationship(
|
||||
'Activity', lazy=True, backref=db.backref('user', lazy='joined')
|
||||
workouts = db.relationship(
|
||||
'Workout', lazy=True, backref=db.backref('user', lazy='joined')
|
||||
)
|
||||
records = db.relationship(
|
||||
'Record', lazy=True, backref=db.backref('user', lazy='joined')
|
||||
@ -90,33 +90,33 @@ class User(BaseModel):
|
||||
return 'Invalid token. Please log in again.'
|
||||
|
||||
@hybrid_property
|
||||
def activities_count(self) -> int:
|
||||
return Activity.query.filter(Activity.user_id == self.id).count()
|
||||
def workouts_count(self) -> int:
|
||||
return Workout.query.filter(Workout.user_id == self.id).count()
|
||||
|
||||
@activities_count.expression # type: ignore
|
||||
def activities_count(self) -> int:
|
||||
@workouts_count.expression # type: ignore
|
||||
def workouts_count(self) -> int:
|
||||
return (
|
||||
select([func.count(Activity.id)])
|
||||
.where(Activity.user_id == self.id)
|
||||
.label('activities_count')
|
||||
select([func.count(Workout.id)])
|
||||
.where(Workout.user_id == self.id)
|
||||
.label('workouts_count')
|
||||
)
|
||||
|
||||
def serialize(self) -> Dict:
|
||||
sports = []
|
||||
total = (0, '0:00:00')
|
||||
if self.activities_count > 0: # type: ignore
|
||||
if self.workouts_count > 0: # type: ignore
|
||||
sports = (
|
||||
db.session.query(Activity.sport_id)
|
||||
.filter(Activity.user_id == self.id)
|
||||
.group_by(Activity.sport_id)
|
||||
.order_by(Activity.sport_id)
|
||||
db.session.query(Workout.sport_id)
|
||||
.filter(Workout.user_id == self.id)
|
||||
.group_by(Workout.sport_id)
|
||||
.order_by(Workout.sport_id)
|
||||
.all()
|
||||
)
|
||||
total = (
|
||||
db.session.query(
|
||||
func.sum(Activity.distance), func.sum(Activity.duration)
|
||||
func.sum(Workout.distance), func.sum(Workout.duration)
|
||||
)
|
||||
.filter(Activity.user_id == self.id)
|
||||
.filter(Workout.user_id == self.id)
|
||||
.first()
|
||||
)
|
||||
return {
|
||||
@ -133,8 +133,8 @@ class User(BaseModel):
|
||||
'timezone': self.timezone,
|
||||
'weekm': self.weekm,
|
||||
'language': self.language,
|
||||
'nb_activities': self.activities_count,
|
||||
'nb_sports': len(sports),
|
||||
'nb_workouts': self.workouts_count,
|
||||
'sports_list': [
|
||||
sport for sportslist in sports for sport in sportslist
|
||||
],
|
||||
|
@ -14,8 +14,8 @@ from fittrackee.responses import (
|
||||
from flask import Blueprint, request, send_file
|
||||
from sqlalchemy import exc
|
||||
|
||||
from ..activities.utils_files import get_absolute_file_path
|
||||
from .models import Activity, User
|
||||
from ..workouts.utils_files import get_absolute_file_path
|
||||
from .models import User, Workout
|
||||
from .utils import authenticate, authenticate_as_admin
|
||||
|
||||
users_blueprint = Blueprint('users', __name__)
|
||||
@ -42,7 +42,7 @@ def get_users(auth_user_id: int) -> Dict:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/users?order_by=activities_count&par_page=5 HTTP/1.1
|
||||
GET /api/users?order_by=workouts_count&par_page=5 HTTP/1.1
|
||||
Content-Type: application/json
|
||||
|
||||
**Example response**:
|
||||
@ -65,8 +65,8 @@ def get_users(auth_user_id: int) -> Dict:
|
||||
"language": "en",
|
||||
"last_name": null,
|
||||
"location": null,
|
||||
"nb_activities": 6,
|
||||
"nb_sports": 3,
|
||||
"nb_workouts": 6,
|
||||
"picture": false,
|
||||
"sports_list": [
|
||||
1,
|
||||
@ -88,8 +88,8 @@ def get_users(auth_user_id: int) -> Dict:
|
||||
"language": "fr",
|
||||
"last_name": null,
|
||||
"location": null,
|
||||
"nb_activities": 0,
|
||||
"nb_sports": 0,
|
||||
"nb_workouts": 0,
|
||||
"picture": false,
|
||||
"sports_list": [],
|
||||
"timezone": "Europe/Paris",
|
||||
@ -108,7 +108,7 @@ def get_users(auth_user_id: int) -> Dict:
|
||||
:query integer per_page: number of users per page (default: 10, max: 50)
|
||||
:query string q: query on user name
|
||||
:query string order_by: sorting criteria (``username``, ``created_at``,
|
||||
``activities_count``, ``admin``)
|
||||
``workouts_count``, ``admin``)
|
||||
:query string order: sorting order (default: ``asc``)
|
||||
|
||||
:reqheader Authorization: OAuth 2.0 Bearer Token
|
||||
@ -137,11 +137,11 @@ def get_users(auth_user_id: int) -> Dict:
|
||||
User.username.like('%' + query + '%') if query else True,
|
||||
)
|
||||
.order_by(
|
||||
User.activities_count.asc() # type: ignore
|
||||
if order_by == 'activities_count' and order == 'asc'
|
||||
User.workouts_count.asc() # type: ignore
|
||||
if order_by == 'workouts_count' and order == 'asc'
|
||||
else True,
|
||||
User.activities_count.desc() # type: ignore
|
||||
if order_by == 'activities_count' and order == 'desc'
|
||||
User.workouts_count.desc() # type: ignore
|
||||
if order_by == 'workouts_count' and order == 'desc'
|
||||
else True,
|
||||
User.username.asc()
|
||||
if order_by == 'username' and order == 'asc'
|
||||
@ -212,8 +212,8 @@ def get_single_user(
|
||||
"language": "en",
|
||||
"last_name": null,
|
||||
"location": null,
|
||||
"nb_activities": 6,
|
||||
"nb_sports": 3,
|
||||
"nb_workouts": 6,
|
||||
"picture": false,
|
||||
"sports_list": [
|
||||
1,
|
||||
@ -328,7 +328,7 @@ def update_user(
|
||||
"language": "en",
|
||||
"last_name": null,
|
||||
"location": null,
|
||||
"nb_activities": 6,
|
||||
"nb_workouts": 6,
|
||||
"nb_sports": 3,
|
||||
"picture": false,
|
||||
"sports_list": [
|
||||
@ -443,8 +443,8 @@ def delete_user(
|
||||
'no other user has admin rights.'
|
||||
)
|
||||
|
||||
for activity in Activity.query.filter_by(user_id=user.id).all():
|
||||
db.session.delete(activity)
|
||||
for workout in Workout.query.filter_by(user_id=user.id).all():
|
||||
db.session.delete(workout)
|
||||
db.session.flush()
|
||||
user_picture = user.picture
|
||||
db.session.delete(user)
|
||||
@ -454,7 +454,7 @@ def delete_user(
|
||||
if os.path.isfile(picture_path):
|
||||
os.remove(picture_path)
|
||||
shutil.rmtree(
|
||||
get_absolute_file_path(f'activities/{user.id}'),
|
||||
get_absolute_file_path(f'workouts/{user.id}'),
|
||||
ignore_errors=True,
|
||||
)
|
||||
shutil.rmtree(
|
||||
|
@ -78,8 +78,8 @@ def verify_extension_and_size(
|
||||
return InvalidPayloadErrorResponse('No selected file.', 'fail')
|
||||
|
||||
allowed_extensions = (
|
||||
'ACTIVITY_ALLOWED_EXTENSIONS'
|
||||
if file_type == 'activity'
|
||||
'WORKOUT_ALLOWED_EXTENSIONS'
|
||||
if file_type == 'workout'
|
||||
else 'PICTURE_ALLOWED_EXTENSIONS'
|
||||
)
|
||||
|
||||
@ -158,13 +158,13 @@ def authenticate_as_admin(f: Callable) -> Callable:
|
||||
return decorated_function
|
||||
|
||||
|
||||
def can_view_activity(
|
||||
auth_user_id: int, activity_user_id: int
|
||||
def can_view_workout(
|
||||
auth_user_id: int, workout_user_id: int
|
||||
) -> Optional[HttpResponse]:
|
||||
"""
|
||||
Return error response if user has no right to view activity
|
||||
Return error response if user has no right to view workout
|
||||
"""
|
||||
if auth_user_id != activity_user_id:
|
||||
if auth_user_id != workout_user_id:
|
||||
return ForbiddenErrorResponse()
|
||||
return None
|
||||
|
||||
|
Reference in New Issue
Block a user