FitTrackee/fittrackee_api/fittrackee_api/users/models.py

134 lines
4.5 KiB
Python
Raw Normal View History

2017-12-16 21:00:46 +01:00
import datetime
import jwt
from fittrackee_api import bcrypt, db
2017-12-16 21:00:46 +01:00
from flask import current_app
from sqlalchemy import func
from ..activities.models import Activity
2017-12-16 21:00:46 +01:00
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
2018-01-01 16:59:46 +01:00
username = db.Column(db.String(20), unique=True, nullable=False)
2017-12-16 21:00:46 +01:00
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(255), nullable=False)
created_at = db.Column(db.DateTime, nullable=False)
2017-12-17 09:16:08 +01:00
admin = db.Column(db.Boolean, default=False, nullable=False)
2018-01-01 16:59:46 +01:00
first_name = db.Column(db.String(80), nullable=True)
last_name = db.Column(db.String(80), nullable=True)
birth_date = db.Column(db.DateTime, nullable=True)
location = db.Column(db.String(80), nullable=True)
bio = db.Column(db.String(200), nullable=True)
2018-01-01 21:54:03 +01:00
picture = db.Column(db.String(255), nullable=True)
timezone = db.Column(db.String(50), nullable=True)
# does the week start Monday?
weekm = db.Column(db.Boolean(50), default=False, nullable=False)
2019-08-28 13:25:39 +02:00
activities = db.relationship(
'Activity', lazy=True, backref=db.backref('users', lazy='joined')
)
records = db.relationship(
'Record', lazy=True, backref=db.backref('users', lazy='joined')
)
language = db.Column(db.String(50), nullable=True)
2017-12-16 21:00:46 +01:00
def __repr__(self):
2018-05-23 17:30:22 +02:00
return f'<User {self.username!r}>'
2017-12-16 21:00:46 +01:00
def __init__(
2019-08-28 13:25:39 +02:00
self, username, email, password, created_at=datetime.datetime.utcnow()
):
2017-12-16 21:00:46 +01:00
self.username = username
self.email = email
self.password = bcrypt.generate_password_hash(
password, current_app.config.get('BCRYPT_LOG_ROUNDS')
).decode()
self.created_at = created_at
2017-12-17 12:07:25 +01:00
@staticmethod
def encode_auth_token(user_id):
2018-01-01 16:59:46 +01:00
"""
Generates the auth token
:param user_id: -
:return: JWToken
"""
2017-12-16 21:00:46 +01:00
try:
payload = {
2019-08-28 13:25:39 +02:00
'exp': datetime.datetime.utcnow()
+ datetime.timedelta(
2017-12-16 21:00:46 +01:00
days=current_app.config.get('TOKEN_EXPIRATION_DAYS'),
2019-08-28 13:25:39 +02:00
seconds=current_app.config.get('TOKEN_EXPIRATION_SECONDS'),
2017-12-16 21:00:46 +01:00
),
'iat': datetime.datetime.utcnow(),
2019-08-28 13:25:39 +02:00
'sub': user_id,
2017-12-16 21:00:46 +01:00
}
return jwt.encode(
payload,
current_app.config.get('SECRET_KEY'),
2019-08-28 13:25:39 +02:00
algorithm='HS256',
2017-12-16 21:00:46 +01:00
)
except Exception as e:
return e
@staticmethod
def decode_auth_token(auth_token):
"""
Decodes the auth token
:param auth_token: -
:return: integer|string
"""
try:
payload = jwt.decode(
2019-08-28 13:25:39 +02:00
auth_token, current_app.config.get('SECRET_KEY')
)
2017-12-16 21:00:46 +01:00
return payload['sub']
except jwt.ExpiredSignatureError:
return 'Signature expired. Please log in again.'
except jwt.InvalidTokenError:
return 'Invalid token. Please log in again.'
2018-05-09 15:52:27 +02:00
def serialize(self):
nb_activity = Activity.query.filter(
Activity.user_id == self.id
).count()
2018-06-07 22:44:52 +02:00
sports = []
total = (None, None)
if nb_activity > 0:
2019-08-28 13:25:39 +02:00
sports = (
db.session.query(Activity.sport_id)
2019-09-23 14:43:56 +02:00
.filter(Activity.user_id == self.id)
2019-08-28 13:25:39 +02:00
.group_by(Activity.sport_id)
.order_by(Activity.sport_id)
2019-08-28 13:25:39 +02:00
.all()
)
2019-09-23 14:43:56 +02:00
total = (
db.session.query(
func.sum(Activity.distance), func.sum(Activity.duration)
)
.filter(Activity.user_id == self.id)
.first()
)
2018-05-09 15:52:27 +02:00
return {
'username': self.username,
'email': self.email,
'created_at': self.created_at,
'admin': self.admin,
'first_name': self.first_name,
'last_name': self.last_name,
'bio': self.bio,
'location': self.location,
'birth_date': self.birth_date,
'picture': self.picture is not None,
'timezone': self.timezone,
'weekm': self.weekm,
'language': self.language,
'nb_activities': nb_activity,
'nb_sports': len(sports),
'sports_list': [
sport for sportslist in sports for sport in sportslist
],
'total_distance': float(total[0]) if total[0] else 0,
'total_duration': str(total[1]) if total[1] else "0:00:00",
2018-05-09 15:52:27 +02:00
}