2018-11-07 11:19:12 -08:00
|
|
|
from sqlalchemy import func
|
2018-09-25 13:09:25 -07:00
|
|
|
from grant.comment.models import Comment
|
2018-11-02 09:07:06 -07:00
|
|
|
from grant.email.models import EmailVerification
|
2018-09-25 13:09:25 -07:00
|
|
|
from grant.extensions import ma, db
|
2018-11-02 09:07:06 -07:00
|
|
|
from grant.utils.misc import make_url
|
2018-11-16 15:05:17 -08:00
|
|
|
from grant.utils.social import get_social_info_from_url
|
2018-11-02 09:07:06 -07:00
|
|
|
from grant.email.send import send_email
|
2018-09-25 13:09:25 -07:00
|
|
|
|
|
|
|
|
|
|
|
class SocialMedia(db.Model):
|
|
|
|
__tablename__ = "social_media"
|
|
|
|
|
|
|
|
id = db.Column(db.Integer(), primary_key=True)
|
|
|
|
# TODO replace this with something proper
|
|
|
|
social_media_link = db.Column(db.String(255), unique=False, nullable=True)
|
|
|
|
user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
|
|
|
|
|
|
|
|
def __init__(self, social_media_link, user_id):
|
|
|
|
self.social_media_link = social_media_link
|
|
|
|
self.user_id = user_id
|
|
|
|
|
|
|
|
|
|
|
|
class Avatar(db.Model):
|
|
|
|
__tablename__ = "avatar"
|
|
|
|
|
|
|
|
id = db.Column(db.Integer(), primary_key=True)
|
|
|
|
image_url = db.Column(db.String(255), unique=False, nullable=True)
|
|
|
|
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
|
|
|
user = db.relationship("User", back_populates="avatar")
|
|
|
|
|
|
|
|
def __init__(self, image_url, user_id):
|
|
|
|
self.image_url = image_url
|
|
|
|
self.user_id = user_id
|
|
|
|
|
|
|
|
|
|
|
|
class User(db.Model):
|
|
|
|
__tablename__ = "user"
|
|
|
|
|
|
|
|
id = db.Column(db.Integer(), primary_key=True)
|
|
|
|
email_address = db.Column(db.String(255), unique=True, nullable=True)
|
|
|
|
account_address = db.Column(db.String(255), unique=True, nullable=True)
|
|
|
|
display_name = db.Column(db.String(255), unique=False, nullable=True)
|
|
|
|
title = db.Column(db.String(255), unique=False, nullable=True)
|
|
|
|
|
2018-11-14 13:12:24 -08:00
|
|
|
social_medias = db.relationship(SocialMedia, backref="user", lazy=True, cascade="all, delete-orphan")
|
2018-09-25 13:09:25 -07:00
|
|
|
comments = db.relationship(Comment, backref="user", lazy=True)
|
2018-11-14 13:12:24 -08:00
|
|
|
avatar = db.relationship(Avatar, uselist=False, back_populates="user", cascade="all, delete-orphan")
|
|
|
|
email_verification = db.relationship(EmailVerification, uselist=False, back_populates="user", lazy=True, cascade="all, delete-orphan")
|
2018-09-25 13:09:25 -07:00
|
|
|
|
|
|
|
# TODO - add create and validate methods
|
|
|
|
|
|
|
|
def __init__(self, email_address=None, account_address=None, display_name=None, title=None):
|
|
|
|
if not email_address and not account_address:
|
|
|
|
raise ValueError("Either email_address or account_address is required to create a user")
|
|
|
|
|
|
|
|
self.email_address = email_address
|
|
|
|
self.account_address = account_address
|
|
|
|
self.display_name = display_name
|
|
|
|
self.title = title
|
|
|
|
|
2018-11-02 09:07:06 -07:00
|
|
|
@staticmethod
|
2018-11-13 05:58:02 -08:00
|
|
|
def create(email_address=None, account_address=None, display_name=None, title=None, _send_email=True):
|
2018-11-02 09:07:06 -07:00
|
|
|
user = User(
|
|
|
|
account_address=account_address,
|
|
|
|
email_address=email_address,
|
|
|
|
display_name=display_name,
|
|
|
|
title=title
|
|
|
|
)
|
|
|
|
db.session.add(user)
|
|
|
|
db.session.flush()
|
|
|
|
|
|
|
|
# Setup & send email verification
|
|
|
|
ev = EmailVerification(user_id=user.id)
|
|
|
|
db.session.add(ev)
|
|
|
|
db.session.commit()
|
|
|
|
|
2018-11-27 11:07:09 -08:00
|
|
|
if _send_email:
|
2018-11-13 05:58:02 -08:00
|
|
|
send_email(user.email_address, 'signup', {
|
|
|
|
'display_name': user.display_name,
|
|
|
|
'confirm_url': make_url(f'/email/verify?code={ev.code}')
|
|
|
|
})
|
2018-11-02 09:07:06 -07:00
|
|
|
|
|
|
|
return user
|
|
|
|
|
2018-10-19 22:18:27 -07:00
|
|
|
@staticmethod
|
2018-11-07 11:19:12 -08:00
|
|
|
def get_by_identifier(email_address: str = None, account_address: str = None):
|
2018-10-19 22:18:27 -07:00
|
|
|
if not email_address and not account_address:
|
|
|
|
raise ValueError("Either email_address or account_address is required to get a user")
|
|
|
|
|
|
|
|
return User.query.filter(
|
2018-11-07 11:19:12 -08:00
|
|
|
(func.lower(User.account_address) == func.lower(account_address)) |
|
|
|
|
(func.lower(User.email_address) == func.lower(email_address))
|
2018-10-19 22:18:27 -07:00
|
|
|
).first()
|
|
|
|
|
2018-09-25 13:09:25 -07:00
|
|
|
class UserSchema(ma.Schema):
|
|
|
|
class Meta:
|
|
|
|
model = User
|
|
|
|
# Fields to expose
|
2018-09-26 12:42:40 -07:00
|
|
|
fields = (
|
|
|
|
"account_address",
|
|
|
|
"title",
|
|
|
|
"email_address",
|
|
|
|
"social_medias",
|
|
|
|
"avatar",
|
|
|
|
"display_name",
|
|
|
|
"userid"
|
|
|
|
)
|
|
|
|
|
|
|
|
social_medias = ma.Nested("SocialMediaSchema", many=True)
|
|
|
|
avatar = ma.Nested("AvatarSchema")
|
2018-09-25 13:09:25 -07:00
|
|
|
userid = ma.Method("get_userid")
|
|
|
|
|
|
|
|
def get_userid(self, obj):
|
|
|
|
return obj.id
|
|
|
|
|
|
|
|
user_schema = UserSchema()
|
|
|
|
users_schema = UserSchema(many=True)
|
2018-09-26 12:42:40 -07:00
|
|
|
|
|
|
|
class SocialMediaSchema(ma.Schema):
|
|
|
|
class Meta:
|
|
|
|
model = SocialMedia
|
|
|
|
# Fields to expose
|
2018-11-16 15:05:17 -08:00
|
|
|
fields = (
|
2018-11-19 12:23:56 -08:00
|
|
|
"url",
|
2018-11-16 15:05:17 -08:00
|
|
|
"service",
|
|
|
|
"username",
|
|
|
|
)
|
|
|
|
|
2018-11-19 12:23:56 -08:00
|
|
|
url = ma.Method("get_url")
|
2018-11-16 15:05:17 -08:00
|
|
|
service = ma.Method("get_service")
|
|
|
|
username = ma.Method("get_username")
|
|
|
|
|
2018-11-19 12:23:56 -08:00
|
|
|
def get_url(self, obj):
|
|
|
|
return obj.social_media_link
|
|
|
|
|
2018-11-16 15:05:17 -08:00
|
|
|
def get_service(self, obj):
|
|
|
|
info = get_social_info_from_url(obj.social_media_link)
|
|
|
|
return info['service']
|
2018-11-19 12:23:56 -08:00
|
|
|
|
2018-11-16 15:05:17 -08:00
|
|
|
def get_username(self, obj):
|
|
|
|
info = get_social_info_from_url(obj.social_media_link)
|
|
|
|
return info['username']
|
2018-09-26 12:42:40 -07:00
|
|
|
|
2018-10-19 22:18:27 -07:00
|
|
|
|
2018-09-26 12:42:40 -07:00
|
|
|
social_media_schema = SocialMediaSchema()
|
|
|
|
social_media_schemas = SocialMediaSchema(many=True)
|
|
|
|
|
|
|
|
|
|
|
|
class AvatarSchema(ma.Schema):
|
|
|
|
class Meta:
|
|
|
|
model = SocialMedia
|
|
|
|
# Fields to expose
|
|
|
|
fields = ("image_url",)
|
|
|
|
|
|
|
|
|
|
|
|
avatar_schema = AvatarSchema()
|
|
|
|
avatar_schemas = AvatarSchema(many=True)
|